diff --git a/thanks-for-fixes.md b/thanks-for-fixes.md index ad0086553..0072ae680 100644 --- a/thanks-for-fixes.md +++ b/thanks-for-fixes.md @@ -80,10 +80,28 @@ $ warning: this program uses gets(), which is unsafe. whereas without the warning it's much easier to see that it's a prompt. +Another great example is: + +```sh +$ cd 1990/cmills +$ ./cmills +Shuffle... +warning: this program uses gets(), which is unsafe. +Total $1000. Wager? +``` + In some entries this change is not possible, in one-liners it might make them too long (though it's also been possible to do it in some cases) and in some entries it's more complicated than others because of the annoying fact that for '"compatibility" reasons' `fgets()` retains the newline and `gets()` does not. +As the v7 man page used to say: + +``` +BUGS + +The fgets(3) function retains the newline while gets(3) does not, all in the +name of backward compatibility. +``` Some entries like [1992/adrian](1992/adrian/README.md) were more complicated in other ways due to the code generating other output and because of how it works @@ -94,6 +112,9 @@ fixes in that entry. In any case some of the entries have been updated this way for the reasons described above and in the [FAQ](/faq.md). +Where possible `gets` has been redefined to be `fgets` with the appropriate arg. +This is not always possible but if often is. + See also [bugs.md](/bugs.md) for a further discussion on the matter. @@ -125,7 +146,7 @@ they were not fixed as the problems were documented by the author or us. Of course it can be argued that by fixing these things it makes it more user friendly for modern enjoyment but even so it's very often the wrong way to go -about it. If the author does not mention it t hen it can be considered a bug +about it. If the author does not mention it then it can be considered a bug that can be fixed. See the [bugs.md](/bugs.md) for more information regarding this situation and @@ -408,9 +429,7 @@ commented out. ## [1986/hague](1986/hague/hague.c) ([README.md](1986/hague/README.md])) -Cody made this use `fgets()` to avoid alarming and annoying messages about -`gets()` being unsafe, sometimes interspersed with the output of the program. -For more details about that see the [FAQ](/faq.md). +Cody made this use `fgets()`. ## [1986/holloway](1986/holloway/holloway.c) ([README.md](1986/holloway/README.md])) @@ -599,15 +618,7 @@ size constraints of the contest). ## [1987/wall](1987/wall/wall.c) ([README.md](1987/wall/README.md])) -Cody made this safer by using `fgets()` instead of `gets()`. This prevents an -annoying and potentially alarming warning at compiling, linking or runtime. -Though this could be partly remedied through redirecting `stderr` to `/dev/null` -this would not truly resolve the problem either and in order to avoid the -warning one would have to always redirect `stderr` to `/dev/null`. - -Later Cody improved upon the `gets()`/`fgets()` change to make it more like the -original by redefining `gets()` to use `fgets()` (with the correct args) so that -the code can refer to `gets()` instead. +Cody made this use `fgets(3)`. ## [1987/westley](1987/westley/westley.c) ([README.md](1987/westley/README.md])) @@ -738,11 +749,7 @@ to itself and `pain()` does now. ## [1988/reddy](1988/reddy/reddy.c) ([README.md](1988/reddy/README.md)) -Cody made this use `fgets()` to prevent annoying warnings during compiling, -linking and runtime, the latter of which being the most annoying. - -Cody also restored the name of the winner in the README.md file that was missing -by some crazy chance. +Cody made this use `fgets(3)`. ## [1988/spinellis](1988/spinellis/spinellis.c) ([README.md](1988/spinellis/README.md])) @@ -981,17 +988,7 @@ judges was retained. Yusuke got this to work in modern systems (it previously resulted in a bus error). -To prevent alarming warnings at linking or runtime Cody made the entry use -`fgets()` rather than `gets()`. He notes that another option would have been to -redirect `stderr` to `/dev/null` but he did not think of that at the time. - -Cody later improved upon the `gets()`/`fgets()` fix to make it more like the -original where the code can refer to `gets()` in the way it originally did. This -was done through a macro to redefine `gets`. - -BTW: Cody asks the following question: if the compiler compiles, the linker -links and the user executes does that make the compiler the jury, the linker the -judge and user the executioner? :-) +Cody made this use `fgets(3)`. ## [1990/dds](1990/dds/dds.c) ([README.md](1990/dds/README.md])) @@ -1008,16 +1005,7 @@ Cody fixed another compiler error by removing the erroneous prototype to `fopen()`. Cody also changed a `char *` used for file I/O to be a proper `FILE *` and fixed a typo in [LANDER.BAS](1990/dds/LANDER.BAS). -Cody also made this use `fgets()` instead of `gets()` to make it safer and to -prevent an annoying and potentially alarming warning at compiling and/or linking -and/or runtime, the latter of which is unfortunately interspersed with the -output of the program. - -Later Cody improved the `gets()`/`fgets()` fix by redefining `gets()` to use -`fgets()`. Notice that the original entry used `fgets()` in one case as it has -to read from another file and in this place nothing was changed. - -With these improvements the entry looks much more like the original! +Cody also made this use `fgets(3)`. ## [1990/dg](1990/dg/dg.c) ([README.md](1990/dg/README.md])) @@ -1074,22 +1062,13 @@ suggested `-trigraphs`. Both work but we used Yusuke's idea. ## [1990/tbr](1990/tbr/tbr.c) ([README.md](1990/tbr/README.md])) Cody fixed this to work with modern compilers; `exit(3)` returns void but the -function was used in a binary expression so this wouldn't even compile. Cody -also changed the code to use `fgets()` instead of `gets()` so one would not get -a warning about the use of `gets()` at linking time or execution, the latter of +function was used in a binary expression so this wouldn't even compile. + +Cody also changed the code to use `fgets()` instead of `gets()` so one would not get +a warning about the use of `gets(3)` at linking time or execution, the latter of which was causing confusing output due to the warning being interspersed with the program's interactive output. -Cody later improved his fix so that it looks more like the original. A problem -that usually occurs with `gets()` to `fgets()` is for 'backwards compatibility' -(so the man page once said) `fgets()` retains the newline and `gets()` does not. -In this program if one does not remove the newline it breaks the program. This -usually requires that one check that `fgets()` does not return NULL but with -some experimenting this proved to seem to not be a problem here so by adding a -couple macros that redefine `exit()` and `gets()` a whole binary expression -could be removed (thus removing an extra `exit()` call) and it now almost looks -like the same as the original. - Additionally, Cody fixed the shortened version provided by the author in the same way as the original entry, first the compile fix and then later on making it look more like the original by redefining `exit` and also redefining `gets()` @@ -1121,11 +1100,10 @@ if (a[1]==NULL||a[2]==NULL||a[3]==NULL||a[4]==NULL||a[5]==NULL) return 1; be changed to just test the value of `A` when `a` is argv and `A` is argc? +Cody also changed the code to use `fgets(3)`. -Finally Cody changed this program to use `fgets()` not `gets()` to make it safer -and to prevent a warning about `gets()` at linking or runtime. Since this -program is so incredible the extra fixes were deemed worth having and this is why -it was done. +Since this program is so incredible the extra fixes were deemed worth having and +this is why it was done. Cody later disabled a warning in the Makefile that proved to be a problem only with clang in linux but which was defaulting to an error. This way was the @@ -1256,8 +1234,8 @@ string. Thus the end of the string actually looks like: !.Xop.fssps!.Xop.sfuvso.uzqf!.Xop.jnqmjdju.gvodujpo.efdmbsbujpo!b/d ``` -But then there is the matter of getting the C to use `fgets()`. As can be seen -above it's not as simple as changing `gets()` to `fgets()`. This was more magic +But then there is the matter of getting the C to use `fgets(3)`. As can be seen +above it's not as simple as changing `gets(3)` to `fgets(3)`. This was more magic characters that had to be updated and some added. The C code: ```c @@ -1327,8 +1305,8 @@ It is hoped that this is the last time the string has to be updated to work with all versions of clang but if not the above is how it works. With these changes in place it will compile and work with both gcc and clang and -the C code generated will use `fgets()`, not `gets()`, therefore removing the -annoying warnings. Note that the array passed to `fgets()` is an int but that +the C code generated will use `fgets(3)`, not `gets(3)`, therefore removing the +annoying warnings. Note that the array passed to `fgets(3)` is an int but that was the same for `gets()` and is not necessary to update to a `char[]`. The key to the string is that it rotates the character by `+1`. This was not @@ -1439,33 +1417,27 @@ Cody also restored a slightly more obscure line of code that had been changed: though it's questionable how much more (if at all) obscure that is :-) -Cody also changed the location that it used `gets()` to be `fgets()` instead to -make it safer and to prevent annoying warnings during compiling, linking or -runtime (interspersed with the program's output). This was complicated because -of how the other source files are generated (as above); simply changing the code -could cause invalid output in the program which made other files fail to compile -(for this example specifically, see below). +Cody also changed the location that it used `gets()` to be `fgets(3)`. +This was complicated because of how the other source files are generated (as +above); simply changing the code could cause invalid output in the program which +made other files fail to compile (for this example specifically, see below). -One might think that simply changing the `gets()` to `fgets()` (with `stdin`) -would work but it did not because `fgets()` stores the newline and `gets()` does +One might think that simply changing the `gets(3)` to `fgets(3)` (with `stdin`) +would work but it did not because `fgets(3)` stores the newline and `gets(3)` does not. That is well known but this code was relying on not having this newline in a different way (see also above). -With `fgets()` the code `if(A(Y)) puts(Y);` ended up printing an extra line +With `fgets(3)` the code `if(A(Y)) puts(Y);` ended up printing an extra line which made the generation of some files (like `adhead.c`) fail to compile. Why? There was a blank line after a `\` at the end of the first line of a _macro definition_! Thus the code now first trims off the last character of the buffer read to get the same correct functionality but in a safe and non obnoxious way. -Later Cody improved the change to `fgets()` to make it slightly more like the -original. This still requires the additional stripping of the newline inside the -loop but now it uses what looks like before, just a call to `gets()`. - -But the improvement so that it uses `gets()` could not be changed to have the -macro do the removal of the extra line (as in with a comma operator or a `&&`) -as this, as might be expected from the above, caused compilation errors with -another generated file (`adwc.c`)! Thus after the `gets()` call in the line that -looks like: +In this case the macro for `gets` could not be changed to have the macro do the +removal of the extra line (as in with a comma operator or a `&&`) as this, as +might be expected from the above, caused compilation errors with another +generated file (`adwc.c`)! Thus after the `gets(3)` call in the line that looks +like: ```c while( gets(Y) ){ Y[strlen(Y)-1]='\0'; if(A(Y)) puts(Y); } @@ -1522,18 +1494,18 @@ commands that we suggested and some additional ones that provide for some fun. Cody fixed a crash that prevented this entry from working in some cases in some systems (like macOS) by disabling the optimiser in the Makefile. -Cody also changed the buffer size in such a way that `gets()` should be safe +Cody also changed the buffer size in such a way that `gets(3)` should be safe (theoretically) as it comes from the command line (though it can also read input -from stdin after starting the program). Ideally `fgets()` would be used but this +from stdin after starting the program). Ideally `fgets(3)` would be used but this is a more problematic. Previously it had a buffer size of 256 which could -easily overflow. In this entry `gets()` is used in a more complicated way: +easily overflow. In this entry `gets(3)` is used in a more complicated way: first `m` is set to `*++p` in a for loop where `p` is argv. Later `m` is set to -point to `h` which was of size 256. `gets()` is called as `m = gets(m)`) but -trying to change it to use `fgets()` proved more a problem. Since the input must +point to `h` which was of size 256. `gets(3)` is called as `m = gets(m)`) but +trying to change it to use `fgets(3)` proved more a problem. Since the input must come from the command line Cody changed the buffer size to `ARG_MAX+1` which should be enough (again theoretically) especially since the command expects redirecting a dictionary file as part of the command line. This also makes it -possible for longer strings to be read (in case the `gets()` was not used in a +possible for longer strings to be read (in case the `gets(3)` was not used in a loop). Cody also added the [mkdict.sh](1992/gson/mkdict.sh) script that the author @@ -1578,17 +1550,9 @@ Judges' remarks in the README.md file) this will not work with clang. Cody also provided the `runme.sh` script to demonstrate it as using make was problematic. -Cody made it use `fgets()` instead of `gets()` to prevent annoying warnings -getting in the way (in linux linking in a binary with `gets()` produces a -warning that might get in the way with this entry and in macOS at runtime it -prints a warning which often is interspersed with the output of the program -which can be confusing). +Cody made it use `fgets()` instead of `gets()`. -Cody later improved the `fgets()` change to look more like the original i.e. it -now uses a redefined `gets()`. This did require modifying the line number with -`#line 1` under the macro `gets()`. - -Still this cannot work with clang due to different compiler messages. See +NOTE: this entry cannot work with clang due to different compiler messages. See [bugs.md](/bugs.md) for details. @@ -1718,12 +1682,7 @@ compile time. See the README.md for details. ## [1993/schnitzi](1993/schnitzi/schnitzi.c) ([README.md](1993/schnitzi/README.md])) -Cody made this use `fgets()` not `gets()` to make it safer and to prevent an -annoying warning with compiling and/or linking and/or runtime, the latter of -which is unfortunately interspersed with the output of the program itself. - -Cody later improved the fix to use `gets()` via a macro so that it looks like -the original code. +Cody made this use `fgets(3)` not `gets(3)`. ## [1993/vanb](1993/vanb/vanb.c) ([README.md](1993/vanb/README.md])) @@ -1808,12 +1767,10 @@ Cody also fixed it for clang under linux which objected to incompatible pointer type (because `time(2)` takes a `time_t *` which in some systems is a `long *` but what was being passed to it is an `int`). -Cody also changed the entry to use `fgets()` instead of `gets()` to make it safe -for lines greater than 231 in length and to prevent a warning at linking or at -runtime, the latter of which can be interspersed with output of the program. -Note that this now prints a newline after the output but this seems like a -worthy compromise for preventing the interspersed output in macOS and at the -same time it's safer (fixing it to not have the extra newline is more +Cody also changed the entry to use `fgets(3)` instead of `gets(3)`. This one has +a minor annoyance in that it now prints a newline after the output but this +seems like a worthy compromise for preventing the interspersed output in macOS +and at the same time it's safer (fixing it to not have the extra newline is more problematic than it's worth and in macOS another line of output would be shown without the change anyway and the difference is that now it's just a blank line rather than an annoying warning). @@ -2257,14 +2214,9 @@ commands that we recommended. ## [2000/anderson](2000/anderson/anderson.c) ([README.md](2000/anderson/README.md])) -Cody changed this entry to use `fgets()` instead of `gets()` to make it safer -and to prevent annoying warnings from showing up at compiling, linking and/or -runtime, the latter interspersed with the output of the program. This involved +Cody changed this entry to use `fgets(3)` instead of `gets(3)`. This involved changing the `K` arg to `gets(3)` to `&K` in `fgets(3)`. -Cody later improved the fix to use `gets()` by redefining `gets()` so that the -code looks like before. - Cody also added the [try.sh](2000/anderson/try.sh) script.