Blob Blame History Raw
From 61838b0fdacb71a881baac164043b8e40ddfbec5 Mon Sep 17 00:00:00 2001
From: Tom Hughes <tom@compton.nu>
Date: Tue, 17 Nov 2015 17:36:16 +0000
Subject: [PATCH] Remove size limit when expanding macros

This removes a seemingly undocumented, and not even well defined, limit
on the size of a macro expansion when parsing a spec file.

[lkardos@redhat.com: created new funtion expandMacrosU() (Unlimited)
instead of modifying expandMacros() in order not to change API/ABI]

Signed-off-by: Lubos Kardos <lkardos@redhat.com>
---
 build/files.c     |  6 ++++--
 build/pack.c      |  6 ++++--
 build/parseSpec.c | 10 ++++++----
 rpmio/macro.c     | 17 +++++++++++++++++
 rpmio/rpmmacro.h  | 12 ++++++++++++
 5 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/build/files.c b/build/files.c
index ea595b9..2fc434e 100644
--- a/build/files.c
+++ b/build/files.c
@@ -1631,11 +1631,13 @@ static rpmRC readFilesManifest(rpmSpec spec, Package pkg, const char *path)
     while (fgets(buf, sizeof(buf), fd)) {
 	if (handleComments(buf))
 	    continue;
-	if (expandMacros(spec, spec->macros, buf, sizeof(buf))) {
+	char *expanded = expandMacrosU(spec, spec->macros, buf);
+	if (expanded == NULL) {
 	    rpmlog(RPMLOG_ERR, _("line: %s\n"), buf);
 	    goto exit;
 	}
-	argvAdd(&(pkg->fileList), buf);
+	argvAdd(&(pkg->fileList), expanded);
+	free(expanded);
 	nlines++;
     }
 
diff --git a/build/pack.c b/build/pack.c
index 213d85e..6ffe450 100644
--- a/build/pack.c
+++ b/build/pack.c
@@ -132,11 +132,13 @@ static rpmRC addFileToTag(rpmSpec spec, const char * file,
     }
 
     while (fgets(buf, sizeof(buf), f)) {
-	if (expandMacros(spec, spec->macros, buf, sizeof(buf))) {
+	char *expanded = expandMacrosU(spec, spec->macros, buf);
+	if (expanded == NULL) {
 	    rpmlog(RPMLOG_ERR, _("%s: line: %s\n"), fn, buf);
 	    goto exit;
 	}
-	appendStringBuf(sb, buf);
+	appendStringBuf(sb, expanded);
+	free(expanded);
     }
     headerPutString(h, tag, getStringBuf(sb));
     rc = RPMRC_OK;
diff --git a/build/parseSpec.c b/build/parseSpec.c
index edc3d00..610e371 100644
--- a/build/parseSpec.c
+++ b/build/parseSpec.c
@@ -180,13 +180,15 @@ static int expandMacrosInSpecBuf(rpmSpec spec, int strip)
     if (lbuf[0] == '#')
 	isComment = 1;
 
-    lbuf = xstrdup(spec->lbuf);
+    lbuf = spec->lbuf;
 
-    rc = expandMacros(spec, spec->macros, spec->lbuf, spec->lbufSize);
-    if (rc) {
+    spec->lbuf = expandMacrosU(spec, spec->macros, lbuf);
+    if (spec->lbuf == NULL) {
 	rpmlog(RPMLOG_ERR, _("line %d: %s\n"),
-		spec->lineNum, spec->lbuf);
+		spec->lineNum, lbuf);
 	goto exit;
+    } else {
+	spec->lbufSize = strlen(spec->lbuf) + 1;
     }
 
     if (strip & STRIP_COMMENTS && isComment) {
diff --git a/rpmio/macro.c b/rpmio/macro.c
index 4b3c41b..4c8934e 100644
--- a/rpmio/macro.c
+++ b/rpmio/macro.c
@@ -1471,6 +1471,23 @@ int expandMacros(void * spec, rpmMacroContext mc, char * sbuf, size_t slen)
     return rc;
 }
 
+char *expandMacrosU(void * spec, rpmMacroContext mc, char * sbuf)
+{
+    char *target = NULL;
+    int rc;
+
+    mc = rpmmctxAcquire(mc);
+    rc = doExpandMacros(mc, sbuf, &target);
+    rpmmctxRelease(mc);
+
+    if (rc) {
+	free(target);
+	target = NULL;
+    }
+
+    return target;
+}
+
 void
 rpmDumpMacroTable(rpmMacroContext mc, FILE * fp)
 {
diff --git a/rpmio/rpmmacro.h b/rpmio/rpmmacro.h
index 765c78c..a4884b0 100644
--- a/rpmio/rpmmacro.h
+++ b/rpmio/rpmmacro.h
@@ -66,6 +66,18 @@ int	expandMacros	(void * spec, rpmMacroContext mc,
 				size_t slen);
 
 /** \ingroup rpmmacro
+ * Expand macro into buffer.
+ * @deprecated Use rpmExpand().
+ * @todo Eliminate from API.
+ * @param spec		cookie (unused)
+ * @param mc		macro context (NULL uses global context).
+ * @retval sbuf		input macro to expand
+ * @return		macro expansion (malloc'ed) or NULL on failure
+ */
+char	*expandMacrosU	(void * spec, rpmMacroContext mc,
+				char * sbuf);
+
+/** \ingroup rpmmacro
  * Add macro to context.
  * @deprecated Use rpmDefineMacro().
  * @param mc		macro context (NULL uses global context).
-- 
1.9.3

From aee8446eb498fec7bfd7a2848ab97440b7bb7226 Mon Sep 17 00:00:00 2001
From: Tom Hughes <tom@compton.nu>
Date: Mon, 23 Nov 2015 09:38:37 +0000
Subject: [PATCH 1/2] Rename expandMacrosU to rpmExpandMacros

Address review issues from #32 by renaming the function and
cleaning up the comment and parameter list.
---
 build/files.c     |  2 +-
 build/pack.c      |  2 +-
 build/parseSpec.c |  2 +-
 rpmio/macro.c     |  2 +-
 rpmio/rpmmacro.h  | 10 ++++------
 5 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/build/files.c b/build/files.c
index 4d49449..0bc4acc 100644
--- a/build/files.c
+++ b/build/files.c
@@ -1624,7 +1624,7 @@ static rpmRC readFilesManifest(rpmSpec spec, Package pkg, const char *path)
     while (fgets(buf, sizeof(buf), fd)) {
 	if (handleComments(buf))
 	    continue;
-	char *expanded = expandMacrosU(spec, spec->macros, buf);
+	char *expanded = rpmExpandMacros(spec->macros, buf, 0);
 	if (expanded == NULL) {
 	    rpmlog(RPMLOG_ERR, _("line: %s\n"), buf);
 	    goto exit;
diff --git a/build/pack.c b/build/pack.c
index 6ffe450..ec06bc8 100644
--- a/build/pack.c
+++ b/build/pack.c
@@ -132,7 +132,7 @@ static rpmRC addFileToTag(rpmSpec spec, const char * file,
     }
 
     while (fgets(buf, sizeof(buf), f)) {
-	char *expanded = expandMacrosU(spec, spec->macros, buf);
+	char *expanded = rpmExpandMacros(spec->macros, buf, 0);
 	if (expanded == NULL) {
 	    rpmlog(RPMLOG_ERR, _("%s: line: %s\n"), fn, buf);
 	    goto exit;
diff --git a/build/parseSpec.c b/build/parseSpec.c
index 610e371..6171bb0 100644
--- a/build/parseSpec.c
+++ b/build/parseSpec.c
@@ -182,7 +182,7 @@ static int expandMacrosInSpecBuf(rpmSpec spec, int strip)
 
     lbuf = spec->lbuf;
 
-    spec->lbuf = expandMacrosU(spec, spec->macros, lbuf);
+    spec->lbuf = rpmExpandMacros(spec->macros, lbuf, 0);
     if (spec->lbuf == NULL) {
 	rpmlog(RPMLOG_ERR, _("line %d: %s\n"),
 		spec->lineNum, lbuf);
diff --git a/rpmio/macro.c b/rpmio/macro.c
index 4c8934e..f9ca027 100644
--- a/rpmio/macro.c
+++ b/rpmio/macro.c
@@ -1471,7 +1471,7 @@ int expandMacros(void * spec, rpmMacroContext mc, char * sbuf, size_t slen)
     return rc;
 }
 
-char *expandMacrosU(void * spec, rpmMacroContext mc, char * sbuf)
+char *rpmExpandMacros(rpmMacroContext mc, const char * sbuf, int flags)
 {
     char *target = NULL;
     int rc;
diff --git a/rpmio/rpmmacro.h b/rpmio/rpmmacro.h
index a4884b0..f5ddcac 100644
--- a/rpmio/rpmmacro.h
+++ b/rpmio/rpmmacro.h
@@ -67,15 +67,13 @@ int	expandMacros	(void * spec, rpmMacroContext mc,
 
 /** \ingroup rpmmacro
  * Expand macro into buffer.
- * @deprecated Use rpmExpand().
- * @todo Eliminate from API.
- * @param spec		cookie (unused)
  * @param mc		macro context (NULL uses global context).
- * @retval sbuf		input macro to expand
+ * @param sbuf		input macro to expand
+ * @param flags		flags (currently unused)
  * @return		macro expansion (malloc'ed) or NULL on failure
  */
-char	*expandMacrosU	(void * spec, rpmMacroContext mc,
-				char * sbuf);
+char	*rpmExpandMacros	(rpmMacroContext mc, const char * sbuf,
+					int flags);
 
 /** \ingroup rpmmacro
  * Add macro to context.
-- 
1.9.3

From ddf9ec7befe83ba1a12453a56e4e471aa9bcf4d3 Mon Sep 17 00:00:00 2001
From: Lubos Kardos <lkardos@redhat.com>
Date: Thu, 26 Nov 2015 15:20:05 +0100
Subject: [PATCH 2/2] rpmExpandMacros() is modified to be able to return more
 return codes

Now rpmExpandMacros() returns integer as a return value. Negative return
value implies failure. Return values can be more utilized in the future.
E. g. return value could specify how many macros were expanded in given
string.
---
 build/files.c     |  4 ++--
 build/pack.c      |  4 ++--
 build/parseSpec.c | 21 +++++++++------------
 rpmio/macro.c     |  9 +++++----
 rpmio/rpmmacro.h  |  7 ++++---
 5 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/build/files.c b/build/files.c
index 0bc4acc..d00a785 100644
--- a/build/files.c
+++ b/build/files.c
@@ -1604,6 +1604,7 @@ static rpmRC readFilesManifest(rpmSpec spec, Package pkg, const char *path)
     FILE *fd = NULL;
     rpmRC rc = RPMRC_FAIL;
     unsigned int nlines = 0;
+    char *expanded;
 
     if (*path == '/') {
 	fn = rpmGetPath(path, NULL);
@@ -1624,8 +1625,7 @@ static rpmRC readFilesManifest(rpmSpec spec, Package pkg, const char *path)
     while (fgets(buf, sizeof(buf), fd)) {
 	if (handleComments(buf))
 	    continue;
-	char *expanded = rpmExpandMacros(spec->macros, buf, 0);
-	if (expanded == NULL) {
+	if(rpmExpandMacros(spec->macros, buf, &expanded, 0) < 0) {
 	    rpmlog(RPMLOG_ERR, _("line: %s\n"), buf);
 	    goto exit;
 	}
diff --git a/build/pack.c b/build/pack.c
index ec06bc8..bfb4c73 100644
--- a/build/pack.c
+++ b/build/pack.c
@@ -132,8 +132,8 @@ static rpmRC addFileToTag(rpmSpec spec, const char * file,
     }
 
     while (fgets(buf, sizeof(buf), f)) {
-	char *expanded = rpmExpandMacros(spec->macros, buf, 0);
-	if (expanded == NULL) {
+	char *expanded;
+	if(rpmExpandMacros(spec->macros, buf, &expanded, 0) < 0) {
 	    rpmlog(RPMLOG_ERR, _("%s: line: %s\n"), fn, buf);
 	    goto exit;
 	}
diff --git a/build/parseSpec.c b/build/parseSpec.c
index 6171bb0..9fff0e2 100644
--- a/build/parseSpec.c
+++ b/build/parseSpec.c
@@ -169,7 +169,7 @@ static int restoreFirstChar(rpmSpec spec)
 static int expandMacrosInSpecBuf(rpmSpec spec, int strip)
 {
     char *lbuf = NULL;
-    int rc = 0, isComment = 0;
+    int isComment = 0;
 
      /* Don't expand macros (eg. %define) in false branch of %if clause */
     if (!spec->readStack->reading)
@@ -180,17 +180,17 @@ static int expandMacrosInSpecBuf(rpmSpec spec, int strip)
     if (lbuf[0] == '#')
 	isComment = 1;
 
-    lbuf = spec->lbuf;
 
-    spec->lbuf = rpmExpandMacros(spec->macros, lbuf, 0);
-    if (spec->lbuf == NULL) {
+    if(rpmExpandMacros(spec->macros, spec->lbuf, &lbuf, 0) < 0) {
 	rpmlog(RPMLOG_ERR, _("line %d: %s\n"),
-		spec->lineNum, lbuf);
-	goto exit;
-    } else {
-	spec->lbufSize = strlen(spec->lbuf) + 1;
+		spec->lineNum, spec->lbuf);
+	return 1;
     }
 
+    free(spec->lbuf);
+    spec->lbuf = lbuf;
+    spec->lbufSize = strlen(spec->lbuf) + 1;
+
     if (strip & STRIP_COMMENTS && isComment) {
 	char *bufA = lbuf;
 	char *bufB = spec->lbuf;
@@ -212,10 +212,7 @@ static int expandMacrosInSpecBuf(rpmSpec spec, int strip)
 		spec->lineNum, lbuf);
     }
 
-exit:
-    free(lbuf);
-
-    return rc;
+    return 0;
 }
 
 /* Return zero on success, 1 if we need to read more and -1 on errors. */
diff --git a/rpmio/macro.c b/rpmio/macro.c
index f9ca027..0c009ea 100644
--- a/rpmio/macro.c
+++ b/rpmio/macro.c
@@ -1471,7 +1471,7 @@ int expandMacros(void * spec, rpmMacroContext mc, char * sbuf, size_t slen)
     return rc;
 }
 
-char *rpmExpandMacros(rpmMacroContext mc, const char * sbuf, int flags)
+int rpmExpandMacros(rpmMacroContext mc, const char * sbuf, char ** obuf, int flags)
 {
     char *target = NULL;
     int rc;
@@ -1482,10 +1482,11 @@ char *rpmExpandMacros(rpmMacroContext mc, const char * sbuf, int flags)
 
     if (rc) {
 	free(target);
-	target = NULL;
+	return -1;
+    } else {
+	*obuf = target;
+	return 1;
     }
-
-    return target;
 }
 
 void
diff --git a/rpmio/rpmmacro.h b/rpmio/rpmmacro.h
index f5ddcac..8027f98 100644
--- a/rpmio/rpmmacro.h
+++ b/rpmio/rpmmacro.h
@@ -69,11 +69,12 @@ int	expandMacros	(void * spec, rpmMacroContext mc,
  * Expand macro into buffer.
  * @param mc		macro context (NULL uses global context).
  * @param sbuf		input macro to expand
+ * @param obuf		macro expansion (malloc'ed)
  * @param flags		flags (currently unused)
- * @return		macro expansion (malloc'ed) or NULL on failure
+ * @return		negative on failure
  */
-char	*rpmExpandMacros	(rpmMacroContext mc, const char * sbuf,
-					int flags);
+int	rpmExpandMacros	(rpmMacroContext mc, const char * sbuf,
+				char ** obuf, int flags);
 
 /** \ingroup rpmmacro
  * Add macro to context.
-- 
1.9.3