| 581 | } |
| 582 | |
| 583 | static struct cache_tree *read_one(const char **buffer, unsigned long *size_p) |
| 584 | { |
| 585 | const char *buf = *buffer; |
| 586 | unsigned long size = *size_p; |
| 587 | struct cache_tree *it; |
| 588 | int i, subtree_nr; |
| 589 | const unsigned rawsz = the_hash_algo->rawsz; |
| 590 | |
| 591 | it = NULL; |
| 592 | /* skip name, but make sure name exists */ |
| 593 | while (size && *buf) { |
| 594 | size--; |
| 595 | buf++; |
| 596 | } |
| 597 | if (!size) |
| 598 | goto free_return; |
| 599 | buf++; size--; |
| 600 | it = cache_tree(); |
| 601 | |
| 602 | if (parse_int(&buf, &size, &it->entry_count) < 0) |
| 603 | goto free_return; |
| 604 | if (!size || *buf != ' ') |
| 605 | goto free_return; |
| 606 | buf++; size--; |
| 607 | if (parse_int(&buf, &size, &subtree_nr) < 0) |
| 608 | goto free_return; |
| 609 | if (!size || *buf != '\n') |
| 610 | goto free_return; |
| 611 | buf++; size--; |
| 612 | if (0 <= it->entry_count) { |
| 613 | if (size < rawsz) |
| 614 | goto free_return; |
| 615 | oidread(&it->oid, (const unsigned char *)buf, |
| 616 | the_repository->hash_algo); |
| 617 | buf += rawsz; |
| 618 | size -= rawsz; |
| 619 | } |
| 620 | |
| 621 | #if DEBUG_CACHE_TREE |
| 622 | if (0 <= it->entry_count) |
| 623 | fprintf(stderr, "cache-tree <%s> (%d ent, %d subtree) %s\n", |
| 624 | *buffer, it->entry_count, subtree_nr, |
| 625 | oid_to_hex(&it->oid)); |
| 626 | else |
| 627 | fprintf(stderr, "cache-tree <%s> (%d subtrees) invalid\n", |
| 628 | *buffer, subtree_nr); |
| 629 | #endif |
| 630 | |
| 631 | /* |
| 632 | * Just a heuristic -- we do not add directories that often but |
| 633 | * we do not want to have to extend it immediately when we do, |
| 634 | * hence +2. |
| 635 | */ |
| 636 | it->subtree_alloc = subtree_nr + 2; |
| 637 | CALLOC_ARRAY(it->down, it->subtree_alloc); |
| 638 | for (i = 0; i < subtree_nr; i++) { |
| 639 | /* read each subtree */ |
| 640 | struct cache_tree *sub; |
no test coverage detected