-1

I am stuck in pset2 on cs50 , and honestly I think I am missing alot of stuff, I dont know if I can go forward in the course without being able to truely understand some basics. I am trying to get this done and then I think I will pause and still learn some basics about c. I need help with this as well as more commentary that I would be most grateful for.

so basically here's my code

#define _XOPEN_SOURCE
#include <cs50.h>
#include <stdio.h>
#include <crypt.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

bool crack(string given_hash);


int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Usage ./crack hash\n");
        return 1;
    }

    if (!crack(argv[1]))
         return 1;
 }

bool crack(string given_hash)
{    
    string Alphabet = "abcdefghijklmnopqrstuvwxyABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char key[6];
    char salt[3];
    salt[2] = '\0';

    for (int x = 0; x < 2; x++)
    {
        salt[x] = given_hash[x];
    }

    // single-letter keys.
    for (int i = 0; i < 52; i++)
    {
        key[0] = Alphabet[i], key[1] = '\0';
        string new_hash = crypt(key,salt);
        if (strcmp(new_hash, given_hash) == 0)
        {
            printf("you got the key: %s\n",key);
            return 0;
        }
    }

    // for 2-letter keys.
    for (int i = 0; i < 52; i++)
    {
        key[0] = Alphabet[i], key[2] = '\0';
        for (int j = 0; j < 52; j++)
        {
            key[1] = Alphabet[j]; 
        }
        string new_hash = crypt(key,salt);
        if (strcmp(new_hash, given_hash) == 0)
        {
            printf("you got the key: %s\n",key);
            return 0;
        }
    }

    // for 3-letter keys.
    for (int i = 0; i < 52; i++)
    {
        key[0] = Alphabet[i], key[3] = '\0';
        for (int j = 0; j < 52; j++)
        {
            key[1] = Alphabet[j];
            for (int k = 0; k < 52; k++)
            {
                key[2] = Alphabet[k];
            }
        }
        string new_hash = crypt(key,salt);
        if (strcmp(new_hash, given_hash) == 0)
        {
            printf("you got the key: %s\n",key);
            return 0;
        }
    }

    // for 4-letter keys.
    for (int i = 0; i < 52; i++)
    {
        key[0] = Alphabet[i], key[4] = '\0';
        for (int j = 0; j < 52; j++)
        {
            key[1] = Alphabet[j];
            for (int k = 0; k < 52; k++)
            {
                key[2] = Alphabet[k];
                for( int l = 0; l < 52; l++)
                {
                    key[3] = Alphabet[l];
                }
            }
        }
        string new_hash = crypt(key,salt);
        if (strcmp(new_hash, given_hash) == 0)
        {
            printf("you got the key: %s\n",key);
            return 0;
        }
    }

    // for 5-letter keys.
    for (int i = 0; i < 52; i++)
    {
        key[0] = Alphabet[i], key[5] = '\0';
        for (int j = 0; j < 52; j++)
        {
            key[1] = Alphabet[j];
            for (int k = 0; k < 52; k++)
            {
                key[2] = Alphabet[k];
                for(int l = 0; l < 52; l++)
                {
                    key[3] = Alphabet[l];
                    for(int m = 0; m < 52; m++)
                {
                    key[4] = Alphabet[m];
                }
            }
        }
    }
    string new_hash = crypt(key,salt);
    if (strcmp(new_hash, given_hash) == 0)
    {
        printf("you got the key: %s\n",key);
        return 0;
    }
  }
}

now I dont know what I am doing wrong , I know this error is due no no returning thing in a non void function, but how do I fix it ?

Diaa Alaa
  • 23
  • 1
  • 10
  • Your main function has 2 returns but they're both conditional on the if statements, i.e they might now get executed and your main function doesn't return anything then – toastedDeli Mar 16 '19 at 03:13
  • thanks for the reply but the error is actually on the crack function , I would try to 'return 0;' on main and try again! – Diaa Alaa Mar 16 '19 at 03:15
  • nope, nothing happened, error remained :'( – Diaa Alaa Mar 16 '19 at 03:17
  • I just removed a brace from the end of the code you pasted, are you sure you dont have an extra one in your code or something? – toastedDeli Mar 16 '19 at 03:20

2 Answers2

1

Both your main and crack function have a code path that possibly reach then end of the function and will not return a value.

main - If crack returns 1 or true then the code will reach the end of main without returning an int value. There is however an exception for main that if you do not explicitly return then it will return 0. So while not a problem, I would still ensure that all code paths return.

crack - If none of your tests find a matching password hash then the function would reach the end and not return. Based on the function logic it would never happen, but the compiler does not know that.

To resolve the issue you need to ensure that all code paths return a value.

Chris Taylor
  • 52,623
  • 10
  • 78
  • 89
  • `main` does not. Any function in C/C++, `return 0` is implicit. –  Mar 16 '19 at 03:33
  • I meant main not any in above post. Actually, in C99 and up it return 0, in 89 and before it returns int but it is unknown what value does it have. Read this: https://stackoverflow.com/a/18721336/5550963 –  Mar 16 '19 at 03:38
  • 2
    @Gox _Any function in C/C++, return 0 is implicit._. No, it does not hold true for any function but only for `main()`. – H.S. Mar 16 '19 at 03:41
  • @gox I think the confusion is in the wording of your first comment "Any function in C/C++, return 0 is implicit." – Chris Taylor Mar 16 '19 at 03:43
  • @Gox In your first comment you have mentioned - _Any function in C/C++, return 0 is implicit....._. – H.S. Mar 16 '19 at 03:44
  • @H.S. that was my mistake. I apologize for it. –  Mar 16 '19 at 03:50
0

You are getting error control may reach end of non-void function because the crack() function is suppose to return bool and there is no return statement in crack() function at the end. While compiling the code, the compiler found that all the return statements of crack() function can be reached only if some condition is satisfied

bool crack(string given_hash)

{    

    ....
    ....

    if (strcmp(new_hash, given_hash) == 0)
    {
        printf("you got the key: %s\n",key);
        return 0;
    }
    ....
    ....

    if (strcmp(new_hash, given_hash) == 0)
    {
        printf("you got the key: %s\n",key);
        return 0;
    }
    ....
    ....

    if (strcmp(new_hash, given_hash) == 0)
    {
        printf("you got the key: %s\n",key);
        return 0;
    }
    ....
    ....

    if (strcmp(new_hash, given_hash) == 0)
    {
        printf("you got the key: %s\n",key);
        return 0;
    }
    ....
    ....

    if (strcmp(new_hash, given_hash) == 0)
    {
        printf("you got the key: %s\n",key);
        return 0;
    }
}
      //<================ Return statement missing

}

and there is a possibility that the control may reach to end of function if none of the conditions is satisfied. You should add a return statement in the end of crack() function and return a value that indicates failure. Since in all cases you are returning 0 (seems that is for success case), may you can return 1 at the end to indicate failure:

    ....
    ....
    return 1;

}

Note that there is an exception for main() function, if control reaches the end of the main() function without encountering a return statement, return 0; is executed.

H.S.
  • 11,654
  • 2
  • 15
  • 32
  • ok now that I could compile it, it doesnt return anything :'( – Diaa Alaa Mar 16 '19 at 03:32
  • Read this https://stackoverflow.com/a/18721336/5550963 carefully. It is in 99 and up that main always return 0. –  Mar 16 '19 at 03:40
  • @Gox My answer talks about `crack()` and not `main()`. For the `main()`, I have added a foot note in my answer. Check https://en.cppreference.com/w/c/language/return and https://en.cppreference.com/w/c/language/main_function – H.S. Mar 16 '19 at 03:43