If function is false, the else works. If true, segfault.

I have this function:
1
2
3
4
5
6
7
8
9
10
    bool login(const string& username, const string& password)
    {
        if(user_exists(username))
        {
            ifstream pswfile;
            pswfile.open(string(appdata + '\\' + username + '\\' + username + ".psw").c_str());
            return ispassword(password, read_userpassword(pswfile));
        }
        return false;
    }


All the functions called are these:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
string decodify(const vector<int>& code)
    {
        string ret;
        for(unsigned i = 0; i < code.size(); i++)
        {
            ret[i] = ((static_cast<char>((code[i]) - 9)/7));
        }
        return ret;
    }
    vector<int> read_userpassword(ifstream& file)
    {
        vector<int> password;
        string read_string;
        for(int i = 0; getline(file, read_string); i++)
        {
            password[i] = std::stoi(read_string);
        }
        return password;
    }
    bool ispassword(const string& password_try, const vector<int>& codified_string)
    {
        return decodify(codified_string) == password_try;
    }


Then, I use like that:
1
2
3
4
5
6
7
...
if(user::login(usuario, senha))
{
   cout << "Welcome, " << usuario;
}
else cout << "Authentication failed";
...


When failed to authenticate, I receive the output "Authentication failed", but when I know that the password and username is correct, I receive segfault and my program stops working. Why?
In decodify you have an empty string. You attempt to modify nonexistent elements of that empty string, resulting in undefined behavior.

In read_userpassword you have an empty vector. You attempt to modify nonexistent elements of that empty vector, resulting in undefined behavior.

Avoid undefined behavior.
And how can I fix that?
1
2
3
4
5
6
7
8
9
string decodify(const vector<int>& code)
    {
        string ret;
        for(unsigned i = 0; i < code.size(); i++)
        {
            ret += ((static_cast<char>((code[i]) - 9)/7));
        }
        return ret;
}


1
2
3
4
5
6
7
8
9
10
    vector<int> read_userpassword(ifstream& file)
    {
        vector<int> password;
        string read_string;
        while (getline(file, read_string))
        {
            password.push_back(std::stoi(read_string));
        }
        return password;
    }


Now, if the input is correct, I get false. Any idea?
Yes. Debug your code. Test your functions. Preferably before you start plugging them in to other code.

Presumably there is a function codify somewhere that does the opposite of decodify;

Does
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <string>

int main()
{
    std::string s("somepwval59") ;
    std::string decodified = decodify(codify(s)) ;
    if ( decodified != s )
        std::cout << '"' << s << "\" is not equal to \"" << decodified << "\"\n" ; 
    else
        std::cout << "equal\n" ;
}

produce the expected value of equal?

You might find http://www.slideshare.net/JonJagger/larry-and-jen-do-roman-numerals-in-c
to be of interest.
Last edited on
Haha, I got a broken gdb or anything like that. I'll test your code.
Topic archived. No new replies allowed.