Hi.
One bug, one possible bug and some small speed improvements.

(in GNU Global 6.3.4 source).

The bug is in getconfs() [conf.c] parameter sb is not tested in all the places
it is used, against NULL.
I added the following temporary test code after 'if (!exist) {', line 392:

        if(sb == NULL)
                die("sb == NULL in getconfs()");

and it kept dying [die()ing] and displaying that message.

The possible bug is in setupdbpath() [getdbpath.c], the return value from the 
call
to 's = strbuf_fgets(sb, fp, STRBUF_NOCRLF);' on line 306 could be NULL, and 
the next
function called is 'if (!test("d", s)) {', test() would use the previous 
pathname used,
which would be the wrong one or it would die(); if the file was empty, but not 
sure
if this is possible.

The speed improvements are:
 1. Removal of duplicate uses of strlen() in assoc.c and dbop.c
 2. A change to use strbuf_getlen() instead of strlen() in makepath() 
[makepath.c]
 3. A moved strlen() in getconfs() [conf.c] as the string it uses doesn't change
     in the loop.

I have also added some additions to the Doxygen comments.

Simon Dommett



diff -u -r old_6.3.4/libutil/args.c new_7.7.7/libutil/args.c
--- old_6.3.4/libutil/args.c    2015-02-02 09:32:23 +0000
+++ new_7.7.7/libutil/args.c    2015-03-08 07:47:36 +0000
@@ -93,7 +93,7 @@
 /**
  * args_open_gfind: #args_open like interface for handling output of 
@NAME{gfind}.
  *
- *     @param[in]      agp     GFIND descriptor
+ *     @param[in]      agp     #GFIND descriptor
  */
 void
 args_open_gfind(GFIND *agp)
@@ -170,11 +170,11 @@
 /**
  * preparse_options
  *
- *     @param[in]      argc
- *     @param[in]      argv
+ *     @param[in]      argc    main()'s argc integer
+ *     @param[in]      argv    main()'s argv string array
  *
- * Setup the GTAGSCONF and the GTAGSLABEL environment variable
- * according to the --gtagsconf and --gtagslabel option.
+ * Setup the @FILE{GTAGSCONF} and the @FILE{GTAGSLABEL} environment variables
+ * according to the @OPTION{--gtagsconf} and @OPTION{--gtagslabel} options.
  */
 void
 preparse_options(int argc, char *const *argv)
@@ -183,11 +183,11 @@
        char *p;
        char *confpath = NULL;
        char *label = NULL;
-       char *opt_gtagsconf = "--gtagsconf";
-       char *opt_gtagslabel = "--gtagslabel";
+       const char *opt_gtagsconf = "--gtagsconf";
+       const char *opt_gtagslabel = "--gtagslabel";
 
        for (i = 1; i < argc; i++) {
-               p = argv[i];
+               /* p = argv[i]; */
 
                if ((p = locatestring(argv[i], opt_gtagsconf, MATCH_AT_FIRST))) 
{
                        if (*p == '\0') {
@@ -222,11 +222,15 @@
                set_env("GTAGSLABEL", label);
 }
 /**
- * prepend_options: 
+ * prepend_options: creates a new argv main() array, by prepending (space 
separated)
+ *             options and arguments from the string argument @a options.
  *
- *     @param[in/out]  argc
- *     @param[in]      argv
- *     @param[in]      options
+ *     @param[in,out]  argc    pointer to main()'s argc integer
+ *     @param[in]      argv    main()'s argv string array
+ *     @param[in]      options string
+ *     @return The new argv array.
+ *
+ *     @remark The program's name is copied back into: returned[0] (argv[0]).
  */
 char **
 prepend_options(int *argc, char *const *argv, const char *options)
diff -u -r old_6.3.4/libutil/assoc.c new_7.7.7/libutil/assoc.c
--- old_6.3.4/libutil/assoc.c   2015-02-02 09:32:23 +0000
+++ new_7.7.7/libutil/assoc.c   2015-03-13 02:23:38 +0000
@@ -86,13 +86,14 @@
        DB *db = assoc->db;
        DBT key, dat;
        int status;
+       int length;
 
        if (db == NULL)
                die("associate array is not prepared.");
-       if (strlen(name) == 0)
+       if ((length = strlen(name)) == 0)
                die("primary key size == 0.");
        key.data = (char *)name;
-       key.size = strlen(name)+1;
+       key.size = length+1;
        dat.data = (char *)value;
        dat.size = strlen(value)+1;
 
@@ -119,13 +120,14 @@
        DB *db = assoc->db;
        DBT key, dat;
        int status;
+       int size;
 
        if (db == NULL)
                die("associate array is not prepared.");
-       if (strlen(name) == 0)
+       if ((size = strlen(name)) == 0)
                die("primary key size == 0.");
        key.data = (char *)name;
-       key.size = strlen(name)+1;
+       key.size = size+1;
        dat.data = (char *)value;
        dat.size = length;
 
diff -u -r old_6.3.4/libutil/conf.c new_7.7.7/libutil/conf.c
--- old_6.3.4/libutil/conf.c    2015-02-02 09:32:23 +0000
+++ new_7.7.7/libutil/conf.c    2015-03-13 02:23:36 +0000
@@ -113,7 +113,7 @@
  * readrecord: read recoed indexed by label.
  *
  *     @param[in]      label   label in config file
- *     @return         record
+ *     @return         record or @VAR{NULL}
  *
  * @par Jobs:
  * - skip comment.
@@ -176,6 +176,8 @@
  *     @param[out]     sb      string buffer
  *     @param[in]      label   record label
  *     @param[in]      level   nest level for check
+ *
+ * @remark This function may call itself (recursive)
  */
 static void
 includelabel(STRBUF *sb, const char *label, int        level)
@@ -204,7 +206,7 @@
  * configpath: get path of configuration file.
  *
  *     @param[in]      rootdir Project root directory
- *     @return         path name of the configuration file
+ *     @return         path name of the configuration file or @VAR{NULL}
  */
 static char *
 configpath(const char *rootdir)
@@ -357,9 +359,13 @@
        char buf[MAXPROPLEN];
        int all = 0;
        int exist = 0;
+       int bufsize;
 
        if (!opened)
                die("configuration file not opened.");
+       if (sb == NULL) {
+               return 0;
+       }
        /* 'path' is reserved name for the current path of configuration file */
        if (!strcmp(name, "path")) {
                if (config_path)
@@ -369,17 +375,18 @@
        if (!strcmp(name, "skip") || !strcmp(name, "gtags_parser") || 
!strcmp(name, "langmap"))
                all = 1;
        snprintf(buf, sizeof(buf), ":%s=", name);
+       bufsize = strlen(buf);
        p = confline;
        while ((p = locatestring(p, buf, MATCH_FIRST)) != NULL) {
-               if (exist && sb)
+               if (exist /* && sb */ )
                        strbuf_putc(sb, ',');           
                exist = 1;
-               for (p += strlen(buf); *p; p++) {
+               for (p += bufsize; *p; p++) {
                        if (*p == ':')
                                break;
                        if (*p == '\\' && *(p + 1) == ':')      /* quoted 
character */
                                p++;
-                       if (sb)
+                       /* if (sb) */
                                strbuf_putc(sb, *p);
                }
                if (!all)
diff -u -r old_6.3.4/libutil/dbop.c new_7.7.7/libutil/dbop.c
--- old_6.3.4/libutil/dbop.c    2015-02-02 09:32:23 +0000
+++ new_7.7.7/libutil/dbop.c    2015-03-14 06:08:44 +0000
@@ -215,7 +215,7 @@
  *     @param[in]      flags
  *                     #DBOP_DUP: allow duplicate records. <br>
  *                     #DBOP_SORTED_WRITE: use sorted writing. This requires 
@NAME{POSIX} sort.
- *     @return         descripter for @NAME{dbop_xxx()}
+ *     @return         descripter for @NAME{dbop_xxx()} or @VAR{NULL}
  *
  * Sorted wirting is fast because all writing is done by not insertion but 
addition.
  */
@@ -299,7 +299,7 @@
  *
  *     @param[in]      dbop    descripter
  *     @param[in]      name    name
- *     @return         pointer to data
+ *     @return         pointer to data or @VAR{NULL}
  */
 const char *
 dbop_get(DBOP *dbop, const char *name)
@@ -362,7 +362,7 @@
                return;
        }
        key.data = (char *)name;
-       key.size = strlen(name)+1;
+       key.size = len+1;
        dat.data = (char *)data;
        dat.size = strlen(data)+1;
 
@@ -449,7 +449,7 @@
        if (flag)
                strbuf_puts0(sb, flag);
        key.data = (char *)name;
-       key.size = strlen(name)+1;
+       key.size = len+1;
        dat.data = strbuf_value(sb);
        dat.size = strbuf_getlen(sb);
 
@@ -516,8 +516,8 @@
  *     @param[in]      preg    compiled regular expression if any.
  *     @param[in]      flags   following dbop_next call take over this. <br>
  *                     #DBOP_KEY:      read key part <br>
- *                     #DBOP_PREFIX:   prefix read; only valied when 
sequential read
- *     @return         data
+ *                     #DBOP_PREFIX:   prefix read; only valid when sequential 
read
+ *     @return         data or @VAR{NULL}
  */
 const char *
 dbop_first(DBOP *dbop, const char *name, regex_t *preg, int flags)
@@ -525,6 +525,7 @@
        DB *db = dbop->db;
        DBT key, dat;
        int status;
+       int len;
 
        dbop->preg = preg;
        dbop->ioflags = flags;
@@ -535,11 +536,11 @@
                return dbop3_first(dbop, name, preg, flags);
 #endif
        if (name) {
-               if (strlen(name) > MAXKEYLEN)
+               if ((len = strlen(name)) > MAXKEYLEN)
                        die("primary key too long.");
                strlimcpy(dbop->key, name, sizeof(dbop->key));
                key.data = (char *)name;
-               key.size = strlen(name);
+               key.size = len;
                /*
                 * includes NULL character unless prefix read.
                 */
@@ -597,7 +598,7 @@
  * dbop_next: get next record. 
  * 
  *     @param[in]      dbop    dbop descripter
- *     @return         data
+ *     @return         data or @VAR{NULL}
  *
  * @note dbop_next() always skip meta records.
  */
@@ -681,6 +682,8 @@
 }
 /**
  * get_flag: get flag value
+ * 
+ * @note Will return an empty string (not @VAR{NULL}), if not found/can't get.
  */
 const char *
 dbop_getflag(DBOP *dbop)
@@ -707,18 +710,22 @@
 }
 /**
  * dbop_getoption: get option
+ *
+ * @return the option's value or @VAR{NULL}
  */
 const char *
 dbop_getoption(DBOP *dbop, const char *key)
 {
        static char buf[1024];
        const char *p;
+       int keysize;
 
        if ((p = dbop_get(dbop, key)) == NULL)
                return NULL;
-       if (dbop->lastsize < strlen(key))
+       keysize = strlen(key);
+       if (dbop->lastsize < keysize)
                die("invalid format (dbop_getoption).");
-       for (p += strlen(key); *p && isspace((unsigned char)*p); p++)
+       for (p += keysize; *p && isspace((unsigned char)*p); p++)
                ;
        strlimcpy(buf, p, sizeof(buf));
        return buf;
diff -u -r old_6.3.4/libutil/getdbpath.c new_7.7.7/libutil/getdbpath.c
--- old_6.3.4/libutil/getdbpath.c       2015-02-02 09:32:23 +0000
+++ new_7.7.7/libutil/getdbpath.c       2015-03-13 02:23:38 +0000
@@ -304,7 +304,13 @@
                        }
                        sb = strbuf_open(0);
                        s = strbuf_fgets(sb, fp, STRBUF_NOCRLF);
-                       if (!test("d", s)) {
+                       if(s == NULL) {
+                               /* Empty file? */
+                               if(verbose)
+                                       fprintf(stderr, "'%s' ignored; 
strbuf_fgets() returned NULL.\n", path);
+                               goto ignore_lab;
+                       }
+                       if (!test("d", s)) {    /* XXX: if s == NULL, test() 
will use previous path used. */
                                if (verbose)
                                        fprintf(stderr, "'%s' ignored because 
it doesn't include existent directory name.\n", path);
                        } else {
@@ -316,6 +322,7 @@
                                        s = realpath(makepath(root, s, NULL), 
buf);
                                strlimcpy(root, s, MAXPATHLEN);
                        }
+ignore_lab:;
                        fclose(fp);
                        strbuf_close(sb);
                        break;
@@ -328,12 +335,13 @@
        return 0;
 }
 /**
- * in_the_project: test whether path is in the project.
+ * in_the_project: test whether @a path is in the project.
  *
- *     @param[in]      target file or directory
+ *     @param[in]      path    target file or directory
  *     @return         0: out of the project, 1: in the project
  *
- * Please pass an absolute path name which does not include '.' or '..'.
+ * @note Please pass an absolute path name which does not include @FILE{.} 
(current directory) or
+ *       @FILE{..} (parent directory).
  */
 int
 in_the_project(const char *path)
diff -u -r old_6.3.4/libutil/makepath.c new_7.7.7/libutil/makepath.c
--- old_6.3.4/libutil/makepath.c        2015-02-02 09:32:23 +0000
+++ new_7.7.7/libutil/makepath.c        2015-03-13 02:23:38 +0000
@@ -70,12 +70,11 @@
 makepath(const char *dir, const char *file, const char *suffix)
 {
        STATIC_STRBUF(sb);
-       int length;
        char sep = '/';
 
        strbuf_clear(sb);
        if (dir != NULL) {
-               if ((length = strlen(dir)) > MAXPATHLEN)
+               if ( strlen(dir) > MAXPATHLEN)
                        die("path name too long. '%s'\n", dir);
 
 #if defined(_WIN32) || defined(__DJGPP__)
@@ -93,7 +92,7 @@
                        strbuf_putc(sb, '.');
                strbuf_puts(sb, suffix);
        }
-       if ((length = strlen(strbuf_value(sb))) > MAXPATHLEN)
+       if ( strbuf_getlen(sb) > MAXPATHLEN)
                die("path name too long. '%s'\n", strbuf_value(sb));
        return strbuf_value(sb);
 }
diff -u -r old_6.3.4/libutil/path.c new_7.7.7/libutil/path.c
--- old_6.3.4/libutil/path.c    2015-02-02 09:32:23 +0000
+++ new_7.7.7/libutil/path.c    2015-03-06 05:00:56 +0000
@@ -165,6 +165,10 @@
 #if (defined(_WIN32) && !defined(__CYGWIN__)) || defined(__DJGPP__)
 /**
  * realpath: get the complete path
+ *
+ * @param[in]  in_path
+ * @param[out] out_path        result string
+ * @return     @a out_path
  */
 char *
 realpath(const char *in_path, char *out_path)
@@ -200,6 +204,8 @@
  *                     -1: base directory not found <br>
  *                     -2: permission error <br>
  *                     -3: cannot make directory
+ *
+ *     @remark Directories are created in mode 0775.
  */
 int
 makedirectories(const char *base, const char *rest, int verbose)
@@ -238,6 +244,8 @@
 }
 /**
  * trimpath: trim path name
+ *
+ * @remark Just skips over @CODE{"./"} at the beginning of @a path, if present.
  */
 const char *
 trimpath(const char *path)
@@ -248,6 +256,10 @@
 }
 /**
  * get the current directory
+ *
+ * @param[out] buf     result string
+ * @param[in]  size    size of @a buf
+ * @return     @a buf or NULL
  */
 char *
 vgetcwd(char *buf, size_t size) {
_______________________________________________
Bug-global mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-global

Reply via email to