diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2010-09-27 16:03:56 +0300 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2010-09-27 16:10:36 +0300 |
commit | 46f32d25ce813ffd4df95605a3f745615ec90faa (patch) | |
tree | 3ed666de595a5267134f2a8442679b808ab96997 | |
parent | d8777387db3128ea5f4f5b211d2aa54736f7f717 (diff) | |
download | rpm-46f32d25ce813ffd4df95605a3f745615ec90faa.tar.gz rpm-46f32d25ce813ffd4df95605a3f745615ec90faa.tar.bz2 rpm-46f32d25ce813ffd4df95605a3f745615ec90faa.zip |
Eliminate the internal in-place-expansion buffer limitation
- Return the dynamically allocated expansion buffer to callers from
expandU(), except using a slightly less cryptic expandThis() name
for it now. Also deal with non-terminated strings centrally in
expandThis() instead of doing alloc + copy to terminate in every caller.
-rw-r--r-- | rpmio/macro.c | 62 |
1 files changed, 32 insertions, 30 deletions
diff --git a/rpmio/macro.c b/rpmio/macro.c index b8a9d5748..d460771f8 100644 --- a/rpmio/macro.c +++ b/rpmio/macro.c @@ -435,28 +435,33 @@ expandT(MacroBuf mb, const char * f, size_t flen) } /** - * Save source/target and expand macro in u. + * Macro-expand string src, return result in dynamically allocated buffer. * @param mb macro expansion state - * @param u input macro, output expansion - * @param ulen no. bytes in u buffer + * @param src string to expand + * @param slen input string length (or 0 for strlen()) + * @retval target pointer to expanded string (malloced) * @return result of expansion */ static int -expandU(MacroBuf mb, char * u, size_t ulen) +expandThis(MacroBuf mb, const char * src, size_t slen, char **target) { struct MacroBuf_s umb; int rc; + char *tstr = NULL; + + if (slen) { + tstr = xmalloc(slen + 1); + strncpy(tstr, src, slen); + tstr[slen] = '\0'; + } /* Copy other state from "parent", but we want a buffer of our own */ umb = *mb; umb.buf = NULL; - rc = expandMacro(&umb, u); - - /* Copy back result, flag error on truncation */ - rc += (rstrlcpy(u, umb.buf, ulen) >= ulen); - - _free(umb.buf); + rc = expandMacro(&umb, tstr ? tstr : src); + *target = umb.buf; + _free(tstr); return rc; } @@ -480,15 +485,12 @@ static void mbAppend(MacroBuf mb, char c) static int doShellEscape(MacroBuf mb, const char * cmd, size_t clen) { - size_t blen = MACROBUFSIZ + clen; - char *buf = xmalloc(blen); + char *buf = NULL; FILE *shf; int rc = 0; int c; - strncpy(buf, cmd, clen); - buf[clen] = '\0'; - rc = expandU(mb, buf, blen); + rc = expandThis(mb, cmd, clen, &buf); if (rc) goto exit; @@ -528,7 +530,7 @@ doDefine(MacroBuf mb, const char * se, int level, int expandbody) char *buf = xmalloc(blen); char *n = buf, *ne = n; char *o = NULL, *oe; - char *b, *be; + char *b, *be, *ebody = NULL; int c; int oc = ')'; @@ -622,15 +624,19 @@ doDefine(MacroBuf mb, const char * se, int level, int expandbody) goto exit; } - if (expandbody && expandU(mb, b, (&buf[blen] - b))) { - rpmlog(RPMLOG_ERR, _("Macro %%%s failed to expand\n"), n); - goto exit; + if (expandbody) { + if (expandThis(mb, b, 0, &ebody)) { + rpmlog(RPMLOG_ERR, _("Macro %%%s failed to expand\n"), n); + goto exit; + } + b = ebody; } addMacro(mb->mc, n, o, b, (level - 1)); exit: _free(buf); + _free(ebody); return se; } @@ -888,12 +894,9 @@ exit: static void doOutput(MacroBuf mb, int waserror, const char * msg, size_t msglen) { - size_t blen = MACROBUFSIZ + msglen; - char *buf = xmalloc(blen); + char *buf = NULL; - strncpy(buf, msg, msglen); - buf[msglen] = '\0'; - (void) expandU(mb, buf, blen); + (void) expandThis(mb, msg, msglen, &buf); if (waserror) rpmlog(RPMLOG_ERR, "%s\n", buf); else @@ -914,16 +917,15 @@ static void doFoo(MacroBuf mb, int negate, const char * f, size_t fn, const char * g, size_t gn) { - size_t blen = MACROBUFSIZ + fn + gn; - char *buf = xmalloc(blen); + char *buf = NULL; char *b = NULL, *be; int c; - buf[0] = '\0'; if (g != NULL) { - strncpy(buf, g, gn); - buf[gn] = '\0'; - (void) expandU(mb, buf, blen); + (void) expandThis(mb, g, gn, &buf); + } else { + buf = xmalloc(MACROBUFSIZ + fn + gn); + buf[0] = '\0'; } if (STREQ("basename", f, fn)) { if ((b = strrchr(buf, '/')) == NULL) |