]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Handle unknown manifest version gracefully in --dump-manifest
authorJoel Rosdahl <joel@rosdahl.net>
Sun, 5 May 2019 19:54:27 +0000 (21:54 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Sun, 5 May 2019 20:16:15 +0000 (22:16 +0200)
Previously “ccache --dump-manifest file” would crash with an assert when
the file did not have the expected version.

src/ccache.c
src/manifest.c

index fcd7f8f0f775c5a82f4bf6ab7866b631a47cc0bf..becadff5b77e6a9db719e40ea18d6179c0f54271 100644 (file)
@@ -4045,6 +4045,7 @@ ccache_main_options(int argc, char *argv[])
               != -1) {
                switch (c) {
                case DUMP_MANIFEST:
+                       initialize();
                        manifest_dump(optarg, stdout);
                        break;
 
index b783353b58dad7e3414d1aee1e5f5459872d9ff4..7b272b9c704bafabf0b9ec84940bc398ee11d93a 100644 (file)
@@ -229,27 +229,32 @@ create_empty_manifest(void)
 }
 
 static struct manifest *
-read_manifest(gzFile f)
+read_manifest(gzFile f, char **errmsg)
 {
+       *errmsg = NULL;
        struct manifest *mf = create_empty_manifest();
 
        uint32_t magic;
        READ_INT(4, magic);
        if (magic != MAGIC) {
-               cc_log("Manifest file has bad magic number %u", magic);
+               *errmsg = format("Manifest file has bad magic number %u", magic);
                goto error;
        }
 
        READ_BYTE(mf->version);
        if (mf->version != MANIFEST_VERSION) {
-               cc_log("Manifest file has unknown version %u", mf->version);
+               *errmsg = format(
+                       "Unknown manifest version (actual %u, expected %u)",
+                       mf->version,
+                       MANIFEST_VERSION);
                goto error;
        }
 
        READ_BYTE(mf->hash_size);
        if (mf->hash_size != 16) {
                // Temporary measure until we support different hash algorithms.
-               cc_log("Manifest file has unsupported hash size %u", mf->hash_size);
+               *errmsg =
+                       format("Manifest file has unsupported hash size %u", mf->hash_size);
                goto error;
        }
 
@@ -289,7 +294,9 @@ read_manifest(gzFile f)
        return mf;
 
 error:
-       cc_log("Corrupt manifest file");
+       if (!errmsg) {
+               *errmsg = x_strdup("Corrupt manifest file");
+       }
        free_manifest(mf);
        return NULL;
 }
@@ -512,8 +519,7 @@ get_file_hash_index(struct manifest *mf,
                if (time_of_compilation > MAX(file_stat.st_mtime, file_stat.st_ctime)) {
                        fi.mtime = file_stat.st_mtime;
                        fi.ctime = file_stat.st_ctime;
-               }
-               else {
+               } else {
                        fi.mtime = -1;
                        fi.ctime = -1;
                }
@@ -606,9 +612,11 @@ manifest_get(struct conf *conf, const char *manifest_path)
                cc_log("Failed to gzdopen manifest file");
                goto out;
        }
-       mf = read_manifest(f);
+
+       char *errmsg;
+       mf = read_manifest(f, &errmsg);
        if (!mf) {
-               cc_log("Error reading manifest file");
+               cc_log("%s", errmsg);
                goto out;
        }
 
@@ -667,9 +675,12 @@ manifest_put(const char *manifest_path, struct file_hash *object_hash,
                        close(fd1);
                        goto out;
                }
-               mf = read_manifest(f1);
+               char *errmsg;
+               mf = read_manifest(f1, &errmsg);
                gzclose(f1);
                if (!mf) {
+                       cc_log("%s", errmsg);
+                       free(errmsg);
                        cc_log("Failed to read manifest file; deleting it");
                        x_unlink(manifest_path);
                        mf = create_empty_manifest();
@@ -755,9 +766,11 @@ manifest_dump(const char *manifest_path, FILE *stream)
                close(fd);
                goto out;
        }
-       mf = read_manifest(f);
+       char *errmsg;
+       mf = read_manifest(f, &errmsg);
        if (!mf) {
-               fprintf(stderr, "Error reading manifest file\n");
+               fprintf(stderr, "%s\n", errmsg);
+               free(errmsg);
                goto out;
        }
 
@@ -782,7 +795,7 @@ manifest_dump(const char *manifest_path, FILE *stream)
                fprintf(stream, "    Hash: %s\n", hash);
                free(hash);
                fprintf(stream, "    Hashed bytes: %u\n", mf->file_infos[i].hsize);
-               fprintf(stream, "    File size: %"PRIu64"\n", mf->file_infos[i].fsize);
+               fprintf(stream, "    File size: %" PRIu64 "\n", mf->file_infos[i].fsize);
                fprintf(stream, "    Mtime: %lld\n", (long long)mf->file_infos[i].mtime);
                fprintf(stream, "    Ctime: %lld\n", (long long)mf->file_infos[i].ctime);
        }