]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
lib/, src/: Consistently use NULL with fgets(3)
authorAlejandro Colomar <alx@kernel.org>
Sun, 21 Jul 2024 16:21:02 +0000 (18:21 +0200)
committerSerge Hallyn <serge@hallyn.com>
Fri, 28 Nov 2025 14:39:37 +0000 (08:39 -0600)
fgets(3) returns either NULL or the input pointer.  Checking for NULL is
more explicit, and simpler.

<stddef.h> is the header that provides NULL; add it where appropriate.

The meat of this patch can be approximated with the following semantic
patch:

$ cat ~/tmp/spatch/fgets_null.sp
@@
expression a, b, c;
@@

- fgets(a, b, c) == a
+ fgets(a, b, c) != NULL

@@
expression a, b, c;
@@

- fgetsx(a, b, c) == a
+ fgetsx(a, b, c) != NULL

@@
expression a, b, c, p;
@@

- p->cio_fgets(a, b, c) == a
+ p->cio_fgets(a, b, c) != NULL

@@
expression a, b, c;
@@

- fgets(a, b, c) != a
+ fgets(a, b, c) == NULL

@@
expression a, b, c;
@@

- fgetsx(a, b, c) != a
+ fgetsx(a, b, c) == NULL

@@
expression a, b, c, p;
@@

- p->cio_fgets(a, b, c) != a
+ p->cio_fgets(a, b, c) == NUL

Applied as

$ find contrib/ lib* src/ -type f \
| xargs spatch --sp-file ~/tmp/spatch/fgets_null.sp --in-place;

The differences between the actual patch and the approximation via the
semantic patch from above are includes, whitespace, braces, and a case
where there was an implicit pointer-to-bool comparison which I made
explicit.  When reviewing, it'll be useful to use git-diff(1) with '-w'
and '--color-words=.'.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
lib/commonio.c
lib/fields.c
lib/fputsx.c
lib/hushed.c
lib/loginprompt.c
lib/setupenv.c
lib/shadow/gshadow/fgetsgent.c
lib/ttytype.c
lib/user_busy.c
src/login_nopam.c
src/useradd.c

index 85bde16b9bf571ec6b09f640b31e458afbc95bab..5341f7b7eb2a90407b182d3a9f0293f50d8f0b7a 100644 (file)
@@ -16,6 +16,7 @@
 #include <fcntl.h>
 #include <limits.h>
 #include <signal.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/stat.h>
@@ -638,7 +639,7 @@ int commonio_open (struct commonio_db *db, int mode)
        if (NULL == buf)
                goto cleanup_errno;
 
-       while (db->ops->cio_fgets(buf, buflen, db->fp) == buf) {
+       while (db->ops->cio_fgets(buf, buflen, db->fp) != NULL) {
                struct commonio_entry  *p;
 
                while (   (strrchr (buf, '\n') == NULL)
index 2a6f54e5f264011b165f6eb817ce8423cd9a5b54..144e5fd09afcdbf7d9ec6229d6596256aa5394df 100644 (file)
@@ -12,8 +12,9 @@
 #include "fields.h"
 
 #include <ctype.h>
-#include <string.h>
+#include <stddef.h>
 #include <stdio.h>
+#include <string.h>
 
 #include "prototypes.h"
 #include "string/ctype/strisascii/strisprint.h"
@@ -68,9 +69,8 @@ change_field(char *buf, size_t maxsize, const char *prompt)
 
        printf ("\t%s [%s]: ", prompt, buf);
        (void) fflush (stdout);
-       if (fgets (newf, maxsize, stdin) != newf) {
+       if (fgets(newf, maxsize, stdin) == NULL)
                return;
-       }
 
        if (stpsep(newf, "\n") == NULL)
                return;
index 73495e4dee3ef4c9cb05a89f5ced1fd325da9e1c..0f86da4f35af6b9d10f40372f7cea5cf19db8822 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "config.h"
 
+#include <stddef.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -24,7 +25,7 @@ fgetsx(/*@returned@*/char *restrict buf, int cnt, FILE *restrict f)
        char *ep;
 
        while (cnt > 0) {
-               if (fgets (cp, cnt, f) != cp) {
+               if (fgets(cp, cnt, f) == NULL) {
                        if (cp == buf) {
                                return NULL;
                        } else {
index aadc287229878a42525d45f123c0cf7daac05572..c2df9a4b90dba62da4f4e8da54bda73e329f5715 100644 (file)
@@ -13,6 +13,7 @@
 #ident "$Id$"
 
 #include <pwd.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
@@ -73,7 +74,7 @@ bool hushed (const char *username)
        if (NULL == fp) {
                return false;
        }
-       for (found = false; !found && (fgets(buf, sizeof(buf), fp) == buf);) {
+       for (found = false; !found && (fgets(buf, sizeof(buf), fp) != NULL);) {
                stpsep(buf, "\n");
                found = streq(buf, pw->pw_shell) ||
                        streq(buf, pw->pw_name);
index 36ae7061652978809c17a3c2c410f329c745dea2..4798d1c61b3d7bc17c4d7d1f7ac79517c215e27b 100644 (file)
@@ -12,8 +12,9 @@
 #ident "$Id$"
 
 #include <assert.h>
-#include <stdio.h>
 #include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
 
 #include "attr.h"
 #include "defines.h"
@@ -83,9 +84,8 @@ login_prompt(char *name, int namesize)
         */
 
        memzero_a(buf);
-       if (fgets(buf, sizeof(buf), stdin) != buf) {
+       if (fgets(buf, sizeof(buf), stdin) == NULL)
                exit (EXIT_FAILURE);
-       }
 
        if (stpsep(buf, "\n") == NULL)
                exit(EXIT_FAILURE);
index 1bf8b3a35ef98a5b888813156e982efa29154c85..263221636d2b53d09767f1db7564999d83502359 100644 (file)
@@ -16,6 +16,7 @@
 #ident "$Id$"
 
 #include <assert.h>
+#include <stddef.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdio.h>
@@ -55,7 +56,7 @@ static void read_env_file (const char *filename)
        if (NULL == fp) {
                return;
        }
-       while (fgets(buf, sizeof(buf), fp) == buf) {
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
                if (stpsep(buf, "\n") == NULL)
                        break;
 
index 29ef11b720be039cf52d363d49a5e208645172e9..64e7d4541c29d59cf221b6b8f97dfbe789a008a7 100644 (file)
@@ -66,9 +66,8 @@ fgetsgent(FILE *fp)
                buflen *= 2;
 
                len = strlen (buf);
-               if (fgetsx(&buf[len], buflen - len, fp) != &buf[len]) {
+               if (fgetsx(&buf[len], buflen - len, fp) == NULL)
                        return NULL;
-               }
        }
        stpsep(buf, "\n");
        return sgetsgent(buf);
index b3c60be9d8ff410be269472eabab35a0a0560e6f..ee50ce3bc225830f9be8d96356ec0fb628e7f956 100644 (file)
@@ -11,6 +11,7 @@
 
 #ident "$Id$"
 
+#include <stddef.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -47,7 +48,7 @@ void ttytype (const char *line)
                        perror (typefile);
                return;
        }
-       while (fgets(buf, sizeof(buf), fp) == buf) {
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
                if (strprefix(buf, "#")) {
                        continue;
                }
index c265d49d41755084e402eb589b67ff5c76bf75dd..d08229cbe430cea695b3513084c31ff769846e19 100644 (file)
@@ -12,6 +12,7 @@
 #ident "$Id: $"
 
 #include <assert.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <dirent.h>
@@ -127,7 +128,7 @@ static int check_status (const char *name, const char *sname, uid_t uid)
        if (NULL == sfile) {
                return 0;
        }
-       while (fgets(line, sizeof(line), sfile) == line) {
+       while (fgets(line, sizeof(line), sfile) != NULL) {
                if (strprefix(line, "Uid:\t")) {
                        unsigned long ruid, euid, suid;
 
index 9cd147417d76c2f122bbef22a37b5adca94be2de..a41a3f0bd31f81d79eb3d4340126b2e23f4c8128 100644 (file)
@@ -100,7 +100,7 @@ login_access(const char *user, const char *from)
        if (NULL != fp) {
                intmax_t lineno = 0;    /* for diagnostics */
                while (   !match
-                      && (fgets(line, sizeof(line), fp) == line))
+                      && (fgets(line, sizeof(line), fp) != NULL))
                {
                        char  *p;
 
index fcf9b0d21554f59e297da49be5298bb6e14e2ce0..7cce5b703dc0b68f4e38fd8599f1442222ea3907 100644 (file)
 #include <getopt.h>
 #include <grp.h>
 #ifdef ENABLE_LASTLOG
-#include <lastlog.h>
+# include <lastlog.h>
 #endif /* ENABLE_LASTLOG */
 #include <libgen.h>
 #include <pwd.h>
 #include <signal.h>
 #ifdef ACCT_TOOLS_SETUID
-#ifdef USE_PAM
-#include "pam_defs.h"
-#endif                         /* USE_PAM */
+# ifdef USE_PAM
+#  include "pam_defs.h"
+# endif                                /* USE_PAM */
 #endif                         /* ACCT_TOOLS_SETUID */
 #include <paths.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/stat.h>
@@ -355,7 +356,7 @@ get_defaults(struct option_flags *flags)
         * Read the file a line at a time. Only the lines that have relevant
         * values are used, everything else can be ignored.
         */
-       while (fgets(buf, sizeof(buf), fp) == buf) {
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
                stpsep(buf, "\n");
 
                cp = stpsep(buf, "=");
@@ -587,7 +588,7 @@ set_defaults(void)
                goto skip;
        }
 
-       while (fgets(buf, sizeof(buf), ifp) == buf) {
+       while (fgets(buf, sizeof(buf), ifp) != NULL) {
                char  *val;
 
                if (stpsep(buf, "\n") == NULL) {