static int commit_quick_parse(git_revwalk *walk, commit_object *commit, git_rawobj *raw) { const int parent_len = STRLEN("parent ") + GIT_OID_HEXSZ + 1; unsigned char *buffer = raw->data; unsigned char *buffer_end = buffer + raw->len; unsigned char *parents_start; int i, parents = 0; buffer += STRLEN("tree ") + GIT_OID_HEXSZ + 1; parents_start = buffer; while (buffer + parent_len < buffer_end && memcmp(buffer, "parent ", STRLEN("parent ")) == 0) { parents++; buffer += parent_len; } commit->parents = alloc_parents(commit, parents); if (commit->parents == NULL) return GIT_ENOMEM; buffer = parents_start; for (i = 0; i < parents; ++i) { git_oid oid; if (git_oid_mkstr(&oid, (char *)buffer + STRLEN("parent ")) < GIT_SUCCESS) return GIT_EOBJCORRUPTED; commit->parents[i] = commit_lookup(walk, &oid); if (commit->parents[i] == NULL) return GIT_ENOMEM; buffer += parent_len; } commit->out_degree = (unsigned short)parents; if ((buffer = memchr(buffer, '\n', buffer_end - buffer)) == NULL) return GIT_EOBJCORRUPTED; buffer = memchr(buffer, '>', buffer_end - buffer); if (buffer == NULL) return GIT_EOBJCORRUPTED; commit->time = strtol((char *)buffer + 2, NULL, 10); if (commit->time == 0) return GIT_EOBJCORRUPTED; commit->parsed = 1; return GIT_SUCCESS; }
static int commit_quick_parse(git_revwalk *walk, git_commit_list_node *commit, git_rawobj *raw) { const size_t parent_len = strlen("parent ") + GIT_OID_HEXSZ + 1; unsigned char *buffer = raw->data; unsigned char *buffer_end = buffer + raw->len; unsigned char *parents_start, *committer_start; int i, parents = 0; int commit_time; buffer += strlen("tree ") + GIT_OID_HEXSZ + 1; parents_start = buffer; while (buffer + parent_len < buffer_end && memcmp(buffer, "parent ", strlen("parent ")) == 0) { parents++; buffer += parent_len; } commit->parents = alloc_parents(walk, commit, parents); GITERR_CHECK_ALLOC(commit->parents); buffer = parents_start; for (i = 0; i < parents; ++i) { git_oid oid; if (git_oid_fromstr(&oid, (char *)buffer + strlen("parent ")) < 0) return -1; commit->parents[i] = git_revwalk__commit_lookup(walk, &oid); if (commit->parents[i] == NULL) return -1; buffer += parent_len; } commit->out_degree = (unsigned short)parents; if ((committer_start = buffer = memchr(buffer, '\n', buffer_end - buffer)) == NULL) return commit_error(commit, "object is corrupted"); buffer++; if ((buffer = memchr(buffer, '\n', buffer_end - buffer)) == NULL) return commit_error(commit, "object is corrupted"); /* Skip trailing spaces */ while (buffer > committer_start && git__isspace(*buffer)) buffer--; /* Seek for the begining of the pack of digits */ while (buffer > committer_start && git__isdigit(*buffer)) buffer--; /* Skip potential timezone offset */ if ((buffer > committer_start) && (*buffer == '+' || *buffer == '-')) { buffer--; while (buffer > committer_start && git__isspace(*buffer)) buffer--; while (buffer > committer_start && git__isdigit(*buffer)) buffer--; } if ((buffer == committer_start) || (git__strtol32(&commit_time, (char *)(buffer + 1), NULL, 10) < 0)) return commit_error(commit, "cannot parse commit time"); commit->time = (time_t)commit_time; commit->parsed = 1; return 0; }