Use a c++ string for macro expansion buffer

Natively allocate the struct so we can use a string in there.
This commit is contained in:
Panu Matilainen 2024-04-22 12:13:42 +03:00
parent 1721962889
commit 59984c66c5
1 changed files with 29 additions and 57 deletions

View File

@ -3,6 +3,9 @@
*/ */
#include "system.h" #include "system.h"
#include <string>
#include <stdarg.h> #include <stdarg.h>
#include <pthread.h> #include <pthread.h>
#include <errno.h> #include <errno.h>
@ -101,9 +104,7 @@ static void initLocks(void)
* Macro expansion state. * Macro expansion state.
*/ */
struct rpmMacroBuf_s { struct rpmMacroBuf_s {
char * buf; /*!< Expansion buffer. */ std::string buf; /*!< Expansion buffer. */
size_t tpos; /*!< Current position in expansion buffer */
size_t nb; /*!< No. bytes remaining in expansion buffer. */
int depth; /*!< Current expansion depth. */ int depth; /*!< Current expansion depth. */
int level; /*!< Current scoping level */ int level; /*!< Current scoping level */
int error; /*!< Errors encountered during expansion? */ int error; /*!< Errors encountered during expansion? */
@ -446,14 +447,14 @@ expandThis(rpmMacroBuf mb, const char * src, size_t slen, char **target, int *fl
/* Copy other state from "parent", but we want a buffer of our own */ /* Copy other state from "parent", but we want a buffer of our own */
umb = *mb; umb = *mb;
umb.buf = NULL; umb.buf = "";
umb.error = 0; umb.error = 0;
if (flagsp) if (flagsp)
umb.flags = *flagsp; umb.flags = *flagsp;
/* In case of error, flag it in the "parent"... */ /* In case of error, flag it in the "parent"... */
if (expandMacro(&umb, src, slen)) if (expandMacro(&umb, src, slen))
mb->error = 1; mb->error = 1;
*target = umb.buf; *target = xstrdup(umb.buf.c_str());
if (flagsp) if (flagsp)
*flagsp = umb.flags; *flagsp = umb.flags;
@ -463,8 +464,7 @@ expandThis(rpmMacroBuf mb, const char * src, size_t slen, char **target, int *fl
static rpmMacroBuf mbCreate(rpmMacroContext mc, int flags) static rpmMacroBuf mbCreate(rpmMacroContext mc, int flags)
{ {
rpmMacroBuf mb = (rpmMacroBuf)xcalloc(1, sizeof(*mb)); rpmMacroBuf mb = new rpmMacroBuf_s {};
mb->buf = NULL;
mb->depth = mc->depth; mb->depth = mc->depth;
mb->level = mc->level; mb->level = mc->level;
mb->macro_trace = print_macro_trace; mb->macro_trace = print_macro_trace;
@ -474,26 +474,17 @@ static rpmMacroBuf mbCreate(rpmMacroContext mc, int flags)
return mb; return mb;
} }
static void mbAllocBuf(rpmMacroBuf mb, size_t slen)
{
size_t blen = MACROBUFSIZ + slen;
mb->buf = (char *)xmalloc(blen + 1);
mb->buf[0] = '\0';
mb->tpos = 0;
mb->nb = blen;
}
static int mbInit(rpmMacroBuf mb, MacroExpansionData *med, size_t slen) static int mbInit(rpmMacroBuf mb, MacroExpansionData *med, size_t slen)
{ {
if (mb->buf == NULL) if (slen > 0)
mbAllocBuf(mb, slen); mb->buf.reserve(slen);
if (++mb->depth > max_macro_depth) { if (++mb->depth > max_macro_depth) {
rpmMacroBufErr(mb, 1, rpmMacroBufErr(mb, 1,
_("Too many levels of recursion in macro expansion. It is likely caused by recursive macro declaration.\n")); _("Too many levels of recursion in macro expansion. It is likely caused by recursive macro declaration.\n"));
mb->depth--; mb->depth--;
return -1; return -1;
} }
med->tpos = mb->tpos; /* save expansion pointer for printExpand */ med->tpos = mb->buf.size(); /* save expansion pointer for printExpand */
med->macro_trace = mb->macro_trace; med->macro_trace = mb->macro_trace;
med->expand_trace = mb->expand_trace; med->expand_trace = mb->expand_trace;
return 0; return 0;
@ -501,47 +492,33 @@ static int mbInit(rpmMacroBuf mb, MacroExpansionData *med, size_t slen)
static void mbFini(rpmMacroBuf mb, rpmMacroEntry me, MacroExpansionData *med) static void mbFini(rpmMacroBuf mb, rpmMacroEntry me, MacroExpansionData *med)
{ {
mb->buf[mb->tpos] = '\0';
mb->depth--; mb->depth--;
if (mb->error && rpmIsVerbose()) if (mb->error && rpmIsVerbose())
mb->expand_trace = 1; mb->expand_trace = 1;
if (mb->expand_trace) if (mb->expand_trace) {
printExpansion(mb, me, mb->buf + med->tpos, mb->buf + mb->tpos); printExpansion(mb, me, mb->buf.c_str() + med->tpos,
mb->buf.c_str() + mb->buf.size());
}
mb->macro_trace = med->macro_trace; mb->macro_trace = med->macro_trace;
mb->expand_trace = med->expand_trace; mb->expand_trace = med->expand_trace;
} }
void rpmMacroBufAppend(rpmMacroBuf mb, char c) void rpmMacroBufAppend(rpmMacroBuf mb, char c)
{ {
if (mb->nb < 1) { mb->buf += c;
mb->buf = xrealloc(mb->buf, mb->tpos + MACROBUFSIZ + 1);
mb->nb += MACROBUFSIZ;
}
mb->buf[mb->tpos++] = c;
mb->buf[mb->tpos] = '\0';
mb->nb--;
} }
void rpmMacroBufAppendStr(rpmMacroBuf mb, const char *str) void rpmMacroBufAppendStr(rpmMacroBuf mb, const char *str)
{ {
size_t len = strlen(str); mb->buf += str;
if (len > mb->nb) {
mb->buf = xrealloc(mb->buf, mb->tpos + mb->nb + MACROBUFSIZ + len + 1);
mb->nb += MACROBUFSIZ + len;
}
memcpy(mb->buf+mb->tpos, str, len + 1);
mb->tpos += len;
mb->nb -= len;
} }
static void mbUnquote(rpmMacroBuf mb, size_t off) static void mbUnquote(rpmMacroBuf mb, size_t off)
{ {
const int qchar = 0x1f; /* ASCII unit separator */ const int qchar = 0x1f; /* ASCII unit separator */
while (off < mb->tpos) { while (off < mb->buf.size()) {
if (mb->buf[off] == qchar) { if (mb->buf[off] == qchar) {
memmove(mb->buf + off, mb->buf + off + 1, mb->tpos - off - 1); mb->buf.erase(off, 1);
mb->tpos--;
mb->nb++;
} else { } else {
off++; off++;
} }
@ -583,17 +560,15 @@ doShellEscape(rpmMacroBuf mb, const char * cmd, size_t clen)
goto exit; goto exit;
} }
tpos = mb->tpos; tpos = mb->buf.size();
while ((c = fgetc(shf)) != EOF) { while ((c = fgetc(shf)) != EOF) {
rpmMacroBufAppend(mb, c); rpmMacroBufAppend(mb, c);
} }
(void) pclose(shf); (void) pclose(shf);
/* Delete trailing \r \n */ /* Delete trailing \r \n */
while (mb->tpos > tpos && iseol(mb->buf[mb->tpos-1])) { while (mb->buf.size() > tpos && iseol(mb->buf.back()))
mb->buf[--mb->tpos] = '\0'; mb->buf.pop_back();
mb->nb++;
}
exit: exit:
_free(buf); _free(buf);
@ -1491,7 +1466,7 @@ doMacro(rpmMacroBuf mb, rpmMacroEntry me, ARGV_t args, size_t *parsed)
{ {
rpmMacroEntry prevme = mb->me; rpmMacroEntry prevme = mb->me;
ARGV_t prevarg = mb->args; ARGV_t prevarg = mb->args;
size_t old_tpos = mb->tpos; size_t old_tpos = mb->buf.size();
/* Recursively expand body of macro */ /* Recursively expand body of macro */
if (me->flags & ME_FUNC) { if (me->flags & ME_FUNC) {
@ -1618,7 +1593,7 @@ expandMacro(rpmMacroBuf mb, const char *src, size_t slen)
f = fe = NULL; f = fe = NULL;
g = ge = NULL; g = ge = NULL;
if (mb->depth > 1) /* XXX full expansion for outermost level */ if (mb->depth > 1) /* XXX full expansion for outermost level */
med.tpos = mb->tpos; /* save expansion pointer for printExpand */ med.tpos = mb->buf.size(); /* save expansion pointer for printExpand */
lastc = NULL; lastc = NULL;
if ((se = findMacroEnd(s)) == NULL) { if ((se = findMacroEnd(s)) == NULL) {
rpmMacroBufErr(mb, 1, _("Unterminated %c: %s\n"), (char)*s, s); rpmMacroBufErr(mb, 1, _("Unterminated %c: %s\n"), (char)*s, s);
@ -1823,11 +1798,9 @@ static int doExpandMacros(rpmMacroContext mc, const char *src, int flags,
rc = expandMacro(mb, src, 0); rc = expandMacro(mb, src, 0);
mb->buf[mb->tpos] = '\0'; /* XXX just in case */ *target = xstrdup(mb->buf.c_str());
/* expanded output is usually much less than alloced buffer, downsize */
*target = xrealloc(mb->buf, mb->tpos + 1);
_free(mb); delete mb;
return rc; return rc;
} }
@ -1920,7 +1893,7 @@ static void popMacro(rpmMacroContext mc, const char * n)
static int defineMacro(rpmMacroContext mc, const char * macro, int level) static int defineMacro(rpmMacroContext mc, const char * macro, int level)
{ {
rpmMacroBuf mb = (rpmMacroBuf)xcalloc(1, sizeof(*mb)); rpmMacroBuf mb = new rpmMacroBuf_s {};
int rc; int rc;
size_t parsed = 0; size_t parsed = 0;
@ -1928,7 +1901,7 @@ static int defineMacro(rpmMacroContext mc, const char * macro, int level)
mb->mc = mc; mb->mc = mc;
doDefine(mb, macro, level, 0, &parsed); doDefine(mb, macro, level, 0, &parsed);
rc = mb->error; rc = mb->error;
_free(mb); delete mb;
return rc; return rc;
} }
@ -2026,9 +1999,8 @@ int rpmExpandThisMacro(rpmMacroContext mc, const char *n, ARGV_const_t args, ch
if (mep) { if (mep) {
rpmMacroBuf mb = mbCreate(mc, flags); rpmMacroBuf mb = mbCreate(mc, flags);
rc = expandThisMacro(mb, *mep, args, flags); rc = expandThisMacro(mb, *mep, args, flags);
mb->buf[mb->tpos] = '\0'; /* XXX just in case */ target = xstrdup(mb->buf.c_str());
target = xrealloc(mb->buf, mb->tpos + 1); delete mb;
_free(mb);
} }
rpmmctxRelease(mc); rpmmctxRelease(mc);
if (rc) { if (rc) {