Home > database >  How do you manage buffer overflow without affecting other variables in C effectively?
How do you manage buffer overflow without affecting other variables in C effectively?

Time:07-17

Being a beginner to C after using Python, I have run into a very simple problem that I just cannot solve.

While I have seen many solutions on the buffer overflow over 1 input, I can't seem to find a solution to having buffer overflows over 2 inputs.

My program simply gathers input using scanf() for two different variables with a maximum length of 16 characters, while also trying not to store \n. The program then outputs the inputted variables.

The code:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("Enter a word: ");
    char word1[16];
    scanf(" s", word1);
    fflush(stdin);

    printf("Enter another word: ");
    char word2[16];
    scanf(" s", word2);
    fflush(stdin);

    printf("Your first input: %s\n", word1);
    printf("Your second input: %s\n", word2);
    
    return 0;
}

Everything works fine when I input strings that are under the length limit, however as soon as the second input is longer, everything becomes messed up, even if my first input is valid.

.

Working example:

Input 1 = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Input 2 = okay

word1 = AAAAAAAAAAAAAAAA

word2 = okay

Failed example:

Input 1 = okay

Input 2 = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

word1 =

word2 = AAAAAAAAAAAAAAAA

.

My only solution was to shorten how much scanf() reads to 15 (1 less then how much the strings can store)

printf("Enter a word: ");
char word1[16];
scanf(" s, word1);

But why does it not work with 16? Are there any other ways to fix it?

I have also been hearing that fflush() is very problematic and shouldn't be used. Why is that?

Also if you have any other advice with both this question and how I create public questions please let me know since it is my first time using this website.

CodePudding user response:

Strings in C are just arrays of characters. C does not know how long the string is, so it ends the string with a null byte (ie. 0). The string "okay" is really five bytes: {'o', 'k', 'a', 'y', '\0'}.

char word1[16] has space for 16 bytes, but that's only 15 characters plus the null byte.

Either allocate 17 characters, or limit yourself to 15 characters of input.

char word1[16];
scanf(" s", word1);

A common way to deal with this problem is to allocate a single large buffer, read into that, and then copy the input to a properly sized chunk of memory.

char input[1024];

printf("Enter a word: ");
scanf(" 23s", input);
char *word1 = strdup(input);

printf("Enter another word: ");
scanf(" 23s", input);
char *word2 = strdup(input);

I have also been hearing that fflush() is very problematic and shouldn't be used. Why is that?

Though some implementations allow it to be used for input (MacOS, Visual Studio), that is non-standard behavior and it is inconsistent between compilers. Standard fflush is only for output. It's best not to rely on implementation specific behavior and stick to the standard where possible.

CodePudding user response:

fflush(stdin); invokes undefined behaviour. Do not do it.

But why does it not work with 16? Are there any other ways to fix it?

Strings in C language have special character at the end called null terminating character. So if you have a 16 chars array you can only store 15 characters 1 null terminating character. It is the correct behaviour and you need always to remember about it.

int main(int argc, char *argv[])
{
    char str[] = "12345";

    printf("strlen(str) = %zu, sizeof(str) = %zu\n", strlen(str), sizeof(str));
}

https://godbolt.org/z/hz416hqer

strlen(str) = 5, sizeof(str) = 6
  • Related