Skip to content

Commit cbc66c9

Browse files
authored
Merge pull request #1471 from epage/hex
fix(tokens): Ignore hex literals with suffixes
2 parents 3cee018 + 2071579 commit cbc66c9

File tree

2 files changed

+26
-21
lines changed

2 files changed

+26
-21
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
int main() {
2-
uint8 i = 0;
2+
uint8 i = 0x1afe23456UL;
33
std::countr_one(i);
44
return 0;
55
}

crates/typos/src/tokens.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,9 @@ mod parser {
146146
/// later may cause it to fail.
147147
const NON_TERMINATING_CAP: usize = 1024;
148148

149-
pub(crate) fn next_identifier<T>(input: &mut T) -> Result<<T as Stream>::Slice, ()>
149+
pub(crate) fn next_identifier<'i, T>(input: &mut T) -> Result<<T as Stream>::Slice, ()>
150150
where
151+
T: Compare<&'i str>,
151152
T: Compare<char>,
152153
T: Stream + StreamIsPartial + PartialEq,
153154
<T as Stream>::Slice: AsBStr + SliceLen + Default,
@@ -174,8 +175,9 @@ mod parser {
174175
.parse_next(input)
175176
}
176177

177-
fn ignore<T>(input: &mut T) -> Result<<T as Stream>::Slice, ()>
178+
fn ignore<'i, T>(input: &mut T) -> Result<<T as Stream>::Slice, ()>
178179
where
180+
T: Compare<&'i str>,
179181
T: Compare<char>,
180182
T: Stream + StreamIsPartial + PartialEq,
181183
<T as Stream>::Slice: AsBStr + SliceLen + Default,
@@ -236,9 +238,10 @@ mod parser {
236238
.parse_next(input)
237239
}
238240

239-
fn ordinal_literal<T>(input: &mut T) -> Result<<T as Stream>::Slice, ()>
241+
fn ordinal_literal<'i, T>(input: &mut T) -> Result<<T as Stream>::Slice, ()>
240242
where
241243
T: Compare<char>,
244+
T: Compare<&'i str>,
242245
T: Stream + StreamIsPartial + PartialEq,
243246
<T as Stream>::Slice: AsBStr + SliceLen + Default,
244247
<T as Stream>::Token: AsChar + Copy,
@@ -254,7 +257,7 @@ mod parser {
254257
(
255258
take_while(0.., is_sep),
256259
take_while(1.., is_dec_digit),
257-
alt((('s', 't'), ('n', 'd'), ('r', 'd'), ('t', 'h'))),
260+
alt((("st"), ("nd"), ("rd"), ("th"))),
258261
take_while(0.., is_sep),
259262
)
260263
.take(),
@@ -278,7 +281,13 @@ mod parser {
278281
<T as Stream>::Slice: AsBStr + SliceLen + Default,
279282
<T as Stream>::Token: AsChar + Copy,
280283
{
281-
('0', alt(('x', 'X')), take_while(1.., is_hex_digit_with_sep))
284+
(
285+
'0',
286+
alt(('x', 'X')),
287+
take_while(1.., is_hex_digit_with_sep),
288+
take_while(0.., is_xid_continue)
289+
.verify(|s: &<T as Stream>::Slice| std::str::from_utf8(s.as_bstr()).is_ok()),
290+
)
282291
.take()
283292
.parse_next(input)
284293
}
@@ -304,22 +313,20 @@ mod parser {
304313
.parse_next(input)
305314
}
306315

307-
fn jwt<T>(input: &mut T) -> Result<<T as Stream>::Slice, ()>
316+
fn jwt<'i, T>(input: &mut T) -> Result<<T as Stream>::Slice, ()>
308317
where
309318
T: Compare<char>,
319+
T: Compare<&'i str>,
310320
T: Stream + StreamIsPartial + PartialEq,
311321
<T as Stream>::Slice: AsBStr + SliceLen + Default,
312322
<T as Stream>::Token: AsChar + Copy,
313323
{
314324
trace(
315325
"jwt",
316326
(
317-
'e',
318-
'y',
327+
"ey",
319328
take_while(20.., is_jwt_token),
320-
'.',
321-
'e',
322-
'y',
329+
".ey",
323330
take_while(20.., is_jwt_token),
324331
'.',
325332
take_while(20.., is_jwt_token),
@@ -422,10 +429,7 @@ mod parser {
422429

423430
if captured.slice_len() < 90
424431
&& padding_len == 0
425-
&& captured
426-
.as_bstr()
427-
.iter()
428-
.all(|c| !['/', '+'].contains(&c.as_char()))
432+
&& captured.as_bstr().iter().all(|c| ![b'/', b'+'].contains(c))
429433
{
430434
#[allow(clippy::unit_arg)]
431435
return Err(ParserError::from_input(input));
@@ -459,9 +463,10 @@ mod parser {
459463
.parse_next(input)
460464
}
461465

462-
fn url_literal<T>(input: &mut T) -> Result<<T as Stream>::Slice, ()>
466+
fn url_literal<'i, T>(input: &mut T) -> Result<<T as Stream>::Slice, ()>
463467
where
464468
T: Compare<char>,
469+
T: Compare<&'i str>,
465470
T: Stream + StreamIsPartial + PartialEq,
466471
<T as Stream>::Slice: AsBStr + SliceLen + Default,
467472
<T as Stream>::Token: AsChar + Copy,
@@ -473,7 +478,7 @@ mod parser {
473478
take_while(1..NON_TERMINATING_CAP, is_scheme_char),
474479
// HACK: Technically you can skip `//` if you don't have a domain but that would
475480
// get messy to support.
476-
(':', '/', '/'),
481+
("://"),
477482
)),
478483
(
479484
opt((url_userinfo, '@')),
@@ -1260,7 +1265,7 @@ mod test {
12601265
fn tokenize_ignore_hex() {
12611266
let parser = TokenizerBuilder::new().build();
12621267

1263-
let input = "Hello 0xDEADBEEF World";
1268+
let input = "Hello 0xDEADBEEF 0x1afe23456UL World";
12641269
let actual: Vec<_> = parser.parse_bytes(input.as_bytes()).collect();
12651270
assert_data_eq!(
12661271
actual.to_debug(),
@@ -1274,7 +1279,7 @@ mod test {
12741279
Identifier {
12751280
token: "World",
12761281
case: None,
1277-
offset: 17,
1282+
offset: 31,
12781283
},
12791284
]
12801285
@@ -1293,7 +1298,7 @@ mod test {
12931298
Identifier {
12941299
token: "World",
12951300
case: None,
1296-
offset: 17,
1301+
offset: 31,
12971302
},
12981303
]
12991304

0 commit comments

Comments
 (0)