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)
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]);
}
read_manifest(gzFile f)
{
struct manifest *mf;
- uint16_t i, j;
+ uint32_t i, j;
uint32_t magic;
uint8_t version;
uint16_t dummy;
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);
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());