static VALUE rb_git_raw_to_hex(VALUE self, VALUE raw) { git_oid oid; char out[40]; Check_Type(raw, T_STRING); git_oid_mkraw(&oid, RSTRING_PTR(raw)); git_oid_fmt(out, &oid); return rugged_str_new(out, 40, NULL); }
static int tree_parse_buffer(git_tree *tree, char *buffer, char *buffer_end) { static const size_t avg_entry_size = 40; unsigned int expected_size; int error = GIT_SUCCESS; expected_size = (tree->object.source.raw.len / avg_entry_size) + 1; clear_entries(tree); while (buffer < buffer_end) { git_tree_entry *entry; entry = git__malloc(sizeof(git_tree_entry)); if (entry == NULL) { error = GIT_ENOMEM; break; } if (git_vector_insert(&tree->entries, entry) < GIT_SUCCESS) return GIT_ENOMEM; entry->owner = tree; entry->attr = strtol(buffer, &buffer, 8); if (*buffer++ != ' ') { error = GIT_EOBJCORRUPTED; break; } if (memchr(buffer, 0, buffer_end - buffer) == NULL) { error = GIT_EOBJCORRUPTED; break; } entry->filename = git__strdup(buffer); while (buffer < buffer_end && *buffer != 0) buffer++; buffer++; git_oid_mkraw(&entry->oid, (const unsigned char *)buffer); buffer += GIT_OID_RAWSZ; } return error; }
static int tree_parse_buffer(git_tree *tree, const char *buffer, const char *buffer_end) { int error = GIT_SUCCESS; if (git_vector_init(&tree->entries, DEFAULT_TREE_SIZE, entry_sort_cmp) < GIT_SUCCESS) return GIT_ENOMEM; while (buffer < buffer_end) { git_tree_entry *entry; entry = git__calloc(1, sizeof(git_tree_entry)); if (entry == NULL) { error = GIT_ENOMEM; break; } if (git_vector_insert(&tree->entries, entry) < GIT_SUCCESS) return GIT_ENOMEM; if (git__strtol32((long *)&entry->attr, buffer, &buffer, 8) < GIT_SUCCESS) return GIT_EOBJCORRUPTED; if (*buffer++ != ' ') { error = GIT_EOBJCORRUPTED; break; } if (memchr(buffer, 0, buffer_end - buffer) == NULL) { error = GIT_EOBJCORRUPTED; break; } entry->filename = git__strdup(buffer); entry->filename_len = strlen(buffer); while (buffer < buffer_end && *buffer != 0) buffer++; buffer++; git_oid_mkraw(&entry->oid, (const unsigned char *)buffer); buffer += GIT_OID_RAWSZ; } return error; }
static int check_pack_sha1(git_pack *p) { unsigned char *data = p->idx_map.data; off_t pack_sha1_off = p->pack_size - GIT_OID_RAWSZ; size_t idx_pack_sha1_off = p->idx_map.len - 2 * GIT_OID_RAWSZ; git_oid pack_id, idx_pack_id; if (gitfo_lseek(p->pack_fd, pack_sha1_off, SEEK_SET) == -1) return GIT_ERROR; if (gitfo_read(p->pack_fd, pack_id.id, sizeof(pack_id.id))) return GIT_ERROR; git_oid_mkraw(&idx_pack_id, data + idx_pack_sha1_off); if (git_oid_cmp(&pack_id, &idx_pack_id)) return GIT_ERROR; return GIT_SUCCESS; }
int git_index__parse(git_index *index, const char *buffer, size_t buffer_size) { unsigned int i; struct index_header header; git_oid checksum_calculated, checksum_expected; #define seek_forward(_increase) { \ if (_increase >= buffer_size) \ return GIT_EOBJCORRUPTED; \ buffer += _increase; \ buffer_size -= _increase;\ } if (buffer_size < INDEX_HEADER_SIZE + INDEX_FOOTER_SIZE) return GIT_EOBJCORRUPTED; /* Precalculate the SHA1 of the files's contents -- we'll match it to * the provided SHA1 in the footer */ git_hash_buf(&checksum_calculated, (const void *)buffer, buffer_size - INDEX_FOOTER_SIZE); /* Parse header */ if (read_header(&header, buffer) < 0) return GIT_EOBJCORRUPTED; seek_forward(INDEX_HEADER_SIZE); index->entry_count = header.entry_count; /* If there is already a entires array, reuse it if it can hold all the * entries. If not, free and reallocate */ if (index->entry_count > index->entries_size) { free(index->entries); index->entries_size = (uint32_t)(index->entry_count * 1.3f); index->entries = git__malloc(index->entries_size * sizeof(git_index_entry)); } /* Parse all the entries */ for (i = 0; i < index->entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) { size_t entry_size; entry_size = read_entry(&index->entries[i], buffer, buffer_size); /* 0 bytes read means an object corruption */ if (entry_size == 0) return GIT_EOBJCORRUPTED; seek_forward(entry_size); } if (i != index->entry_count) return GIT_EOBJCORRUPTED; /* There's still space for some extensions! */ while (buffer_size > INDEX_FOOTER_SIZE) { size_t extension_size; extension_size = read_extension(index, buffer, buffer_size); /* see if we have read any bytes from the extension */ if (extension_size == 0) return GIT_EOBJCORRUPTED; seek_forward(extension_size); } if (buffer_size != INDEX_FOOTER_SIZE) return GIT_EOBJCORRUPTED; /* 160-bit SHA-1 over the content of the index file before this checksum. */ git_oid_mkraw(&checksum_expected, (const unsigned char *)buffer); if (git_oid_cmp(&checksum_calculated, &checksum_expected) != 0) return GIT_EOBJCORRUPTED; #undef seek_forward return 0; }
static git_index_tree *read_tree_internal( const char **buffer_in, const char *buffer_end, git_index_tree *parent) { git_index_tree *tree; const char *name_start, *buffer; if ((tree = git__malloc(sizeof(git_index_tree))) == NULL) return NULL; memset(tree, 0x0, sizeof(git_index_tree)); tree->parent = parent; buffer = name_start = *buffer_in; if ((buffer = memchr(buffer, '\0', buffer_end - buffer)) == NULL) goto error_cleanup; /* NUL-terminated tree name */ tree->name = git__strdup(name_start); if (++buffer >= buffer_end) goto error_cleanup; /* Blank-terminated ASCII decimal number of entries in this tree */ tree->entries = strtol(buffer, (char **)&buffer, 10); if (*buffer != ' ' || ++buffer >= buffer_end) goto error_cleanup; /* Number of children of the tree, newline-terminated */ tree->children_count = strtol(buffer, (char **)&buffer, 10); if (*buffer != '\n' || ++buffer >= buffer_end) goto error_cleanup; /* 160-bit SHA-1 for this tree and it's children */ if (buffer + GIT_OID_RAWSZ > buffer_end) goto error_cleanup; git_oid_mkraw(&tree->oid, (const unsigned char *)buffer); buffer += GIT_OID_RAWSZ; /* Parse children: */ if (tree->children_count > 0) { unsigned int i; tree->children = git__malloc(tree->children_count * sizeof(git_index_tree *)); if (tree->children == NULL) goto error_cleanup; for (i = 0; i < tree->children_count; ++i) { tree->children[i] = read_tree_internal(&buffer, buffer_end, tree); if (tree->children[i] == NULL) goto error_cleanup; } } *buffer_in = buffer; return tree; error_cleanup: git_index_tree__free(tree); return NULL; }