Skip to content

Commit 0991001

Browse files
authored
Merge pull request #1501 from jaytaph/gos-127-find-entity
html5: fidn_entity builds its candidate once
2 parents 6dd5f81 + f86c6a6 commit 0991001

1 file changed

Lines changed: 20 additions & 9 deletions

File tree

‎crates/gosub_html5/src/tokenizer/character_reference.rs‎

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl Tokenizer<'_> {
7474
}
7575

7676
// find_entity() only returns keys of TOKEN_NAMED_CHARS, so the lookup cannot miss
77-
let entity_chars = TOKEN_NAMED_CHARS.get(entity.as_str()).copied().unwrap_or_default();
77+
let entity_chars = TOKEN_NAMED_CHARS.get(entity).copied().unwrap_or_default();
7878

7979
// Flush codepoints consumed as character reference
8080
for c in entity_chars.chars() {
@@ -326,20 +326,27 @@ impl Tokenizer<'_> {
326326
}
327327

328328
/// Finds the longest entity from the current position in the stream. Returns the entity
329-
/// replacement OR None when no entity has been found.
330-
fn find_entity(&mut self) -> Option<String> {
329+
/// name OR None when no entity has been found.
330+
fn find_entity(&mut self) -> Option<&'static str> {
331331
let chars = self.stream.get_slice(*LONGEST_ENTITY_LENGTH);
332332

333-
for i in (0..=chars.len()).rev() {
334-
if let Some(slice) = chars.get(0..i) {
335-
let entity: String = slice.iter().map(std::string::ToString::to_string).collect();
336-
if TOKEN_NAMED_CHARS.contains_key(entity.as_str()) {
337-
return Some(entity);
333+
// Entity names are ASCII alphanumerics with an optional trailing ';', so only a
334+
// prefix of that run can match.
335+
let mut candidate = String::with_capacity(chars.len());
336+
for c in chars {
337+
match c {
338+
Ch(ch) if ch.is_ascii_alphanumeric() => candidate.push(ch),
339+
Ch(';') => {
340+
candidate.push(';');
341+
break;
338342
}
343+
_ => break,
339344
}
340345
}
341346

342-
None
347+
(1..=candidate.len())
348+
.rev()
349+
.find_map(|i| TOKEN_NAMED_CHARS.get_key(&candidate[..i]).copied())
343350
}
344351
}
345352

@@ -419,6 +426,10 @@ mod tests {
419426
entity_114: ("&copy&", "©&")
420427
entity_115: ("&copya ", "©a ")
421428
entity_116: ("&#169X ", "©X ")
429+
entity_117: ("&copyé", "©é")
430+
entity_118: ("&CounterClockwiseContourIntegral;", "∳")
431+
entity_119: ("&amp;amp;", "&amp;")
432+
entity_120: ("&notén;", "¬én;")
422433

423434
// // ChatGPT generated tests
424435
entity_200: ("&copy;", "©")

0 commit comments

Comments
 (0)