]> git.cameronkatri.com Git - mandoc.git/blobdiff - roff.c
Bugfix in roff_setstrn():
[mandoc.git] / roff.c
diff --git a/roff.c b/roff.c
index 5ea64e20acbf2ae3cdd810ab69dbc560edefebd9..30e923098edf90b9cf067b56a2690f2d8a8554d0 100644 (file)
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/*     $Id: roff.c,v 1.207 2014/04/20 16:46:05 schwarze Exp $ */
+/*     $Id: roff.c,v 1.211 2014/06/29 21:20:31 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -488,16 +488,15 @@ roff_alloc(struct mparse *parse, int options)
 static enum rofferr
 roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
 {
-       char             ubuf[12]; /* buffer to print the number */
+       char             ubuf[24]; /* buffer to print the number */
        const char      *start; /* start of the string to process */
-       const char      *stesc; /* start of an escape sequence ('\\') */
+       char            *stesc; /* start of an escape sequence ('\\') */
        const char      *stnam; /* start of the name, after "[(*" */
        const char      *cp;    /* end of the name, e.g. before ']' */
        const char      *res;   /* the string to be substituted */
        char            *nbuf;  /* new buffer to copy bufp to */
        size_t           maxl;  /* expected length of the escape name */
        size_t           naml;  /* actual length of the escape name */
-       size_t           ressz; /* size of the replacement string */
        int              expand_count;  /* to avoid infinite loops */
        int              npos;  /* position in numeric expression */
        int              irc;   /* return code from roff_evalnum() */
@@ -520,7 +519,7 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
                                break;
 
                if (0 == (stesc - cp) % 2) {
-                       stesc = cp;
+                       stesc = (char *)cp;
                        continue;
                }
 
@@ -614,11 +613,11 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
                        ubuf[1] = '\0';
                        break;
                case 'n':
-                       snprintf(ubuf, sizeof(ubuf), "%d",
+                       (void)snprintf(ubuf, sizeof(ubuf), "%d",
                            roff_getregn(r, stnam, naml));
                        break;
                case 'w':
-                       snprintf(ubuf, sizeof(ubuf), "%d",
+                       (void)snprintf(ubuf, sizeof(ubuf), "%d",
                            24 * (int)naml);
                        break;
                }
@@ -628,21 +627,17 @@ roff_res(struct roff *r, char **bufp, size_t *szp, int ln, int pos)
                            ln, (int)(stesc - *bufp), NULL);
                        res = "";
                }
-               ressz = strlen(res);
 
                /* Replace the escape sequence by the string. */
 
-               *szp += ressz + 1;
-               nbuf = mandoc_malloc(*szp);
-
-               strlcpy(nbuf, *bufp, (size_t)(stesc - *bufp + 1));
-               strlcat(nbuf, res, *szp);
-               strlcat(nbuf, cp, *szp);
+               *stesc = '\0';
+               *szp = mandoc_asprintf(&nbuf, "%s%s%s",
+                   *bufp, res, cp) + 1;
 
                /* Prepare for the next replacement. */
 
                start = nbuf + pos;
-               stesc = nbuf + (stesc - *bufp) + ressz;
+               stesc = nbuf + (stesc - *bufp) + strlen(res);
                free(*bufp);
                *bufp = nbuf;
        }
@@ -1943,7 +1938,8 @@ roff_so(ROFF_ARGS)
 {
        char *name;
 
-       mandoc_msg(MANDOCERR_SO, r->parse, ln, ppos, NULL);
+       name = *bufp + pos;
+       mandoc_vmsg(MANDOCERR_SO, r->parse, ln, ppos, ".so %s", name);
 
        /*
         * Handle `so'.  Be EXTREMELY careful, as we shouldn't be
@@ -1952,9 +1948,9 @@ roff_so(ROFF_ARGS)
         * or using absolute paths.
         */
 
-       name = *bufp + pos;
        if ('/' == *name || strstr(name, "../") || strstr(name, "/..")) {
-               mandoc_msg(MANDOCERR_SOPATH, r->parse, ln, pos, NULL);
+               mandoc_vmsg(MANDOCERR_SO_PATH, r->parse, ln, ppos,
+                   ".so %s", name);
                return(ROFF_ERR);
        }
 
@@ -1990,14 +1986,9 @@ roff_userdef(ROFF_ARGS)
                        cp += 2;
                        continue;
                }
-
-               *szp = strlen(n1) - 3 + strlen(arg[i]) + 1;
-               n2 = mandoc_malloc(*szp);
-
-               strlcpy(n2, n1, (size_t)(cp - n1 + 1));
-               strlcat(n2, arg[i], *szp);
-               strlcat(n2, cp + 3, *szp);
-
+               *cp = '\0';
+               *szp = mandoc_asprintf(&n2, "%s%s%s",
+                   n1, arg[i], cp + 3) + 1;
                cp = n2 + (cp - n1);
                free(n1);
                n1 = n2;
@@ -2077,7 +2068,8 @@ roff_setstrn(struct roffkv **r, const char *name, size_t namesz,
        /* Search for an existing string with the same name. */
        n = *r;
 
-       while (n && strcmp(name, n->key.p))
+       while (n && (namesz != n->key.sz ||
+                       strncmp(n->key.p, name, namesz)))
                n = n->next;
 
        if (NULL == n) {