Skip to content

Commit

Permalink
Report error for invalid hex (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
cakevm authored Jan 10, 2025
1 parent 81587d7 commit f7812e3
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

## [Unreleased]
- Use latest stable Rust version 1.84
- Report error for invalid hex literals `0x0x`

## [1.0.1] - 2025-01-10
- Validate that a constant hex literal is not longer than 32 bytes
Expand Down
13 changes: 7 additions & 6 deletions crates/lexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,17 +444,18 @@ impl<'a> Lexer<'a> {

fn eat_hex_digit(&mut self, initial_char: char) -> TokenResult {
let (integer_str, mut start, end) = self.eat_while(Some(initial_char), |ch| ch.is_ascii_hexdigit() | (ch == 'x'));
if integer_str.matches('x').count() != 1 {
return Err(LexicalError::new(
LexicalErrorKind::InvalidHexLiteral(integer_str.clone()),
self.source.relative_span_by_pos(start, end),
));
}

// TODO: check for sure that we have a correct hex string, eg. 0x56 and not 0x56x34
let kind = if self.context == Context::CodeTableBody {
// In codetables, the bytecode provided is of arbitrary length. We pass
// the code as an Ident, and it is appended to the end of the runtime
// bytecode in codegen.
if &integer_str[0..2] == "0x" {
TokenKind::Ident(integer_str[2..].to_owned())
} else {
TokenKind::Ident(integer_str)
}
TokenKind::Ident(integer_str[2..].to_owned())
} else {
// Only max 32 Bytes is allowed for hex string 0x. 2 + 64 = 66 characters
if integer_str.len() > 66 {
Expand Down
14 changes: 14 additions & 0 deletions crates/lexer/tests/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,17 @@ fn constant_hex_literal_too_long() {
}
panic!("Error did not occurred")
}

#[test]
fn constant_invalid_hex_literal() {
let source = "#define constant TEST = 0x0x";
let flattened_source = FullFileSource { source, file: None, spans: vec![] };
let lexer = Lexer::new(flattened_source);
for tok in lexer {
if tok.is_err() {
assert_eq!(tok.unwrap_err().kind, LexicalErrorKind::InvalidHexLiteral("0x0x".to_string()));
return;
}
}
panic!("Error did not occurred")
}
8 changes: 8 additions & 0 deletions crates/utils/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ pub enum LexicalErrorKind {
InvalidCharacter(char),
/// Invalid hex literal
HexLiteralTooLong(String),
/// Invalid Hex Literal
InvalidHexLiteral(String),
/// Invalid Array Size
/// String param expected to be usize parsable
InvalidArraySize(String),
Expand Down Expand Up @@ -123,6 +125,9 @@ impl<W: Write> Report<W> for LexicalError {
LexicalErrorKind::HexLiteralTooLong(str) => {
write!(f.out, "Hex literal has more than 32 bytes '{str}'")
}
LexicalErrorKind::InvalidHexLiteral(str) => {
write!(f.out, "Invalid Hex literal '{str}'")
}
}
}
}
Expand Down Expand Up @@ -296,6 +301,9 @@ impl fmt::Display for CompilerError {
LexicalErrorKind::HexLiteralTooLong(h) => {
write!(f, "\nError: Hex literal has more than 32 bytes: \"{}\" {}{}\n", h, le.span.identifier(), le.span.source_seg())
}
LexicalErrorKind::InvalidHexLiteral(h) => {
write!(f, "\nError: Invalid Hex literal: \"{}\" {}{}\n", h, le.span.identifier(), le.span.source_seg())
}
},
CompilerError::FileUnpackError(ue) => match ue {
UnpackError::InvalidDirectory(id) => {
Expand Down

0 comments on commit f7812e3

Please sign in to comment.