Make rpmfiFNIndex() safe for callers on different indexes
authorPanu Matilainen <pmatilai@redhat.com>
Thu, 12 Apr 2012 12:15:26 +0000 (15:15 +0300)
committerPanu Matilainen <pmatilai@redhat.com>
Thu, 12 Apr 2012 12:29:18 +0000 (15:29 +0300)
- Previously this would return a pointer to an internal per-rpmfi buffer
  whose contents get silently overwritten on each call to rpmfiFNIndex(),
  making it unsafe for unsafe for random access for more than one
  active caller (such code does not currently exist in rpm though)
- Make rpmfiFNIndex() always return freshly allocated memory, and adjust
  the rpmfiFN() iteration wrapper to free and realloc the internal
  "buffer" on each call. It's a wee bit slower than before but it's
  not called *that* much, and if needed there are ways to optimize it.

lib/rpmfi.c
lib/rpmfi_internal.h

index 96fa39d..ab1269c 100644 (file)
@@ -180,30 +180,13 @@ const char * rpmfiDNIndex(rpmfi fi, int jx)
     return DN;
 }
 
-const char * rpmfiFNIndex(rpmfi fi, int ix)
+char * rpmfiFNIndex(rpmfi fi, int ix)
 {
-    const char * FN = "";
-
+    char *fn = NULL;
     if (fi != NULL && ix >= 0 && ix < fi->fc) {
-       char * t;
-       if (fi->fn == NULL) {
-           size_t dnlmax = 0, bnlmax = 0, len;
-           for (int i = 0; i < fi->dc; i++) {
-               if ((len = strlen(fi->dnl[i])) > dnlmax)
-                   dnlmax = len;
-           }
-           for (int i = 0; i < fi->fc; i++) {
-               if ((len = strlen(fi->bnl[i])) > bnlmax)
-                   bnlmax = len;
-           }
-           fi->fn = xmalloc(dnlmax + bnlmax + 1);
-       }
-       FN = t = fi->fn;
-       *t = '\0';
-       t = stpcpy(t, fi->dnl[fi->dil[ix]]);
-       t = stpcpy(t, fi->bnl[ix]);
+       fn = rstrscat(NULL, fi->dnl[fi->dil[ix]], fi->bnl[ix], NULL);
     }
-    return FN;
+    return fn;
 }
 
 rpmfileAttrs rpmfiFFlagsIndex(rpmfi fi, int ix)
@@ -1294,7 +1277,6 @@ void rpmfiFpLookup(rpmfi fi, fingerPrintCache fpc)
 
 RPMFI_ITERFUNC(const char *, BN, i)
 RPMFI_ITERFUNC(const char *, DN, j)
-RPMFI_ITERFUNC(const char *, FN, i)
 RPMFI_ITERFUNC(const char *, FLink, i)
 RPMFI_ITERFUNC(const char *, FUser, i)
 RPMFI_ITERFUNC(const char *, FGroup, i)
@@ -1312,6 +1294,18 @@ RPMFI_ITERFUNC(rpm_loff_t, FSize, i)
 RPMFI_ITERFUNC(rpm_color_t, FColor, i)
 RPMFI_ITERFUNC(uint32_t, FNlink, i)
 
+const char * rpmfiFN(rpmfi fi)
+{
+    const char *fn = ""; /* preserve behavior on errors */
+    if (fi != NULL) {
+       free(fi->fn);
+       fi->fn = rpmfiFNIndex(fi, fi->i);
+       if (fi->fn != NULL)
+           fn = fi->fn;
+    }
+    return fn;
+}
+
 const unsigned char * rpmfiFDigest(rpmfi fi, int *algo, size_t *len)
 {
     return rpmfiFDigestIndex(fi, fi ? fi->i : -1, algo, len);
index 50b9629..d9be7f5 100644 (file)
@@ -89,7 +89,7 @@ RPM_GNUC_INTERNAL
 const char * rpmfiDNIndex(rpmfi fi, int jx);
 
 RPM_GNUC_INTERNAL
-const char * rpmfiFNIndex(rpmfi fi, int ix);
+char * rpmfiFNIndex(rpmfi fi, int ix);
 
 RPM_GNUC_INTERNAL
 rpmVerifyAttrs rpmfiVFlagsIndex(rpmfi fi, int ix);