Bug 1132468 - Reject invalid sizes. r=jrmuizel, a=lizzard
authorBenoit Girard <b56girard@gmail.com>
Tue, 24 Feb 2015 17:02:10 -0500
changeset 250234 1f4073c76b2b
parent 250233 2f6284a0d529
child 250235 70d3a14eab61
push id4523
push userryanvm@gmail.com
push date2015-03-04 17:35 +0000
treeherdermozilla-beta@729cf69ef43f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, lizzard
bugs1132468
milestone37.0
Bug 1132468 - Reject invalid sizes. r=jrmuizel, a=lizzard
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 + 8);
 	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);