Fix %{uncompress:...} double-expanding arguments + other miscellania
%{uncompress:...} is fairly complicated as far as builtin macros go: it needs to first expand its argument to discover the actual file its supposed to look at, then determine whether the file exists and what sort of compression to use, then determine the macro to use for decompressing that kind of file, expand said macro and finally catenate the expanded argument to the lot. That's a lot of goo to do inline doFoo(), so refactor it into a separate function. Up to now the last step was implemented by re-expanding the argument too, which makes it impossible to reliably handle paths with percent signs. Just expand the command, and catenate the argument as deity intended. Additionally make behavior with empty argument consistent with other builtins: %{uncompress:} expands to nothing instead of printing out an error message with an empty filename.
This commit is contained in:
parent
94623389ba
commit
227cddca88
107
rpmio/macro.c
107
rpmio/macro.c
|
@ -144,6 +144,8 @@ static void doSP(MacroBuf mb, int chkexist, int negate,
|
|||
const char * f, size_t fn, const char * g, size_t gn);
|
||||
static void doTrace(MacroBuf mb, int chkexist, int negate,
|
||||
const char * f, size_t fn, const char * g, size_t gn);
|
||||
static void doUncompress(MacroBuf mb, int chkexist, int negate,
|
||||
const char * f, size_t fn, const char * g, size_t gn);
|
||||
|
||||
static const char * doDef(MacroBuf mb, const char * se);
|
||||
static const char * doGlobal(MacroBuf mb, const char * se);
|
||||
|
@ -577,7 +579,7 @@ static struct builtins_s {
|
|||
{ STR_AND_LEN("suffix"), doFoo, NULL, 1 },
|
||||
{ STR_AND_LEN("trace"), doTrace, NULL, 0 },
|
||||
{ STR_AND_LEN("u2p"), doFoo, NULL, 1 },
|
||||
{ STR_AND_LEN("uncompress"),doFoo, NULL, 1 },
|
||||
{ STR_AND_LEN("uncompress"),doUncompress, NULL, 1 },
|
||||
{ STR_AND_LEN("undefine"), NULL, doUndefine, 0 },
|
||||
{ STR_AND_LEN("url2path"), doFoo, NULL, 1 },
|
||||
{ STR_AND_LEN("verbose"), doFoo, NULL, 1 },
|
||||
|
@ -1074,6 +1076,65 @@ doSP(MacroBuf mb, int chkexist, int negate,
|
|||
free(buf);
|
||||
}
|
||||
|
||||
static void doUncompress(MacroBuf mb, int chkexist, int negate,
|
||||
const char * f, size_t fn, const char * g, size_t gn)
|
||||
{
|
||||
rpmCompressedMagic compressed = COMPRESSED_OTHER;
|
||||
char *b, *be, *buf = NULL;
|
||||
int c;
|
||||
|
||||
if (gn) {
|
||||
expandThis(mb, g, gn, &buf);
|
||||
for (b = buf; (c = *b) && isblank(c);)
|
||||
b++;
|
||||
for (be = b; (c = *be) && !isblank(c);)
|
||||
be++;
|
||||
*be++ = '\0';
|
||||
}
|
||||
|
||||
if (gn == 0 || *b == '\0')
|
||||
goto exit;
|
||||
|
||||
if (rpmFileIsCompressed(b, &compressed))
|
||||
mb->error = 1;
|
||||
|
||||
switch (compressed) {
|
||||
default:
|
||||
case COMPRESSED_NOT:
|
||||
expandMacro(mb, "%__cat ", 0);
|
||||
break;
|
||||
case COMPRESSED_OTHER:
|
||||
expandMacro(mb, "%__gzip -dc ", 0);
|
||||
break;
|
||||
case COMPRESSED_BZIP2:
|
||||
expandMacro(mb, "%__bzip2 -dc ", 0);
|
||||
break;
|
||||
case COMPRESSED_ZIP:
|
||||
expandMacro(mb, "%__unzip ", 0);
|
||||
break;
|
||||
case COMPRESSED_LZMA:
|
||||
case COMPRESSED_XZ:
|
||||
expandMacro(mb, "%__xz -dc ", 0);
|
||||
break;
|
||||
case COMPRESSED_LZIP:
|
||||
expandMacro(mb, "%__lzip -dc ", 0);
|
||||
break;
|
||||
case COMPRESSED_LRZIP:
|
||||
expandMacro(mb, "%__lrzip -dqo- ", 0);
|
||||
break;
|
||||
case COMPRESSED_7ZIP:
|
||||
expandMacro(mb, "%__7zip x ", 0);
|
||||
break;
|
||||
case COMPRESSED_ZSTD:
|
||||
expandMacro(mb, "%__zstd -dc ", 0);
|
||||
break;
|
||||
}
|
||||
mbAppendStr(mb, buf);
|
||||
|
||||
exit:
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute macro primitives.
|
||||
* @param mb macro expansion state
|
||||
|
@ -1089,8 +1150,7 @@ doFoo(MacroBuf mb, int chkexist, int negate, const char * f, size_t fn,
|
|||
const char * g, size_t gn)
|
||||
{
|
||||
char *buf = NULL;
|
||||
char *b = NULL, *be;
|
||||
int c;
|
||||
char *b = NULL;
|
||||
int verbose = (rpmIsVerbose() != 0);
|
||||
int expand = (g != NULL && gn > 0);
|
||||
int expandagain = 1;
|
||||
|
@ -1158,47 +1218,6 @@ doFoo(MacroBuf mb, int chkexist, int negate, const char * f, size_t fn,
|
|||
} else if (STREQ("url2path", f, fn) || STREQ("u2p", f, fn)) {
|
||||
(void)urlPath(buf, (const char **)&b);
|
||||
if (*b == '\0') b = "/";
|
||||
} else if (STREQ("uncompress", f, fn)) {
|
||||
rpmCompressedMagic compressed = COMPRESSED_OTHER;
|
||||
for (b = buf; (c = *b) && isblank(c);)
|
||||
b++;
|
||||
for (be = b; (c = *be) && !isblank(c);)
|
||||
be++;
|
||||
*be++ = '\0';
|
||||
if (rpmFileIsCompressed(b, &compressed))
|
||||
mb->error = 1;
|
||||
switch (compressed) {
|
||||
default:
|
||||
case COMPRESSED_NOT:
|
||||
sprintf(be, "%%__cat %s", b);
|
||||
break;
|
||||
case COMPRESSED_OTHER:
|
||||
sprintf(be, "%%__gzip -dc %s", b);
|
||||
break;
|
||||
case COMPRESSED_BZIP2:
|
||||
sprintf(be, "%%__bzip2 -dc %s", b);
|
||||
break;
|
||||
case COMPRESSED_ZIP:
|
||||
sprintf(be, "%%__unzip %s", b);
|
||||
break;
|
||||
case COMPRESSED_LZMA:
|
||||
case COMPRESSED_XZ:
|
||||
sprintf(be, "%%__xz -dc %s", b);
|
||||
break;
|
||||
case COMPRESSED_LZIP:
|
||||
sprintf(be, "%%__lzip -dc %s", b);
|
||||
break;
|
||||
case COMPRESSED_LRZIP:
|
||||
sprintf(be, "%%__lrzip -dqo- %s", b);
|
||||
break;
|
||||
case COMPRESSED_7ZIP:
|
||||
sprintf(be, "%%__7zip x %s", b);
|
||||
break;
|
||||
case COMPRESSED_ZSTD:
|
||||
sprintf(be, "%%__zstd -dc %s", b);
|
||||
break;
|
||||
}
|
||||
b = be;
|
||||
} else if (STREQ("getenv", f, fn)) {
|
||||
b = getenv(buf);
|
||||
} else if (STREQ("getconfdir", f, fn)) {
|
||||
|
|
|
@ -189,7 +189,7 @@ runroot rpm \
|
|||
])
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([uncompress macro])
|
||||
AT_SETUP([uncompress macro 1])
|
||||
AT_KEYWORDS([macros])
|
||||
AT_CHECK([
|
||||
runroot rpm \
|
||||
|
@ -201,6 +201,18 @@ runroot rpm \
|
|||
])
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([uncompress macro 2])
|
||||
AT_KEYWORDS([macros])
|
||||
AT_CHECK([
|
||||
echo xxxxxxxxxxxxxxxxxxxxxxxxx > ${RPMTEST}/tmp/"some%%ath"
|
||||
runroot rpm \
|
||||
--eval "%{uncompress:/tmp/some%%%%ath}"
|
||||
],
|
||||
[0],
|
||||
[/usr/bin/cat /tmp/some%%ath
|
||||
])
|
||||
|
||||
AT_CLEANUP
|
||||
AT_SETUP([basename macro])
|
||||
AT_KEYWORDS([macros])
|
||||
AT_CHECK([
|
||||
|
@ -251,6 +263,8 @@ AT_CHECK([
|
|||
runroot rpm --eval "%{dirname}"
|
||||
runroot rpm --eval "%{dirname:}"
|
||||
runroot rpm --eval "%{dirname:dir}"
|
||||
runroot rpm --eval "%{uncompress}"
|
||||
runroot rpm --eval "%{uncompress:}"
|
||||
runroot rpm --eval "%{getncpus:}"
|
||||
runroot rpm --eval "%{getncpus:5}"
|
||||
runroot rpm --eval "%{define:}"
|
||||
|
@ -259,8 +273,10 @@ runroot rpm --eval "%{dump:foo}"
|
|||
[1],
|
||||
[
|
||||
dir
|
||||
|
||||
],
|
||||
[error: %dirname: argument expected
|
||||
error: %uncompress: argument expected
|
||||
error: %getncpus: unexpected argument
|
||||
error: %getncpus: unexpected argument
|
||||
error: %define: unexpected argument
|
||||
|
|
Loading…
Reference in New Issue