X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Frepo_solv.c;h=5858d4fc6c31f1518d157c859cc934c09f642897;hb=e679b515eddb3dd340fb25620de0160211f40fdc;hp=0eedc18a19264ad22a4c041a7137d187b88d085c;hpb=228d41221788430a09b85c488d62363c006c0993;p=platform%2Fupstream%2Flibsolv.git diff --git a/src/repo_solv.c b/src/repo_solv.c index 0eedc18..5858d4f 100644 --- a/src/repo_solv.c +++ b/src/repo_solv.c @@ -7,9 +7,9 @@ /* * repo_solv.c - * + * * Add a repo in solv format - * + * */ @@ -113,7 +113,7 @@ read_id(Repodata *data, Id max) if (!(c & 128)) { x = (x << 7) | c; - if (max && x >= max) + if (max && x >= (unsigned int)max) { data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "read_id: id too large (%u/%u)", x, max); return 0; @@ -149,7 +149,7 @@ read_idarray(Repodata *data, Id max, Id *map, Id *store, Id *end) continue; } x = (x << 6) | (c & 63); - if (max && x >= max) + if (max && x >= (unsigned int)max) { data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "read_idarray: id too large (%u/%u)", x, max); return 0; @@ -217,13 +217,13 @@ data_read_idarray(unsigned char *dp, Id **storep, Id *map, int max, Repodata *da continue; } x = (x << 6) | (c & 63); - if (max && x >= max) + if (max && x >= (unsigned int)max) { data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "data_read_idarray: id too large (%u/%u)", x, max); data->error = SOLV_ERROR_ID_RANGE; break; } - *store++ = x; + *store++ = map ? map[x] : x; if ((c & 64) == 0) break; x = 0; @@ -261,7 +261,7 @@ data_read_rel_idarray(unsigned char *dp, Id **storep, Id *map, int max, Repodata } x = old + (x - 1); old = x; - if (max && x >= max) + if (max && x >= (unsigned int)max) { data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "data_read_rel_idarray: id too large (%u/%u)", x, max); break; @@ -360,7 +360,7 @@ incore_add_ideof(Repodata *data, Id sx, int eof) static void incore_add_blob(Repodata *data, unsigned char *buf, int len) { - if (data->incoredatafree < len) + if (data->incoredatafree < (unsigned int)len) { data->incoredata = solv_realloc(data->incoredata, data->incoredatalen + INCORE_ADD_CHUNK + len); data->incoredatafree = INCORE_ADD_CHUNK + len; @@ -444,8 +444,8 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) { Pool *pool = repo->pool; int i, l; - unsigned int numid, numrel, numdir, numsolv; - unsigned int numkeys, numschemata; + int numid, numrel, numdir, numsolv; + int numkeys, numschemata; Offset sizeid; Offset *str; /* map Id -> Offset into string space */ @@ -502,7 +502,7 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) extendstart = repo->start; extendend = repo->end; } - + memset(&data, 0, sizeof(data)); data.repo = repo; data.fp = fp; @@ -519,16 +519,26 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) return pool_error(pool, SOLV_ERROR_UNSUPPORTED, "unsupported SOLV version"); } - numid = read_u32(&data); - numrel = read_u32(&data); - numdir = read_u32(&data); - numsolv = read_u32(&data); - numkeys = read_u32(&data); - numschemata = read_u32(&data); + numid = (int)read_u32(&data); + numrel = (int)read_u32(&data); + numdir = (int)read_u32(&data); + numsolv = (int)read_u32(&data); + numkeys = (int)read_u32(&data); + numschemata = (int)read_u32(&data); solvflags = read_u32(&data); - if (numdir && numdir < 2) + if (numid < 0 || numid >= 0x20000000) + return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of ids"); + if (numrel < 0 || numrel >= 0x20000000) + return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of rels"); + if (numdir && (numdir < 2 || numdir >= 0x20000000)) return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of dirs"); + if (numsolv < 0 || numsolv >= 0x20000000) + return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of solvables"); + if (numkeys < 0 || numkeys >= 0x20000000) + return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of keys"); + if (numschemata < 0 || numschemata >= 0x20000000) + return pool_error(pool, SOLV_ERROR_CORRUPT, "bad number of schematas"); if (numrel && (flags & REPO_LOCALPOOL) != 0) return pool_error(pool, SOLV_ERROR_CORRUPT, "relations are forbidden in a local pool"); @@ -548,10 +558,10 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) /* * read strings and Ids - * + * */ - + /* * alloc buffers */ @@ -561,7 +571,7 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) spool = &pool->ss; /* alloc max needed string buffer and string pointers, will shrink again later */ #if 0 - spool->stringspace = solv_realloc(spool->stringspace, spool->sstrings + sizeid + 1); + spool->stringspace = solv_realloc(spool->stringspace, spool->sstrings + sizeid + 1); spool->strings = solv_realloc2(spool->strings, spool->nstrings + numid, sizeof(Offset)); #else spool->sstrings += sizeid + 1; @@ -575,7 +585,7 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) { data.localpool = 1; spool = &data.spool; - spool->stringspace = solv_malloc(7 + sizeid + 1); + spool->stringspace = solv_malloc(7 + sizeid + 1); spool->strings = solv_malloc2(numid < 2 ? 2 : numid, sizeof(Offset)); strcpy(spool->stringspace, ""); spool->sstrings = 7; @@ -587,7 +597,7 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) /* * read string data and append to old string space */ - + strsp = spool->stringspace + spool->sstrings; /* append new entries */ if ((solvflags & SOLV_FLAG_PREFIX_POOL) == 0) { @@ -602,7 +612,7 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) unsigned int pfsize = read_u32(&data); char *prefix = solv_malloc(pfsize); char *pp = prefix; - char *old_str = 0; + char *old_str = strsp; char *dest = strsp; int freesp = sizeid; @@ -672,35 +682,16 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) /* alloc id map for name and rel Ids. this maps ids in the solv files * to the ids in our pool */ idmap = solv_calloc(numid + numrel, sizeof(Id)); - - /* grow hash if needed, otherwise reuse */ - hashmask = mkmask(spool->nstrings + numid); + stringpool_resize_hash(spool, numid); + hashtbl = spool->stringhashtbl; + hashmask = spool->stringhashmask; #if 0 POOL_DEBUG(SOLV_DEBUG_STATS, "read %d strings\n", numid); - POOL_DEBUG(SOLV_DEBUG_STATS, "string hash buckets: %d, old %d\n", hashmask + 1, spool->stringhashmask + 1); + POOL_DEBUG(SOLV_DEBUG_STATS, "string hash buckets: %d\n", hashmask + 1); #endif - if (hashmask > spool->stringhashmask) - { - spool->stringhashtbl = solv_free(spool->stringhashtbl); - spool->stringhashmask = hashmask; - spool->stringhashtbl = hashtbl = solv_calloc(hashmask + 1, sizeof(Id)); - for (i = 1; i < spool->nstrings; i++) - { - h = strhash(spool->stringspace + spool->strings[i]) & hashmask; - hh = HASHCHAIN_START; - while (hashtbl[h]) - h = HASHCHAIN_NEXT(h, hh, hashmask); - hashtbl[h] = i; - } - } - else - { - hashtbl = spool->stringhashtbl; - hashmask = spool->stringhashmask; - } - /* * run over strings and merge with pool. + * we could use stringpool_str2id, but this is faster. * also populate id map (maps solv Id -> pool Id) */ for (i = 1; i < numid; i++) @@ -748,53 +739,30 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) idmap[i] = id; /* repo relative -> pool relative */ sp += l; /* next string */ } - if (hashmask > mkmask(spool->nstrings + 8192)) - { - spool->stringhashtbl = solv_free(spool->stringhashtbl); - spool->stringhashmask = 0; - } stringpool_shrink(spool); /* vacuum */ } - + /******* Part 2: Relation IDs ***************************************/ /* * read RelDeps - * + * */ - + if (numrel) { /* extend rels */ pool->rels = solv_realloc2(pool->rels, pool->nrels + numrel, sizeof(Reldep)); ran = pool->rels; - /* grow hash if needed, otherwise reuse */ - hashmask = mkmask(pool->nrels + numrel); + pool_resize_rels_hash(pool, numrel); + hashtbl = pool->relhashtbl; + hashmask = pool->relhashmask; #if 0 POOL_DEBUG(SOLV_DEBUG_STATS, "read %d rels\n", numrel); - POOL_DEBUG(SOLV_DEBUG_STATS, "rel hash buckets: %d, old %d\n", hashmask + 1, pool->relhashmask + 1); + POOL_DEBUG(SOLV_DEBUG_STATS, "rel hash buckets: %d\n", hashmask + 1); #endif - if (hashmask > pool->relhashmask) - { - pool->relhashtbl = solv_free(pool->relhashtbl); - pool->relhashmask = hashmask; - pool->relhashtbl = hashtbl = solv_calloc(hashmask + 1, sizeof(Id)); - for (i = 1; i < pool->nrels; i++) - { - h = relhash(ran[i].name, ran[i].evr, ran[i].flags) & hashmask; - hh = HASHCHAIN_START; - while (hashtbl[h]) - h = HASHCHAIN_NEXT(h, hh, hashmask); - hashtbl[h] = i; - } - } - else - { - hashtbl = pool->relhashtbl; - hashmask = pool->relhashmask; - } /* * read RelDeps from repo @@ -827,11 +795,6 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) } idmap[i + numid] = MAKERELDEP(id); /* fill Id map */ } - if (hashmask > mkmask(pool->nrels + 4096)) - { - pool->relhashtbl = solv_free(pool->relhashtbl); - pool->relhashmask = 0; - } pool_shrink_rels(pool); /* vacuum */ } @@ -863,11 +826,20 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) { id = read_id(&data, i + numid); if (id >= numid) - data.dirpool.dirs[i] = -(id - numid); - else if (idmap) - data.dirpool.dirs[i] = idmap[id]; - else - data.dirpool.dirs[i] = id; + { + data.dirpool.dirs[i++] = -(id - numid); + if (i >= numdir) + { + data.error = pool_error(pool, SOLV_ERROR_CORRUPT, "last dir entry is not a component"); + break; + } + id = read_id(&data, numid); + } + if (idmap) + id = idmap[id]; + data.dirpool.dirs[i] = id; + if (id <= 0) + data.error = pool_error(pool, SOLV_ERROR_CORRUPT, "bad dir component"); } } @@ -913,7 +885,7 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) /* cannot handle mapped ids in vertical */ if (!(flags & REPO_LOCALPOOL) && keys[i].storage == KEY_STORAGE_VERTICAL_OFFSET && (type == REPOKEY_TYPE_ID || type == REPOKEY_TYPE_IDARRAY)) data.error = pool_error(pool, SOLV_ERROR_UNSUPPORTED, "mapped ids are not supported for STORAGE_VERTICAL_OFFSET"); - + if (keys[i].type == REPOKEY_TYPE_CONSTANTID && idmap) keys[i].size = idmap[keys[i].size]; #if 0 @@ -936,7 +908,7 @@ repo_add_solv(Repo *repo, FILE *fp, int flags) } /******* Part 5: Schemata ********************************************/ - + id = read_id(&data, 0); schemadata = solv_calloc(id + 1, sizeof(Id)); schemadatap = schemadata + 1; @@ -1101,13 +1073,13 @@ printf("=> %s %s %p\n", pool_id2str(pool, keys[key].name), pool_id2str(pool, key case REPOKEY_TYPE_ID: dp = data_read_id_max(dp, &did, idmap, numid + numrel, &data); if (s && id == SOLVABLE_NAME) - s->name = did; + s->name = did; else if (s && id == SOLVABLE_ARCH) - s->arch = did; + s->arch = did; else if (s && id == SOLVABLE_EVR) - s->evr = did; + s->evr = did; else if (s && id == SOLVABLE_VENDOR) - s->vendor = did; + s->vendor = did; else if (keys[key].storage == KEY_STORAGE_INCORE) incore_add_id(&data, did); #if 0 @@ -1304,7 +1276,7 @@ printf("=> %s %s %p\n", pool_id2str(pool, keys[key].name), pool_id2str(pool, key { Id fileoffset = 0; unsigned int pagesize; - + /* we have vertical data, make it available */ data.verticaloffset = solv_calloc(numkeys, sizeof(Id)); for (i = 1; i < numkeys; i++)