OSDN Git Service

libpwdgrp: can't depend on strlen(line_buff) != 0
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 31 Mar 2010 08:24:37 +0000 (10:24 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 31 Mar 2010 08:24:37 +0000 (10:24 +0200)
function                                             old     new   delta
bb__pgsreader                                        188     202     +14

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
libpwdgrp/pwd_grp.c

index 947f48d..5b0d6b2 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 #include "libbb.h"
-//#include <features.h>
 #include <assert.h>
 
 #ifndef _PATH_SHADOW
@@ -1000,7 +999,6 @@ static int bb__parsespent(void *data, char *line)
                        if (*endptr != ':') {
                                break;
                        }
-
                }
 
                *line++ = '\0';
@@ -1022,56 +1020,60 @@ static int bb__parsespent(void *data, char *line)
 static int bb__pgsreader(int (*parserfunc)(void *d, char *line), void *data,
                                char *__restrict line_buff, size_t buflen, FILE *f)
 {
-       int line_len;
        int skip;
        int rv = ERANGE;
 
        if (buflen < PWD_BUFFER_SIZE) {
                errno = rv;
-       } else {
-               skip = 0;
-               do {
-                       if (!fgets(line_buff, buflen, f)) {
-                               if (feof(f)) {
-                                       rv = ENOENT;
-                               }
-                               break;
-                       }
+               return rv;
+       }
 
-                       line_len = strlen(line_buff) - 1; /* strlen() must be > 0. */
-                       if (line_buff[line_len] == '\n') {
-                               line_buff[line_len] = 0;
-                       } else if (line_len + 2 == buflen) { /* line too long */
-                               ++skip;
-                               continue;
+       skip = 0;
+       while (1) {
+               if (!fgets(line_buff, buflen, f)) {
+                       if (feof(f)) {
+                               rv = ENOENT;
                        }
+                       break;
+               }
 
-                       if (skip) {
-                               --skip;
+               {
+                       int line_len = strlen(line_buff) - 1;
+                       if (line_len >= 0 && line_buff[line_len] == '\n') {
+                               line_buff[line_len] = '\0';
+                       } else
+                       if (line_len + 2 == buflen) {
+                               /* A start (or continuation) of overlong line */
+                               skip = 1;
                                continue;
-                       }
+                       } /* else: a last line in the file, and it has no '\n' */
+               }
 
-                       /* NOTE: glibc difference - glibc strips leading whitespace from
-                        * records.  We do not allow leading whitespace. */
-
-                       /* Skip empty lines, comment lines, and lines with leading
-                        * whitespace. */
-                       if (*line_buff && (*line_buff != '#') && !isspace(*line_buff)) {
-                               if (parserfunc == bb__parsegrent) {     /* Do evil group hack. */
-                                       /* The group entry parsing function needs to know where
-                                        * the end of the buffer is so that it can construct the
-                                        * group member ptr table. */
-                                       ((struct group *) data)->gr_name = line_buff + buflen;
-                               }
+               if (skip) {
+                       /* This "line" is a remainder of overlong line, ignore */
+                       skip = 0;
+                       continue;
+               }
 
-                               if (!parserfunc(data, line_buff)) {
-                                       rv = 0;
-                                       break;
-                               }
+               /* NOTE: glibc difference - glibc strips leading whitespace from
+                * records.  We do not allow leading whitespace. */
+
+               /* Skip empty lines, comment lines, and lines with leading
+                * whitespace. */
+               if (line_buff[0] != '\0' && line_buff[0] != '#' && !isspace(line_buff[0])) {
+                       if (parserfunc == bb__parsegrent) {
+                               /* Do evil group hack:
+                                * The group entry parsing function needs to know where
+                                * the end of the buffer is so that it can construct the
+                                * group member ptr table. */
+                               ((struct group *) data)->gr_name = line_buff + buflen;
                        }
-               } while (1);
-
-       }
+                       if (parserfunc(data, line_buff) == 0) {
+                               rv = 0;
+                               break;
+                       }
+               }
+       } /* while (1) */
 
        return rv;
 }