Validate the integrity stream listpack entries structure. Both in term of a * valid listpack, but also that the structure of the entires matches a valid * stream. return 1 if valid 0 if not valid. */
| 3586 | * valid listpack, but also that the structure of the entires matches a valid |
| 3587 | * stream. return 1 if valid 0 if not valid. */ |
| 3588 | int streamValidateListpackIntegrity(unsigned char *lp, size_t size, int deep) { |
| 3589 | int valid_record; |
| 3590 | unsigned char *p, *next; |
| 3591 | |
| 3592 | /* Since we don't want to run validation of all records twice, we'll |
| 3593 | * run the listpack validation of just the header and do the rest here. */ |
| 3594 | if (!lpValidateIntegrity(lp, size, 0)) |
| 3595 | return 0; |
| 3596 | |
| 3597 | /* In non-deep mode we just validated the listpack header (encoded size) */ |
| 3598 | if (!deep) return 1; |
| 3599 | |
| 3600 | next = p = lpValidateFirst(lp); |
| 3601 | if (!lpValidateNext(lp, &next, size)) return 0; |
| 3602 | if (!p) return 0; |
| 3603 | |
| 3604 | /* entry count */ |
| 3605 | int64_t entry_count = lpGetIntegerIfValid(p, &valid_record); |
| 3606 | if (!valid_record) return 0; |
| 3607 | p = next; if (!lpValidateNext(lp, &next, size)) return 0; |
| 3608 | |
| 3609 | /* deleted */ |
| 3610 | int64_t deleted_count = lpGetIntegerIfValid(p, &valid_record); |
| 3611 | if (!valid_record) return 0; |
| 3612 | p = next; if (!lpValidateNext(lp, &next, size)) return 0; |
| 3613 | |
| 3614 | /* num-of-fields */ |
| 3615 | int64_t master_fields = lpGetIntegerIfValid(p, &valid_record); |
| 3616 | if (!valid_record) return 0; |
| 3617 | p = next; if (!lpValidateNext(lp, &next, size)) return 0; |
| 3618 | |
| 3619 | /* the field names */ |
| 3620 | for (int64_t j = 0; j < master_fields; j++) { |
| 3621 | p = next; if (!lpValidateNext(lp, &next, size)) return 0; |
| 3622 | } |
| 3623 | |
| 3624 | /* the zero master entry terminator. */ |
| 3625 | int64_t zero = lpGetIntegerIfValid(p, &valid_record); |
| 3626 | if (!valid_record || zero != 0) return 0; |
| 3627 | p = next; if (!lpValidateNext(lp, &next, size)) return 0; |
| 3628 | |
| 3629 | entry_count += deleted_count; |
| 3630 | while (entry_count--) { |
| 3631 | if (!p) return 0; |
| 3632 | int64_t fields = master_fields, extra_fields = 3; |
| 3633 | int64_t flags = lpGetIntegerIfValid(p, &valid_record); |
| 3634 | if (!valid_record) return 0; |
| 3635 | p = next; if (!lpValidateNext(lp, &next, size)) return 0; |
| 3636 | |
| 3637 | /* entry id */ |
| 3638 | lpGetIntegerIfValid(p, &valid_record); |
| 3639 | if (!valid_record) return 0; |
| 3640 | p = next; if (!lpValidateNext(lp, &next, size)) return 0; |
| 3641 | lpGetIntegerIfValid(p, &valid_record); |
| 3642 | if (!valid_record) return 0; |
| 3643 | p = next; if (!lpValidateNext(lp, &next, size)) return 0; |
| 3644 | |
| 3645 | if (!(flags & STREAM_ITEM_FLAG_SAMEFIELDS)) { |
no test coverage detected