Make rpmfiFNIndex() safe for callers on different indexes

- 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.
This commit is contained in:
Panu Matilainen 2012-04-12 15:15:26 +03:00
parent 2685bc0036
commit 11116a6786
2 changed files with 17 additions and 23 deletions

View 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);

View 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);