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