]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
manifest file_info fix
authorYiding Jia <yiding@fb.com>
Mon, 14 Apr 2014 21:46:46 +0000 (14:46 -0700)
committerJoel Rosdahl <joel@rosdahl.net>
Tue, 15 Apr 2014 20:27:29 +0000 (22:27 +0200)
manifest.c

index 7f02ede0c574d865801b2267e7f6cab9c1be1e81..4a456f50317f3be6b203796b4bea9a6bad7ab027 100644 (file)
@@ -65,6 +65,7 @@
 static const uint32_t MAGIC = 0x63436d46U;
 static const uint8_t  VERSION = 0;
 static const uint32_t MAX_MANIFEST_ENTRIES = 100;
+static const uint32_t MAX_MANIFEST_FILE_INFO_ENTRIES = 10000;
 
 #define ccache_static_assert(e) \
        do { enum { ccache_static_assert__ = 1/(e) }; } while (0)
@@ -124,7 +125,7 @@ file_infos_equal(void *key1, void *key2)
 static void
 free_manifest(struct manifest *mf)
 {
-       uint16_t i;
+       uint32_t i;
        for (i = 0; i < mf->n_files; i++) {
                free(mf->files[i]);
        }
@@ -207,7 +208,7 @@ static struct manifest *
 read_manifest(gzFile f)
 {
        struct manifest *mf;
-       uint16_t i, j;
+       uint32_t i, j;
        uint32_t magic;
        uint8_t version;
        uint16_t dummy;
@@ -305,7 +306,7 @@ error:
 static int
 write_manifest(gzFile f, const struct manifest *mf)
 {
-       uint16_t i, j;
+       uint32_t i, j;
 
        WRITE_INT(4, MAGIC);
        WRITE_INT(1, VERSION);
@@ -630,6 +631,15 @@ manifest_put(const char *manifest_path, struct file_hash *object_hash,
                       MAX_MANIFEST_ENTRIES);
                free_manifest(mf);
                mf = create_empty_manifest();
+       } else if (mf->n_file_infos > MAX_MANIFEST_FILE_INFO_ENTRIES) {
+               /* Rarely, file_info entries can grow large in pathological cases where
+                * many included files change, but the main file does not. This also puts
+                * an upper bound on the number of file_info entries.
+                */
+               cc_log("More than %u file_info entries in manifest file; discarding",
+                      MAX_MANIFEST_FILE_INFO_ENTRIES);
+               free_manifest(mf);
+               mf = create_empty_manifest();
        }
 
        tmp_file = format("%s.tmp.%s", manifest_path, tmp_string());