checker: ensure hex character literals don't overflow in strings (#10725)
							parent
							
								
									1b26ce1f7a
								
							
						
					
					
						commit
						02f0a30555
					
				|  | @ -493,6 +493,44 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Typ | ||||||
| 	return ast.string_type | 	return ast.string_type | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pub fn (mut c Checker) string_lit(mut node ast.StringLiteral) ast.Type { | ||||||
|  | 	mut idx := 0 | ||||||
|  | 	for idx < node.val.len { | ||||||
|  | 		match node.val[idx] { | ||||||
|  | 			`\\` { | ||||||
|  | 				mut start_pos := token.Position{ | ||||||
|  | 					...node.pos | ||||||
|  | 					col: node.pos.col + 1 + idx | ||||||
|  | 				} | ||||||
|  | 				start_idx := idx | ||||||
|  | 				idx++ | ||||||
|  | 				next_ch := node.val[idx] or { return ast.string_type } | ||||||
|  | 				if next_ch == `x` { | ||||||
|  | 					idx++ | ||||||
|  | 					mut ch := node.val[idx] or { return ast.string_type } | ||||||
|  | 					mut hex_char_count := 0 | ||||||
|  | 					for ch.is_hex_digit() { | ||||||
|  | 						hex_char_count++ | ||||||
|  | 						if hex_char_count > 4 { | ||||||
|  | 							end_pos := token.Position{ | ||||||
|  | 								...start_pos | ||||||
|  | 								len: idx + 1 - start_idx | ||||||
|  | 							} | ||||||
|  | 							c.error('hex character literal overflows string', end_pos) | ||||||
|  | 						} | ||||||
|  | 						idx++ | ||||||
|  | 						ch = node.val[idx] or { return ast.string_type } | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				idx++ | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return ast.string_type | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub fn (mut c Checker) int_lit(mut node ast.IntegerLiteral) ast.Type { | pub fn (mut c Checker) int_lit(mut node ast.IntegerLiteral) ast.Type { | ||||||
| 	if node.val.len < 17 { | 	if node.val.len < 17 { | ||||||
| 		// can not be a too large number, no need for more expensive checks
 | 		// can not be a too large number, no need for more expensive checks
 | ||||||
|  |  | ||||||
|  | @ -5069,7 +5069,7 @@ pub fn (mut c Checker) expr(node ast.Expr) ast.Type { | ||||||
| 				// string literal starts with "c": `C.printf(c'hello')`
 | 				// string literal starts with "c": `C.printf(c'hello')`
 | ||||||
| 				return ast.byte_type.set_nr_muls(1) | 				return ast.byte_type.set_nr_muls(1) | ||||||
| 			} | 			} | ||||||
| 			return ast.string_type | 			return c.string_lit(mut node) | ||||||
| 		} | 		} | ||||||
| 		ast.StringInterLiteral { | 		ast.StringInterLiteral { | ||||||
| 			return c.string_inter_lit(mut node) | 			return c.string_inter_lit(mut node) | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | vlib/v/checker/tests/hex_literal_overflow.vv:1:35: error: hex character literal overflows string | ||||||
|  |     1 | s := 'this hex character literal, \xffffffff, should be caught by the checker' | ||||||
|  |       |                                   ~~~~~~~ | ||||||
|  |     2 | println(s) | ||||||
|  | @ -0,0 +1,2 @@ | ||||||
|  | s := 'this hex character literal, \xffffffff, should be caught by the checker' | ||||||
|  | println(s) | ||||||
		Loading…
	
		Reference in New Issue