summaryrefslogtreecommitdiff
path: root/src/repodata.c
diff options
context:
space:
mode:
authorMichael Schroeder <mls@suse.de>2014-03-25 19:01:20 +0100
committerMichael Schroeder <mls@suse.de>2014-03-25 19:01:20 +0100
commitb7dbb3c2dd915471cf41da9e29a551df4823eecc (patch)
treeb937ca3f44425562760fca8eb72b0de2e0eed3d7 /src/repodata.c
parentffc1e961c5c2f543f21a732b2d227872d629648f (diff)
downloadlibsolv-b7dbb3c2dd915471cf41da9e29a551df4823eecc.tar.gz
libsolv-b7dbb3c2dd915471cf41da9e29a551df4823eecc.tar.bz2
libsolv-b7dbb3c2dd915471cf41da9e29a551df4823eecc.zip
fix access to freed memory if we had to allocate a new schema when serializing a key
Diffstat (limited to 'src/repodata.c')
-rw-r--r--src/repodata.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/src/repodata.c b/src/repodata.c
index 86c4774..547b24b 100644
--- a/src/repodata.c
+++ b/src/repodata.c
@@ -3063,7 +3063,8 @@ repodata_internalize(Repodata *data)
{
Repokey *key, solvkey;
Id entry, nentry;
- Id schemaid, *schema, *sp, oldschema, *keyp, *keypstart, *seen;
+ Id schemaid, keyid, *schema, *sp, oldschema, *keyp, *seen;
+ int schemaoffset;
unsigned char *dp, *ndp;
int newschema, oldcount;
struct extdata newincore;
@@ -3185,18 +3186,19 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
data->mainschema = schemaid;
data->mainschemaoffsets = solv_calloc(sp - schema, sizeof(Id));
}
- keypstart = data->schemadata + data->schemata[schemaid];
- for (keyp = keypstart; *keyp; keyp++)
+ /* we don't use a pointer to the schemadata here as repodata_serialize_key
+ * may call repodata_schema2id() which might realloc our schemadata */
+ for (schemaoffset = data->schemata[schemaid]; (keyid = data->schemadata[schemaoffset]) != 0; schemaoffset++)
{
if (entry == -1)
- data->mainschemaoffsets[keyp - keypstart] = newincore.len;
- if (*keyp == solvkeyid)
+ data->mainschemaoffsets[schemaoffset - data->schemata[schemaid]] = newincore.len;
+ if (keyid == solvkeyid)
{
/* add flexarray entry count */
data_addid(&newincore, data->end - data->start);
break;
}
- key = data->keys + *keyp;
+ key = data->keys + keyid;
#if 0
fprintf(stderr, "internalize %d(%d):%s:%s\n", entry, entry + data->start, pool_id2str(data->repo->pool, key->name), pool_id2str(data->repo->pool, key->type));
#endif
@@ -3213,21 +3215,19 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
ndp = data_skip_key(data, dp, key);
oldcount--;
}
- if (seen[*keyp] == -1)
+ if (seen[keyid] == -1)
{
/* If this key was an old one _and_ was not overwritten with
a different value copy over the old value (we skipped it
above). */
if (dp != ndp)
data_addblob(&newincore, dp, ndp - dp);
- seen[*keyp] = 0;
+ seen[keyid] = 0;
}
- else if (seen[*keyp])
+ else if (seen[keyid])
{
- /* Otherwise we have a new value. Parse it into the internal
- form. */
- repodata_serialize_key(data, &newincore, &newvincore,
- schema, key, seen[*keyp] - 1);
+ /* Otherwise we have a new value. Parse it into the internal form. */
+ repodata_serialize_key(data, &newincore, &newvincore, schema, key, seen[keyid] - 1);
}
dp = ndp;
}