MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / zipmapValidateIntegrity

Function zipmapValidateIntegrity

src/zipmap.c:380–442  ·  view source on GitHub ↗

Validate the integrity of the data structure. * when `deep` is 0, only the integrity of the header is validated. * when `deep` is 1, we scan all the entries one by one. */

Source from the content-addressed store, hash-verified

378 * when `deep` is 0, only the integrity of the header is validated.
379 * when `deep` is 1, we scan all the entries one by one. */
380int zipmapValidateIntegrity(unsigned char *zm, size_t size, int deep) {
381#define OUT_OF_RANGE(p) ( \
382 (p) < zm + 2 || \
383 (p) > zm + size - 1)
384 unsigned int l, s, e;
385
386 /* check that we can actually read the header (or ZIPMAP_END). */
387 if (size < 2)
388 return 0;
389
390 /* the last byte must be the terminator. */
391 if (zm[size-1] != ZIPMAP_END)
392 return 0;
393
394 if (!deep)
395 return 1;
396
397 unsigned int count = 0;
398 unsigned char *p = zm + 1; /* skip the count */
399 while(*p != ZIPMAP_END) {
400 /* read the field name length encoding type */
401 s = zipmapGetEncodedLengthSize(p);
402 /* make sure the entry length doesn't rech outside the edge of the zipmap */
403 if (OUT_OF_RANGE(p+s))
404 return 0;
405
406 /* read the field name length */
407 l = zipmapDecodeLength(p);
408 p += s; /* skip the encoded field size */
409 p += l; /* skip the field */
410
411 /* make sure the entry doesn't rech outside the edge of the zipmap */
412 if (OUT_OF_RANGE(p))
413 return 0;
414
415 /* read the value length encoding type */
416 s = zipmapGetEncodedLengthSize(p);
417 /* make sure the entry length doesn't rech outside the edge of the zipmap */
418 if (OUT_OF_RANGE(p+s))
419 return 0;
420
421 /* read the value length */
422 l = zipmapDecodeLength(p);
423 p += s; /* skip the encoded value size*/
424 e = *p++; /* skip the encoded free space (always encoded in one byte) */
425 p += l+e; /* skip the value and free space */
426 count++;
427
428 /* make sure the entry doesn't rech outside the edge of the zipmap */
429 if (OUT_OF_RANGE(p))
430 return 0;
431 }
432
433 /* check that the zipmap is not empty. */
434 if (count == 0) return 0;
435
436 /* check that the count in the header is correct */
437 if (zm[0] != ZIPMAP_BIGLEN && zm[0] != count)

Callers 1

rdbLoadObjectFunction · 0.85

Calls 2

zipmapDecodeLengthFunction · 0.85

Tested by

no test coverage detected