diff --git a/rpmio/macro.c b/rpmio/macro.c index 6e2aa6213..b89a995c1 100644 --- a/rpmio/macro.c +++ b/rpmio/macro.c @@ -445,6 +445,61 @@ exit: _free(buf); } + +/* Names in the table must be in ASCII-code order */ +static struct builtins_s { + const char * name; +} const builtinmacros[] = { + { "P" }, + { "Q" }, + { "S" }, + { "basename" }, + { "define" }, + { "dirname" }, + { "dump" }, + { "echo" }, + { "error" }, + { "expand" }, + { "getconfdir" }, + { "getenv" }, + { "global" }, + { "load" }, + { "lua" }, + { "quote" }, + { "shrink" }, + { "suffix" }, + { "trace" }, + { "uncompress" }, + { "undefine" }, + { "url2path" }, + { "verbose" }, + { "warn" } +}; +static const size_t numbuiltins = sizeof(builtinmacros)/sizeof(*builtinmacros); + +static int namecmp(const void *name1, const void *name2) +{ + struct builtins_s *n1 = (struct builtins_s *)name1; + struct builtins_s *n2 = (struct builtins_s *)name2; + + return strcmp(n1->name, n2->name); +} + +/** + * Return a pointer to the built-in macro with the given name + * @param name macro name + * @return pointer to the built-in macro or NULL if not found + */ +static const struct builtins_s* lookupBuiltin(const char *name) +{ + struct builtins_s macro; + + macro.name = name; + + return bsearch(¯o, builtinmacros, numbuiltins, sizeof(*builtinmacros), + namecmp); +} + static const int validName(const char *name, size_t namelen, const char *action) { int rc = 0; @@ -457,6 +512,11 @@ validName(const char *name, size_t namelen, const char *action) { goto exit; } + if (lookupBuiltin(name)) { + rpmlog(RPMLOG_ERR, _("Macro %%%s is a built-in (%s)\n"), name, action); + goto exit; + } + rc = 1; exit: diff --git a/tests/rpmmacro.at b/tests/rpmmacro.at index 6352a28bc..f1fc15793 100644 --- a/tests/rpmmacro.at +++ b/tests/rpmmacro.at @@ -30,10 +30,12 @@ AT_SETUP([invalid rpm --define]) AT_KEYWORDS([macros]) AT_CHECK([ runroot rpm --define "_ that" +runroot rpm --define "undefine that" ], [1], [], [error: Macro %_ has illegal name (%define) +error: Macro %undefine is a built-in (%define) ]) AT_CLEANUP