-1

i wrote a small program to test strings in c and im having trouble understanding why it works when it seemingly shouldn`t, the code is:

#include <stdio.h>

int main() {
    
    char name[5];
    printf("Enter your name: ");
    scanf("%s",name);
    printf("you entered: %s\n",name);
    printf("your name is %d letters long\n", strlen(name));
    return 0;
}

entering a 5 letter name i expect to run into trouble bacause i can`t fit the 5 characters + null character ender into an array of size 5, however the program works fine:

enter image description here

2 Answers2

2

The other answer isn't wrong but it doesn't fully answer the question.

The reason this works is because c isn't strict about memory bounds. Even though you've allocated a char array of length 5, you can fill it past the end of the array and c won't stop you.

When you pass name to printf(), it simply reads the memory starting at the beginning of the array until it reaches the null terminator \0. The same is true for strlen(), it simply counts until it reaches the null terminator.

m-atoms
  • 61
  • 1
  • 5
  • 3
    It is worth noting that such [buffer overflows](https://en.wikipedia.org/wiki/Buffer_overflow) are not always harmless. Often, the overwritten data is important, and it may cause the program to crash, or the overflow can be used for security exploits. In this case, OP was just lucky that everything worked as intended. On a different compiler or different compiler settings, it may stop working. – Andreas Wenzel Jun 10 '21 at 22:46
  • 1
    "it simply counts until it reaches the null terminator." --> C species that the `p` in `strlen(p)`, point to a _string_ - which has a `'\0'`. It not a _string_, it is not "until it reaches the null terminator \0". It is undefined. – chux - Reinstate Monica Jun 11 '21 at 05:40
2

Other answers in this thread have mentioned this, but have not provided resources to help you better understand the issue. So, that is what I will do here.

You have created your first buffer overflow error. This is because C does not have memory safety, meaning that there no restrictions on the boundaries of memory unless explicitly implemented by the user.

In your case, the function scanf("%s",name); gets the data from the user and puts it in the buffer. This function does not check memory boundaries. This means that if the input size is larger than the allocated buffer you are writing outside your allocated memory. In many cases, it is harmless. However, it can be the source of really hard to find bugs and some vulnerabilities. The Wikipedia article about buffer overflow is excellent and explains everything in a lot of detail, which should help you get a better understanding.

The function that you used to read the length of the string strlen(name), also does not do a boundary check. If you look at the man page of strlen, you can see that it does not mention anything about memory boundaries. Instead, it states that it calculates the length between the start of the string and the next terminating null byte.

The strlen() function calculates the length of the string pointed to by s, excluding the terminating null byte ('\0').

So, why does your application work?
You have a function that does not care about memory boundaries when writing, and you have a function that does not care about memory boundaries when reading.

How can you prevent it from happening?
Luckily for you, you are not the first with this problem. If you are interested in understanding how you can prevent this from happening, I recommend you check out this post How to prevent scanf causing a buffer overflow in C? . If you are a beginner, I wouldn't recommend you implement these functions, as some are quite complicated when you are just getting started. However, you can look through the post and see what people are posting and find out more about things mentioned in that post.

bobveringa
  • 230
  • 2
  • 12
  • 1
    "This is because C does not have memory safety," is more like "does not require memory safety,". A compilation may have, might not (and usually not). It is _undefined behavior_. – chux - Reinstate Monica Jun 11 '21 at 05:36