Validate the integrity of the data structure. * when `deep` is 0, only the integrity of the header is validated. * when `deep` is 1, we make sure there are no duplicate or out of order records. */
| 289 | * when `deep` is 0, only the integrity of the header is validated. |
| 290 | * when `deep` is 1, we make sure there are no duplicate or out of order records. */ |
| 291 | int intsetValidateIntegrity(const unsigned char *p, size_t size, int deep) { |
| 292 | intset *is = (intset *)p; |
| 293 | /* check that we can actually read the header. */ |
| 294 | if (size < sizeof(*is)) |
| 295 | return 0; |
| 296 | |
| 297 | uint32_t encoding = intrev32ifbe(is->encoding); |
| 298 | |
| 299 | size_t record_size; |
| 300 | if (encoding == INTSET_ENC_INT64) { |
| 301 | record_size = INTSET_ENC_INT64; |
| 302 | } else if (encoding == INTSET_ENC_INT32) { |
| 303 | record_size = INTSET_ENC_INT32; |
| 304 | } else if (encoding == INTSET_ENC_INT16){ |
| 305 | record_size = INTSET_ENC_INT16; |
| 306 | } else { |
| 307 | return 0; |
| 308 | } |
| 309 | |
| 310 | /* check that the size matchies (all records are inside the buffer). */ |
| 311 | uint32_t count = intrev32ifbe(is->length); |
| 312 | if (sizeof(*is) + count*record_size != size) |
| 313 | return 0; |
| 314 | |
| 315 | /* check that the set is not empty. */ |
| 316 | if (count==0) |
| 317 | return 0; |
| 318 | |
| 319 | if (!deep) |
| 320 | return 1; |
| 321 | |
| 322 | /* check that there are no dup or out of order records. */ |
| 323 | int64_t prev = _intsetGet(is,0); |
| 324 | for (uint32_t i=1; i<count; i++) { |
| 325 | int64_t cur = _intsetGet(is,i); |
| 326 | if (cur <= prev) |
| 327 | return 0; |
| 328 | prev = cur; |
| 329 | } |
| 330 | |
| 331 | return 1; |
| 332 | } |
| 333 | |
| 334 | #ifdef REDIS_TEST |
| 335 | #include <sys/time.h> |
no test coverage detected