Validate the integrity of a single listpack entry and move to the next one. * The input argument 'pp' is a reference to the current record and is advanced on exit. * Returns 1 if valid, 0 if invalid. */
| 875 | * The input argument 'pp' is a reference to the current record and is advanced on exit. |
| 876 | * Returns 1 if valid, 0 if invalid. */ |
| 877 | int lpValidateNext(unsigned char *lp, unsigned char **pp, size_t lpbytes) { |
| 878 | #define OUT_OF_RANGE(p) ( \ |
| 879 | (p) < lp + LP_HDR_SIZE || \ |
| 880 | (p) > lp + lpbytes - 1) |
| 881 | unsigned char *p = *pp; |
| 882 | if (!p) |
| 883 | return 0; |
| 884 | |
| 885 | /* Before accessing p, make sure it's valid. */ |
| 886 | if (OUT_OF_RANGE(p)) |
| 887 | return 0; |
| 888 | |
| 889 | if (*p == LP_EOF) { |
| 890 | *pp = NULL; |
| 891 | return 1; |
| 892 | } |
| 893 | |
| 894 | /* check that we can read the encoded size */ |
| 895 | uint32_t lenbytes = lpCurrentEncodedSizeBytes(p); |
| 896 | if (!lenbytes) |
| 897 | return 0; |
| 898 | |
| 899 | /* make sure the encoded entry length doesn't rech outside the edge of the listpack */ |
| 900 | if (OUT_OF_RANGE(p + lenbytes)) |
| 901 | return 0; |
| 902 | |
| 903 | /* get the entry length and encoded backlen. */ |
| 904 | unsigned long entrylen = lpCurrentEncodedSizeUnsafe(p); |
| 905 | unsigned long encodedBacklen = lpEncodeBacklen(NULL,entrylen); |
| 906 | entrylen += encodedBacklen; |
| 907 | |
| 908 | /* make sure the entry doesn't rech outside the edge of the listpack */ |
| 909 | if (OUT_OF_RANGE(p + entrylen)) |
| 910 | return 0; |
| 911 | |
| 912 | /* move to the next entry */ |
| 913 | p += entrylen; |
| 914 | |
| 915 | /* make sure the encoded length at the end patches the one at the beginning. */ |
| 916 | uint64_t prevlen = lpDecodeBacklen(p-1); |
| 917 | if (prevlen + encodedBacklen != entrylen) |
| 918 | return 0; |
| 919 | |
| 920 | *pp = p; |
| 921 | return 1; |
| 922 | #undef OUT_OF_RANGE |
| 923 | } |
| 924 | |
| 925 | /* Validate that the entry doesn't reach outside the listpack allocation. */ |
| 926 | static inline void lpAssertValidEntry(unsigned char* lp, size_t lpbytes, unsigned char *p) { |
no test coverage detected