bool hash_equal(struct mdfour *md1, struct mdfour *md2) { unsigned char sum1[16], sum2[16]; hash_result_as_bytes(md1, sum1); hash_result_as_bytes(md2, sum2); return memcmp(sum1, sum2, sizeof(sum1)) == 0; }
bool hash_equal(struct hash *hash1, struct hash *hash2) { unsigned char sum1[16]; hash_result_as_bytes(hash1, sum1); unsigned char sum2[16]; hash_result_as_bytes(hash2, sum2); return memcmp(sum1, sum2, sizeof(sum1)) == 0; }
char * hash_result(struct hash *hash) { unsigned char sum[16]; hash_result_as_bytes(hash, sum); return format_hash_as_string(sum, hash_input_size(hash)); }
/* Return the hash result as a hex string. Caller frees. */ char * hash_result(struct mdfour *md) { unsigned char sum[16]; hash_result_as_bytes(md, sum); return format_hash_as_string(sum, (unsigned) md->totalN); }
static int verify_object(struct conf *conf, struct manifest *mf, struct object *obj, struct hashtable *stated_files, struct hashtable *hashed_files) { for (uint32_t i = 0; i < obj->n_file_info_indexes; i++) { struct file_info *fi = &mf->file_infos[obj->file_info_indexes[i]]; char *path = mf->files[fi->index]; struct file_stats *st = hashtable_search(stated_files, path); if (!st) { struct stat file_stat; if (x_stat(path, &file_stat) != 0) { return 0; } st = x_malloc(sizeof(*st)); st->size = file_stat.st_size; st->mtime = file_stat.st_mtime; st->ctime = file_stat.st_ctime; hashtable_insert(stated_files, x_strdup(path), st); } if (fi->size != st->size) { return 0; } if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) { if (fi->mtime == st->mtime && fi->ctime == st->ctime) { cc_log("mtime/ctime hit for %s", path); continue; } else { cc_log("mtime/ctime miss for %s", path); } } struct file_hash *actual = hashtable_search(hashed_files, path); if (!actual) { struct mdfour hash; hash_start(&hash); int result = hash_source_code_file(conf, &hash, path); if (result & HASH_SOURCE_CODE_ERROR) { cc_log("Failed hashing %s", path); return 0; } if (result & HASH_SOURCE_CODE_FOUND_TIME) { return 0; } actual = x_malloc(sizeof(*actual)); hash_result_as_bytes(&hash, actual->hash); actual->size = hash.totalN; hashtable_insert(hashed_files, x_strdup(path), actual); } if (memcmp(fi->hash, actual->hash, mf->hash_size) != 0 || fi->size != actual->size) { return 0; } } return 1; }
static int verify_object(struct conf *conf, struct manifest *mf, struct object *obj, struct hashtable *hashed_files) { uint32_t i; struct file_info *fi; struct {int result; struct file_hash fh;} *actual; struct mdfour hash; int result; for (i = 0; i < obj->n_file_info_indexes; i++) { fi = &mf->file_infos[obj->file_info_indexes[i]]; actual = hashtable_search(hashed_files, mf->files[fi->index]); if (!actual) { actual = x_malloc(sizeof(*actual)); hash_start(&hash); result = hash_source_code_file(conf, &hash, mf->files[fi->index]); if (result & HASH_SOURCE_CODE_ERROR) { cc_log("Failed hashing %s", mf->files[fi->index]); cloud_hook_reset_includes(); free(actual); return 0; } if (result & HASH_SOURCE_CODE_FOUND_TIME) { cloud_hook_reset_includes(); free(actual); return 0; } actual->result = result; hash_result_as_bytes(&hash, actual->fh.hash); actual->fh.size = hash.totalN; hashtable_insert(hashed_files, x_strdup(mf->files[fi->index]), actual); } if (memcmp(fi->hash, actual->fh.hash, mf->hash_size) != 0 || fi->size != actual->fh.size) { cloud_hook_reset_includes(); return 0; } /* Passing the hash here is an optimization, but it's not the right hash if a time macro was present. */ cloud_hook_include_file(mf->files[fi->index], actual->result ? NULL : &actual->fh); } return 1; }
static int verify_object(struct conf *conf, struct manifest *mf, struct object *obj, struct hashtable *hashed_files) { uint32_t i; struct file_info *fi; struct file_hash *actual; struct mdfour hash; int result; for (i = 0; i < obj->n_file_info_indexes; i++) { fi = &mf->file_infos[obj->file_info_indexes[i]]; actual = hashtable_search(hashed_files, mf->files[fi->index]); if (!actual) { actual = x_malloc(sizeof(*actual)); hash_start(&hash); result = hash_source_code_file(conf, &hash, mf->files[fi->index]); if (result & HASH_SOURCE_CODE_ERROR) { cc_log("Failed hashing %s", mf->files[fi->index]); free(actual); return 0; } if (result & HASH_SOURCE_CODE_FOUND_TIME) { free(actual); return 0; } hash_result_as_bytes(&hash, actual->hash); actual->size = hash.totalN; hashtable_insert(hashed_files, x_strdup(mf->files[fi->index]), actual); } if (memcmp(fi->hash, actual->hash, mf->hash_size) != 0 || fi->size != actual->size) { return 0; } } return 1; }
static int verify_object(struct conf *conf, struct manifest *mf, struct object *obj, struct hashtable *stated_files, struct hashtable *hashed_files) { for (uint32_t i = 0; i < obj->n_file_info_indexes; i++) { struct file_info *fi = &mf->file_infos[obj->file_info_indexes[i]]; char *path = mf->files[fi->index]; struct file_stats *st = hashtable_search(stated_files, path); if (!st) { struct stat file_stat; if (x_stat(path, &file_stat) != 0) { return 0; } st = x_malloc(sizeof(*st)); st->size = file_stat.st_size; st->mtime = file_stat.st_mtime; st->ctime = file_stat.st_ctime; hashtable_insert(stated_files, x_strdup(path), st); } if (fi->size != st->size) { return 0; } // Clang stores the mtime of the included files in the precompiled header, // and will error out if that header is later used without rebuilding. if ((guessed_compiler == GUESSED_CLANG || guessed_compiler == GUESSED_UNKNOWN) && output_is_precompiled_header && fi->mtime != st->mtime) { cc_log("Precompiled header includes %s, which has a new mtime", path); return 0; } if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) { if (!(conf->sloppiness & SLOPPY_FILE_STAT_MATCHES_CTIME)) { if (fi->mtime == st->mtime && fi->ctime == st->ctime) { cc_log("mtime/ctime hit for %s", path); continue; } else { cc_log("mtime/ctime miss for %s", path); } } else { if (fi->mtime == st->mtime) { cc_log("mtime hit for %s", path); continue; } else { cc_log("mtime miss for %s", path); } } } struct file_hash *actual = hashtable_search(hashed_files, path); if (!actual) { struct hash *hash = hash_init(); int result = hash_source_code_file(conf, hash, path); if (result & HASH_SOURCE_CODE_ERROR) { cc_log("Failed hashing %s", path); hash_free(hash); return 0; } if (result & HASH_SOURCE_CODE_FOUND_TIME) { hash_free(hash); return 0; } actual = x_malloc(sizeof(*actual)); hash_result_as_bytes(hash, actual->hash); actual->size = hash_input_size(hash); hashtable_insert(hashed_files, x_strdup(path), actual); hash_free(hash); } if (memcmp(fi->hash, actual->hash, mf->hash_size) != 0 || fi->size != actual->size) { return 0; } } return 1; }
static int verify_object(struct conf *conf, struct manifest *mf, struct object *obj, struct hashtable *stated_files, struct hashtable *hashed_files) { uint32_t i; struct file_info *fi; struct file_hash *actual; struct file_stats *st; struct mdfour hash; int result; char *path; for (i = 0; i < obj->n_file_info_indexes; i++) { fi = &mf->file_infos[obj->file_info_indexes[i]]; path = mf->files[fi->index]; st = hashtable_search(hashed_files, path); if (!st) { struct stat file_stat; if (stat(path, &file_stat) == -1) { cc_log("Failed to stat include file %s: %s", path, strerror(errno)); return 0; } st = x_malloc(sizeof(*st)); st->size = file_stat.st_size; st->mtime = file_stat.st_mtime; st->ctime = file_stat.st_ctime; hashtable_insert(stated_files, x_strdup(path), st); } if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) { /* * st->ctime is sometimes 0, so we can't check that both st->ctime and * st->mtime are greater than time_of_compilation. But it's sufficient to * check that either is. */ if (fi->size == st->size && fi->mtime == st->mtime && fi->ctime == st->ctime && MAX(st->mtime, st->ctime) >= time_of_compilation) { cc_log("size/mtime/ctime hit for %s", path); continue; } else { cc_log("size/mtime/ctime miss for %s", path); } } actual = hashtable_search(hashed_files, path); if (!actual) { actual = x_malloc(sizeof(*actual)); hash_start(&hash); result = hash_source_code_file(conf, &hash, path); if (result & HASH_SOURCE_CODE_ERROR) { cc_log("Failed hashing %s", path); free(actual); return 0; } if (result & HASH_SOURCE_CODE_FOUND_TIME) { free(actual); return 0; } hash_result_as_bytes(&hash, actual->hash); actual->size = hash.totalN; hashtable_insert(hashed_files, x_strdup(path), actual); } if (memcmp(fi->hash, actual->hash, mf->hash_size) != 0 || fi->size != actual->size) { return 0; } } return 1; }