I know that an incorrect use of scanf()
to read user input can lead to undefined behavior and potentially security holes in a program. I've seen many people suggesting that is better to use fgets()
instead of scanf()
, but I know that getline()
automatically realloc whenever the line you are trying to read is larger than the buffer. The only case I can think about getline()
being unsafe is when the user sends too long a string to stdin so it attempts to allocate more memory than the OS can. I'm a little bit confused about this. Is that why people seem to prefer fgets()
over getline()
or it has nothing to do with it?
I haven't tried this in code. I just want to hear what experienced people think about this.
Here is an example program:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
int main() {
char *lineptr = NULL;
size_t n;
if(getline(&lineptr, &n, stdin) == -1)
perror("");
}
if you send 1 TB line to it then it will be killed when the system is out of memory (oom):
$ dd if=/dev/zero of=/dev/stdout bs=$((1024)) count=$((1024*1024*1024)) | ./a.out
Killed
Here is the corresponding dmesg log:
[855440.629377] Out of memory: Killed process 1387599 (a.out) total-vm:134252960kB, anon-rss:55714256kB, file-rss:1164kB, shmem-rss:0kB, UID:1000 pgtables:229544kB oom_score_adj:0
I was playing a Youtube video while this running and there were a few audio glitches but otherwise no ill effects were observed. I have 64 GB of memory and 64 GB of swap configured on a SSD. If you swap to a hard-drive you may be less fortunate.
You can impose a smaller limit (1 GB) with for example ulimit by either limiting the data seg size (-d) or virtual memory (-v):
$ ulimit -d $((1024*1024))
$ dd if=/dev/zero of=/dev/stdout bs=$((1024)) count=$((1024*1024*1024)) | ./a.out
Cannot allocate memory