Allocate macro buffers dynamically

- avoids some entirely needless overflow cases
- somewhat similarly to rpm5.org but use heap instead of stack
This commit is contained in:
Panu Matilainen 2008-02-01 13:00:40 +02:00
parent 56405587f4
commit cc69dd20b8
1 changed files with 67 additions and 45 deletions

View File

@ -484,24 +484,22 @@ expandU(MacroBuf mb, char * u, size_t ulen)
static int static int
doShellEscape(MacroBuf mb, const char * cmd, size_t clen) doShellEscape(MacroBuf mb, const char * cmd, size_t clen)
{ {
char pcmd[MACROBUFSIZ]; size_t blen = MACROBUFSIZ + clen;
char *buf = xmalloc(blen);
FILE *shf; FILE *shf;
int rc; int rc = 0;
int c; int c;
if (clen >= sizeof(pcmd)) { strncpy(buf, cmd, clen);
rpmlog(RPMLOG_ERR, _("Target buffer overflow\n")); buf[clen] = '\0';
return 1; rc = expandU(mb, buf, blen);
}
strncpy(pcmd, cmd, clen);
pcmd[clen] = '\0';
rc = expandU(mb, pcmd, sizeof(pcmd));
if (rc) if (rc)
return rc; goto exit;
if ((shf = popen(pcmd, "r")) == NULL) if ((shf = popen(buf, "r")) == NULL) {
return 1; rc = 1;
goto exit;
}
while((c = fgetc(shf)) != EOF) { while((c = fgetc(shf)) != EOF) {
if (mb->nb > 1) { if (mb->nb > 1) {
SAVECHAR(mb, c); SAVECHAR(mb, c);
@ -514,7 +512,10 @@ doShellEscape(MacroBuf mb, const char * cmd, size_t clen)
*(mb->t--) = '\0'; *(mb->t--) = '\0';
mb->nb++; mb->nb++;
} }
return 0;
exit:
_free(buf);
return rc;
} }
/** /**
@ -529,7 +530,9 @@ static const char *
doDefine(MacroBuf mb, const char * se, int level, int expandbody) doDefine(MacroBuf mb, const char * se, int level, int expandbody)
{ {
const char *s = se; const char *s = se;
char buf[MACROBUFSIZ], *n = buf, *ne = n; size_t blen = MACROBUFSIZ;
char *buf = xmalloc(blen);
char *n = buf, *ne = n;
char *o = NULL, *oe; char *o = NULL, *oe;
char *b, *be; char *b, *be;
int c; int c;
@ -617,21 +620,23 @@ doDefine(MacroBuf mb, const char * se, int level, int expandbody)
/* Options must be terminated with ')' */ /* Options must be terminated with ')' */
if (o && oc != ')') { if (o && oc != ')') {
rpmlog(RPMLOG_ERR, _("Macro %%%s has unterminated opts\n"), n); rpmlog(RPMLOG_ERR, _("Macro %%%s has unterminated opts\n"), n);
return se; goto exit;
} }
if ((be - b) < 1) { if ((be - b) < 1) {
rpmlog(RPMLOG_ERR, _("Macro %%%s has empty body\n"), n); rpmlog(RPMLOG_ERR, _("Macro %%%s has empty body\n"), n);
return se; goto exit;
} }
if (expandbody && expandU(mb, b, (&buf[sizeof(buf)] - b))) { if (expandbody && expandU(mb, b, (&buf[blen] - b))) {
rpmlog(RPMLOG_ERR, _("Macro %%%s failed to expand\n"), n); rpmlog(RPMLOG_ERR, _("Macro %%%s failed to expand\n"), n);
return se; goto exit;
} }
addMacro(mb->mc, n, o, b, (level - 1)); addMacro(mb->mc, n, o, b, (level - 1));
exit:
_free(buf);
return se; return se;
} }
@ -645,7 +650,8 @@ static const char *
doUndefine(rpmMacroContext mc, const char * se) doUndefine(rpmMacroContext mc, const char * se)
{ {
const char *s = se; const char *s = se;
char buf[MACROBUFSIZ], *n = buf, *ne = n; char *buf = xmalloc(MACROBUFSIZ);
char *n = buf, *ne = n;
int c; int c;
COPYNAME(ne, s, c); COPYNAME(ne, s, c);
@ -659,11 +665,13 @@ doUndefine(rpmMacroContext mc, const char * se)
if (!((c = *n) && (xisalpha(c) || c == '_') && (ne - n) > 2)) { if (!((c = *n) && (xisalpha(c) || c == '_') && (ne - n) > 2)) {
rpmlog(RPMLOG_ERR, rpmlog(RPMLOG_ERR,
_("Macro %%%s has illegal name (%%undefine)\n"), n); _("Macro %%%s has illegal name (%%undefine)\n"), n);
return se; goto exit;
} }
delMacro(mc, n); delMacro(mc, n);
exit:
_free(buf);
return se; return se;
} }
@ -786,7 +794,9 @@ static const char *
grabArgs(MacroBuf mb, const rpmMacroEntry me, const char * se, grabArgs(MacroBuf mb, const rpmMacroEntry me, const char * se,
const char * lastc) const char * lastc)
{ {
char buf[MACROBUFSIZ], *b, *be; size_t blen = MACROBUFSIZ;
char *buf = xmalloc(blen);
char *b, *be;
char aname[16]; char aname[16];
const char *opts, *o; const char *opts, *o;
int argc = 0; int argc = 0;
@ -834,7 +844,7 @@ grabArgs(MacroBuf mb, const rpmMacroEntry me, const char * se,
#ifdef NOTYET #ifdef NOTYET
/* XXX if macros can be passed as args ... */ /* XXX if macros can be passed as args ... */
expandU(mb, buf, sizeof(buf)); expandU(mb, buf, blen);
#endif #endif
/* Build argv array */ /* Build argv array */
@ -880,7 +890,7 @@ grabArgs(MacroBuf mb, const rpmMacroEntry me, const char * se,
if (c == '?' || (o = strchr(opts, c)) == NULL) { if (c == '?' || (o = strchr(opts, c)) == NULL) {
rpmlog(RPMLOG_ERR, _("Unknown option %c in %s(%s)\n"), rpmlog(RPMLOG_ERR, _("Unknown option %c in %s(%s)\n"),
(char)c, me->name, opts); (char)c, me->name, opts);
return se; goto exit;
} }
*be++ = '-'; *be++ = '-';
*be++ = c; *be++ = c;
@ -917,6 +927,8 @@ grabArgs(MacroBuf mb, const rpmMacroEntry me, const char * se,
/* Add unexpanded args as macro. */ /* Add unexpanded args as macro. */
addMacro(mb->mc, "*", NULL, b, mb->depth); addMacro(mb->mc, "*", NULL, b, mb->depth);
exit:
_free(buf);
return se; return se;
} }
@ -930,19 +942,17 @@ grabArgs(MacroBuf mb, const rpmMacroEntry me, const char * se,
static void static void
doOutput(MacroBuf mb, int waserror, const char * msg, size_t msglen) doOutput(MacroBuf mb, int waserror, const char * msg, size_t msglen)
{ {
char buf[MACROBUFSIZ]; size_t blen = MACROBUFSIZ + msglen;
char *buf = xmalloc(blen);
if (msglen >= sizeof(buf)) {
rpmlog(RPMLOG_ERR, _("Target buffer overflow\n"));
msglen = sizeof(buf) - 1;
}
strncpy(buf, msg, msglen); strncpy(buf, msg, msglen);
buf[msglen] = '\0'; buf[msglen] = '\0';
(void) expandU(mb, buf, sizeof(buf)); (void) expandU(mb, buf, blen);
if (waserror) if (waserror)
rpmlog(RPMLOG_ERR, "%s\n", buf); rpmlog(RPMLOG_ERR, "%s\n", buf);
else else
fprintf(stderr, "%s", buf); fprintf(stderr, "%s", buf);
_free(buf);
} }
/** /**
@ -958,18 +968,16 @@ static void
doFoo(MacroBuf mb, int negate, const char * f, size_t fn, doFoo(MacroBuf mb, int negate, const char * f, size_t fn,
const char * g, size_t gn) const char * g, size_t gn)
{ {
char buf[MACROBUFSIZ], *b = NULL, *be; size_t blen = MACROBUFSIZ + fn + gn;
char *buf = xmalloc(blen);
char *b = NULL, *be;
int c; int c;
buf[0] = '\0'; buf[0] = '\0';
if (g != NULL) { if (g != NULL) {
if (gn >= sizeof(buf)) {
rpmlog(RPMLOG_ERR, _("Target buffer overflow\n"));
gn = sizeof(buf) - 1;
}
strncpy(buf, g, gn); strncpy(buf, g, gn);
buf[gn] = '\0'; buf[gn] = '\0';
(void) expandU(mb, buf, sizeof(buf)); (void) expandU(mb, buf, blen);
} }
if (STREQ("basename", f, fn)) { if (STREQ("basename", f, fn)) {
if ((b = strrchr(buf, '/')) == NULL) if ((b = strrchr(buf, '/')) == NULL)
@ -1404,11 +1412,12 @@ int
expandMacros(void * spec, rpmMacroContext mc, char * sbuf, size_t slen) expandMacros(void * spec, rpmMacroContext mc, char * sbuf, size_t slen)
{ {
MacroBuf mb = xcalloc(1, sizeof(*mb)); MacroBuf mb = xcalloc(1, sizeof(*mb));
char *tbuf; char *tbuf = NULL;
int rc = 0; int rc = 0;
if (sbuf == NULL || slen == 0) if (sbuf == NULL || slen == 0)
goto exit; goto exit;
if (mc == NULL) mc = rpmGlobalMacroContext; if (mc == NULL) mc = rpmGlobalMacroContext;
tbuf = xcalloc(slen + 1, sizeof(*tbuf)); tbuf = xcalloc(slen + 1, sizeof(*tbuf));
@ -1515,19 +1524,20 @@ int
rpmLoadMacroFile(rpmMacroContext mc, const char * fn) rpmLoadMacroFile(rpmMacroContext mc, const char * fn)
{ {
FD_t fd = Fopen(fn, "r.fpio"); FD_t fd = Fopen(fn, "r.fpio");
char buf[MACROBUFSIZ]; size_t blen = MACROBUFSIZ;
char *buf = xmalloc(blen);
int rc = -1; int rc = -1;
if (fd == NULL || Ferror(fd)) { if (fd == NULL || Ferror(fd)) {
if (fd) (void) Fclose(fd); if (fd) (void) Fclose(fd);
return rc; goto exit;
} }
/* XXX Assume new fangled macro expansion */ /* XXX Assume new fangled macro expansion */
max_macro_depth = 16; max_macro_depth = 16;
buf[0] = '\0'; buf[0] = '\0';
while(rdcl(buf, sizeof(buf), fd) != NULL) { while(rdcl(buf, blen, fd) != NULL) {
char c, *n; char c, *n;
n = buf; n = buf;
@ -1539,6 +1549,9 @@ rpmLoadMacroFile(rpmMacroContext mc, const char * fn)
rc = rpmDefineMacro(mc, n, RMIL_MACROFILES); rc = rpmDefineMacro(mc, n, RMIL_MACROFILES);
} }
rc = Fclose(fd); rc = Fclose(fd);
exit:
_free(buf);
return rc; return rc;
} }
@ -1622,13 +1635,18 @@ rpmFreeMacros(rpmMacroContext mc)
char * char *
rpmExpand(const char *arg, ...) rpmExpand(const char *arg, ...)
{ {
char buf[MACROBUFSIZ], *p, *pe; size_t blen = MACROBUFSIZ;
char *buf = NULL;
char *p, *pe, *res;
const char *s; const char *s;
va_list ap; va_list ap;
if (arg == NULL) if (arg == NULL) {
return xstrdup(""); res = xstrdup("");
goto exit;
}
buf = xmalloc(blen);
buf[0] = '\0'; buf[0] = '\0';
p = buf; p = buf;
pe = stpcpy(p, arg); pe = stpcpy(p, arg);
@ -1637,8 +1655,12 @@ rpmExpand(const char *arg, ...)
while ((s = va_arg(ap, const char *)) != NULL) while ((s = va_arg(ap, const char *)) != NULL)
pe = stpcpy(pe, s); pe = stpcpy(pe, s);
va_end(ap); va_end(ap);
(void) expandMacros(NULL, NULL, buf, sizeof(buf)); (void) expandMacros(NULL, NULL, buf, blen);
return xstrdup(buf); res = xstrdup(buf);
exit:
_free(buf);
return res;
} }
int int