0

Below is my code, I am getting the error "Segmentation fault (core dumped) " I'm new to C the program is supposed to get user input, "hash" it by converting to ASCII values, then it is compared to the string of ASCII numbers, printing "Secret information found!!" if the password that has been input matches

#include <stdio.h>
#include <string.h>
int password_validation(char password_input);
char hashing(char *user_input);
char user_input();


int main()
{
    int k = password_validation(hashing(user_input()));

    if (k == 0){
        printf("\n Secret information found!!! \n");
    }
    else{
        printf("\n try again \n");
    }

    return 0;
}

char user_input(){
    int password_input[100];
    printf("Enter the password: ");
    printf("\n");
    scanf("%s", password_input); 
    return password_input; 
}

char hashing(char *user_input){
    for(int i=0;i< sizeof user_input; i=i+1){

        int num = user_input[i];
        char hashed_password[] = "";
        num = hashed_password[i];
        printf(hashed_password);
        return hashed_password;
    }
}

int password_validation(char password_input){
    printf("works");
    int password_comparison = strcmp("090097099104082111104105116104083097109050048049056101104099115067104117114099104079102069109097099115095095", password_input);
    return password_comparison;
}

    enter code here
  • 1
    In `char user_input()` the local variable `int password_input[100];` no longer exists after function return. Please see [Function returning address of local variable error in C](https://stackoverflow.com/questions/22288871/function-returning-address-of-local-variable-error-in-c) – Weather Vane Nov 05 '18 at 23:33
  • `user_input` is supposed to return a `char`, but you're trying to return an `int[100]`. You can't return arrays in `c` anyway, if you really want to, you need to wrap it in a `struct` first and return that. – yano Nov 05 '18 at 23:33
  • 1
    In `char hashing()` you are indexing the 0-length string `char hashed_password[] = "";` with `num = hashed_password[i];`. And again, you try to return a local array, but incorrectly anyway as @yano wrote. Please look at compiler warnings. – Weather Vane Nov 05 '18 at 23:34
  • the posted code is in the question twice. Please correct – user3629249 Nov 06 '18 at 00:04
  • regarding: `int password_input[100];` and `scanf("%s", password_input);` the `%s` is for inputting a `char` array, but `password_input[]` is an array of `int`. When using the input format specifiers `%s` and/or `%[...]` always include a max characters modifier that is 1 less than the length of the input buffer to avoid a buffer overflow and the resulting undefined behavior. (those input specifiers always append a NUL byte to the input – user3629249 Nov 06 '18 at 00:13
  • OT: when calling any of the `scanf()` family of functions, always check the returned value (not the parameter values) to assure the operation was successful. (in this case, any returned value other than 1 indicates the operation failed – user3629249 Nov 06 '18 at 00:15
  • regarding: `for(int i=0;i< sizeof user_input; i=i+1){` the `sizeof` user_input is the size of a pointer, not the length of the array input by the user. Suggest: `for( int i=0; i < strlen( *user_input); i++){` – user3629249 Nov 06 '18 at 00:18
  • regarding: `char hashed_password[] = "";` this will allocate a 1 byte array on the stack, containing '\0'. So on the first itteration of the loop, this `num = hashed_password[i];` will set `num` to '\0'. two instructions later is the statement: `return hashed_password;` so none of the passed in password will be checked and a 'invalid' pointer will be passed to `password_validation()` Sadly, `password_validation()` is expecting a single character, not a pointer. I.E. the code contains LOTS of problems – user3629249 Nov 06 '18 at 00:28
  • when compiling, always enable the warnings, then fix those warnings. ( for `gcc`, at a minimum use: `-Wall -Wextra -Werror -Wconversion -pedantic -std=gnu11` ) Note: other compilers use different options to obtain the same results. the compiler will output some 11 warnings, all of which need to be corrected. – user3629249 Nov 06 '18 at 00:32

2 Answers2

0

While the comments by Weather Vane and yano are correct, those errors are not likely to cause segmentation faults:

  1. You can still access memory of local variables in C after the function exits, you just can not guarantee the data will be valid.

    Local vars are allocated on the stack so the address it self will remain valid for the process.

  2. A zero length string "" still takes a length 1 array in C because of terminating \0 character. Also, exceeding local array bounds in C won't necessarily cause a seg fault, depending on memory layout of the function.

What is guaranteed to case the segmentation fault, is this line: int password_comparison = strcmp("090097099104082111104105116104083097109050048049056101104099115067104117114099104079102069109097099115095095", password_input);

In your code, password_input is of type char and suppose to contain a value guaranteed to be between -127 and 127.

But, strcmp will treat it as a pointer - an address in memory between 0 and 255.

Addresses in this range are not valid, so when strcmp tries to read it, it will always cause segmentation fault.

Community
  • 1
  • 1
Lev M.
  • 6,088
  • 1
  • 10
  • 23
  • accessing local variables after the function exits is one form of undefined behavior. In this case, the local variables from the prior executed functions will have been overlayed by the later executed function, so any attempt to read those local variables after the function exits will result in garbage\ – user3629249 Nov 06 '18 at 00:37
  • Garbage - yes, segmentation fault - no. The original question was about seg fault. – Lev M. Nov 06 '18 at 22:04
  • Yes, Lev, that is why I used comments rather than supplying an answer – user3629249 Nov 06 '18 at 23:50
0
  1. You shouldn't return local variable in function char user_input()
  2. You need to distinguish char and char*

The following code could work:

#include <stdio.h>
#include <string.h>

#define MAX_SIZE 1024

int  password_validation(char *output);
void             hashing(char *input, char* output, int max_len);
void          user_input(char *input, int max_len);

int main()
{
    char  input[MAX_SIZE];
    char output[MAX_SIZE];
    user_input(input, sizeof input);
    hashing(input, output, sizeof output); 
    int k = password_validation(output);

    if (k == 0)
        printf("\n Secret information found!!! \n");
    else
        printf("\n try again \n");
    return 0;
}

void user_input(char* input, int max_len) {
    printf("Enter the password: \n");
    fgets(input, max_len, stdin); 
    if (input[strlen(input) - 1] == '\n')
        input[strlen(input) - 1] = '\0';
}

void hashing(char *input, char* output, int max_len) {
    int k = 0;
    for(int i = 0; input[i] != '\0' && k + 1 < max_len; ++i) {
        // empty
    }
    output[k] = '\0';
}

int password_validation(char* output) {
    return strcmp("090097099104082111104105116104083097109050048049056101104099115067104117114099104079102069109097099115095095", output);
}
Yunbin Liu
  • 1,484
  • 2
  • 11
  • 20
  • When posting an answer, please post good code. In this case, the answer fails to check the return value (for errors) for functions like `fgets()` – user3629249 Nov 06 '18 at 23:54