Bug 1132468 - Reject invalid sizes. r=jrmuizel
authorBenoit Girard <b56girard@gmail.com>
Tue, 24 Feb 2015 17:02:10 -0500
changeset 230994 f1170bf063bd31cdffab3fa443cdf1387befd22a
parent 230993 175cd1cf7674f0943ca19674a5eb9c72e4515b3c
child 230995 7cea68e38d3f737364164a82e9a64b7b15917209
push id28341
push userkwierso@gmail.com
push dateFri, 27 Feb 2015 02:25:40 +0000
treeherdermozilla-central@93707c1b4edb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1132468
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1132468 - Reject invalid sizes. r=jrmuizel
gfx/qcms/iccread.c
--- a/gfx/qcms/iccread.c
+++ b/gfx/qcms/iccread.c
@@ -549,17 +549,17 @@ static struct lutmABType *read_tag_lutmA
 	num_in_channels = read_u8(src, offset + 8);
 	num_out_channels = read_u8(src, offset + 9);
 	if (num_in_channels > MAX_CHANNELS || num_out_channels > MAX_CHANNELS)
 		return NULL;
 
 	// We require 3in/out channels since we only support RGB->XYZ (or RGB->LAB)
 	// XXX: If we remove this restriction make sure that the number of channels
 	//      is less or equal to the maximum number of mAB curves in qcmsint.h
-	//      also check for clut_size overflow.
+	//      also check for clut_size overflow. Also make sure it's != 0
 	if (num_in_channels != 3 || num_out_channels != 3)
 		return NULL;
 
 	// some of this data is optional and is denoted by a zero offset
 	// we also use this to track their existance
 	a_curve_offset = read_u32(src, offset + 28);
 	clut_offset = read_u32(src, offset + 24);
 	m_curve_offset = read_u32(src, offset + 20);
@@ -579,16 +579,19 @@ static struct lutmABType *read_tag_lutmA
 	if (b_curve_offset)
 		b_curve_offset += offset;
 
 	if (clut_offset) {
 		assert (num_in_channels == 3);
 		// clut_size can not overflow since lg(256^num_in_channels) = 24 bits.
 		for (i = 0; i < num_in_channels; i++) {
 			clut_size *= read_u8(src, clut_offset + i);
+			if (clut_size == 0) {
+				invalid_source(src, "bad clut_size");
+			}
 		}
 	} else {
 		clut_size = 0;
 	}
 
 	// 24bits * 3 won't overflow either
 	clut_size = clut_size * num_out_channels;
 
@@ -599,16 +602,19 @@ static struct lutmABType *read_tag_lutmA
 	if (!lut)
 		return NULL;
 	// we'll fill in the rest below
 	memset(lut, 0, sizeof(struct lutmABType));
 	lut->clut_table   = &lut->clut_table_data[0];
 
 	for (i = 0; i < num_in_channels; i++) {
 		lut->num_grid_points[i] = read_u8(src, clut_offset + i);
+		if (lut->num_grid_points[i] == 0) {
+			invalid_source(src, "bad grid_points");
+		}
 	}
 
 	// Reverse the processing of transformation elements for mBA type.
 	lut->reversed = (type == LUT_MBA_TYPE);
 
 	lut->num_in_channels = num_in_channels;
 	lut->num_out_channels = num_out_channels;
 
@@ -681,51 +687,58 @@ static struct lutType *read_tag_lutType(
 	 * they have room for the num_entries fields */
 	if (type == LUT8_TYPE) {
 		num_input_table_entries = 256;
 		num_output_table_entries = 256;
 		entry_size = 1;
 	} else if (type == LUT16_TYPE) {
 		num_input_table_entries  = read_u16(src, offset + 48);
 		num_output_table_entries = read_u16(src, offset + 50);
+		if (num_input_table_entries == 0 || num_output_table_entries == 0) {
+			invalid_source(src, "Bad channel count");
+			return NULL;
+		}
 		entry_size = 2;
 	} else {
 		assert(0); // the caller checks that this doesn't happen
 		invalid_source(src, "Unexpected lut type");
 		return NULL;
 	}
 
 	in_chan     = read_u8(src, offset + 8);
 	out_chan    = read_u8(src, offset + 9);
 	grid_points = read_u8(src, offset + 10);
 
 	clut_size = pow(grid_points, in_chan);
 	if (clut_size > MAX_CLUT_SIZE) {
+		invalid_source(src, "CLUT too large");
 		return NULL;
 	}
 
 	if (in_chan != 3 || out_chan != 3) {
+		invalid_source(src, "CLUT only supports RGB");
 		return NULL;
 	}
 
 	lut = malloc(sizeof(struct lutType) + (num_input_table_entries * in_chan + clut_size*out_chan + num_output_table_entries * out_chan)*sizeof(float));
 	if (!lut) {
+		invalid_source(src, "CLUT too large");
 		return NULL;
 	}
 
 	/* compute the offsets of tables */
 	lut->input_table  = &lut->table_data[0];
 	lut->clut_table   = &lut->table_data[in_chan*num_input_table_entries];
 	lut->output_table = &lut->table_data[in_chan*num_input_table_entries + clut_size*out_chan];
 
 	lut->num_input_table_entries  = num_input_table_entries;
 	lut->num_output_table_entries = num_output_table_entries;
-	lut->num_input_channels   = read_u8(src, offset + 8);
-	lut->num_output_channels  = read_u8(src, offset + 9);
-	lut->num_clut_grid_points = read_u8(src, offset + 10);
+	lut->num_input_channels   = in_chan;
+	lut->num_output_channels  = out_chan;
+	lut->num_clut_grid_points = grid_points;
 	lut->e00 = read_s15Fixed16Number(src, offset+12);
 	lut->e01 = read_s15Fixed16Number(src, offset+16);
 	lut->e02 = read_s15Fixed16Number(src, offset+20);
 	lut->e10 = read_s15Fixed16Number(src, offset+24);
 	lut->e11 = read_s15Fixed16Number(src, offset+28);
 	lut->e12 = read_s15Fixed16Number(src, offset+32);
 	lut->e20 = read_s15Fixed16Number(src, offset+36);
 	lut->e21 = read_s15Fixed16Number(src, offset+40);