#include "repopack.h"
#include "repopage.h"
+#ifdef _WIN32
+ #include "strfncs.h"
+#endif
+
#define REPODATA_BLOCK 255
static unsigned char *data_skip_key(Repodata *data, unsigned char *dp, Repokey *key);
cid = schematahash[h];
if (cid)
{
- if (!memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
+ if ((data->schemata[cid] + len <= data->schemadatalen) &&
+ !memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
return cid;
/* cache conflict, do a slow search */
for (cid = 1; cid < data->nschemata; cid++)
- if (!memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
+ if ((data->schemata[cid] + len <= data->schemadatalen) &&
+ !memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
return cid;
}
/* a new one */
comps = stringpool_id2str(data->localpool ? &data->spool : &pool->ss, comp);
l = strlen(comps);
p -= l;
- strncpy(p, comps, l);
+ memcpy(p, comps, l);
parent = dirpool_parent(&data->dirpool, parent);
if (parent)
*--p = '/';
queue_empty(q);
dp = find_key_data(data, solvid, keyname, &key);
- if (!dp || key->type != REPOKEY_TYPE_IDARRAY)
+ if (!dp)
return 0;
- for (;;)
+ switch (key->type)
{
- dp = data_read_ideof(dp, &id, &eof);
+ case REPOKEY_TYPE_CONSTANTID:
+ queue_push(q, key->size);
+ break;
+ case REPOKEY_TYPE_ID:
+ dp = data_read_id(dp, &id);
queue_push(q, id);
- if (eof)
- break;
+ break;
+ case REPOKEY_TYPE_IDARRAY:
+ for (;;)
+ {
+ dp = data_read_ideof(dp, &id, &eof);
+ queue_push(q, id);
+ if (eof)
+ break;
+ }
+ break;
+ default:
+ return 0;
}
return 1;
}
return dp;
}
+unsigned int
+repodata_lookup_count(Repodata *data, Id solvid, Id keyname)
+{
+ unsigned char *dp;
+ Repokey *key;
+ unsigned int cnt = 0;
+
+ dp = find_key_data(data, solvid, keyname, &key);
+ if (!dp)
+ return 0;
+ switch (key->type)
+ {
+ case REPOKEY_TYPE_IDARRAY:
+ case REPOKEY_TYPE_REL_IDARRAY:
+ for (cnt = 1; (*dp & 0xc0) != 0; dp++)
+ if ((*dp & 0xc0) == 0x40)
+ cnt++;
+ return cnt;
+ case REPOKEY_TYPE_FIXARRAY:
+ case REPOKEY_TYPE_FLEXARRAY:
+ data_read_id(dp, (int *)&cnt);
+ return cnt;
+ case REPOKEY_TYPE_DIRSTRARRAY:
+ for (;;)
+ {
+ cnt++;
+ while (*dp & 0x80)
+ dp++;
+ if (!(*dp++ & 0x40))
+ return cnt;
+ dp += strlen((const char *)dp) + 1;
+ }
+ case REPOKEY_TYPE_DIRNUMNUMARRAY:
+ for (;;)
+ {
+ cnt++;
+ while (*dp++ & 0x80)
+ ;
+ while (*dp++ & 0x80)
+ ;
+ while (*dp & 0x80)
+ dp++;
+ if (!(*dp++ & 0x40))
+ return cnt;
+ }
+ default:
+ break;
+ }
+ return 1;
+}
+
/* highly specialized function to speed up fileprovides adding.
* - repodata must be available
* - solvid must be >= data->start and < data->end
if (!dp || kv->entry != -1)
return 0;
- while (++kv->entry < kv->num)
+ while (++kv->entry < (int)kv->num)
{
if (kv->entry)
dp = data_skip_schema(data, dp, schema);
tmpattrs = data->attrs[dest - data->start];
data->attrs[dest - data->start] = data->attrs[src - data->start];
data->attrs[src - data->start] = tmpattrs;
+ if (data->lasthandle == src || data->lasthandle == dest)
+ data->lasthandle = 0;
}
break;
case REPOKEY_TYPE_DIRSTRARRAY:
for (v = attrs[1]; data->attriddata[v] ; v += 2)
- if (data->attriddata[v + 1] < attrdatastart)
+ if ((unsigned int)data->attriddata[v + 1] < attrdatastart)
attrdatastart = data->attriddata[v + 1];
/* FALLTHROUGH */
case REPOKEY_TYPE_IDARRAY: