Use char_indices() instead of chars() to prevent more than one-byte characters issue

This commit is contained in:
Guillaume Gomez 2020-10-03 15:43:04 +02:00
parent 5bc148957e
commit ca199b16e5
5 changed files with 43 additions and 48 deletions

View file

@ -46,9 +46,7 @@ fn drop_tag(
f: &impl Fn(&str, &Range<usize>),
) {
let tag_name_low = tag_name.to_lowercase();
if let Some(pos) = tags.iter().rev().position(|(t, _)| t.to_lowercase() == tag_name_low) {
// Because this is from a `rev` iterator, the position is reversed as well!
let pos = tags.len() - 1 - pos;
if let Some(pos) = tags.iter().rposition(|(t, _)| t.to_lowercase() == tag_name_low) {
// If the tag is nested inside a "<script>" or a "<style>" tag, no warning should
// be emitted.
let should_not_warn = tags.iter().take(pos + 1).any(|(at, _)| {
@ -83,9 +81,9 @@ fn extract_tag(
range: Range<usize>,
f: &impl Fn(&str, &Range<usize>),
) {
let mut iter = text.chars().enumerate().peekable();
let mut iter = text.char_indices().peekable();
'top: while let Some((start_pos, c)) = iter.next() {
while let Some((start_pos, c)) = iter.next() {
if c == '<' {
let mut tag_name = String::new();
let mut is_closing = false;
@ -118,20 +116,11 @@ fn extract_tag(
tags.push((tag_name, r));
}
}
continue 'top;
}
// Some chars like 💩 are longer than 1 character, so we need to skip the other
// bytes as well to prevent stopping "in the middle" of a char.
for _ in 0..c.len_utf8() {
iter.next();
break;
}
iter.next();
}
}
// Some chars like 💩 are longer than 1 character, so we need to skip the other
// bytes as well to prevent stopping "in the middle" of a char.
for _ in 0..c.len_utf8() - 1 {
iter.next();
}
}
}

View file

@ -1,4 +1,3 @@
#![allow(invalid_html_tags)]
#![deny(broken_intra_doc_links)]
//~^ NOTE lint level is defined

View file

@ -1,95 +1,95 @@
error: unresolved link to `path::to::nonexistent::module`
--> $DIR/intra-link-errors.rs:8:6
--> $DIR/intra-link-errors.rs:7:6
|
LL | /// [path::to::nonexistent::module]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path`
|
note: the lint level is defined here
--> $DIR/intra-link-errors.rs:2:9
--> $DIR/intra-link-errors.rs:1:9
|
LL | #![deny(broken_intra_doc_links)]
| ^^^^^^^^^^^^^^^^^^^^^^
error: unresolved link to `path::to::nonexistent::macro`
--> $DIR/intra-link-errors.rs:12:6
--> $DIR/intra-link-errors.rs:11:6
|
LL | /// [path::to::nonexistent::macro!]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path`
error: unresolved link to `path::to::nonexistent::type`
--> $DIR/intra-link-errors.rs:16:6
--> $DIR/intra-link-errors.rs:15:6
|
LL | /// [type@path::to::nonexistent::type]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path`
error: unresolved link to `std::io::not::here`
--> $DIR/intra-link-errors.rs:20:6
--> $DIR/intra-link-errors.rs:19:6
|
LL | /// [std::io::not::here]
| ^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not`
error: unresolved link to `std::io::not::here`
--> $DIR/intra-link-errors.rs:24:6
--> $DIR/intra-link-errors.rs:23:6
|
LL | /// [type@std::io::not::here]
| ^^^^^^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not`
error: unresolved link to `std::io::Error::x`
--> $DIR/intra-link-errors.rs:28:6
--> $DIR/intra-link-errors.rs:27:6
|
LL | /// [std::io::Error::x]
| ^^^^^^^^^^^^^^^^^ the struct `Error` has no field or associated item named `x`
error: unresolved link to `std::io::ErrorKind::x`
--> $DIR/intra-link-errors.rs:32:6
--> $DIR/intra-link-errors.rs:31:6
|
LL | /// [std::io::ErrorKind::x]
| ^^^^^^^^^^^^^^^^^^^^^ the enum `ErrorKind` has no variant or associated item named `x`
error: unresolved link to `f::A`
--> $DIR/intra-link-errors.rs:36:6
--> $DIR/intra-link-errors.rs:35:6
|
LL | /// [f::A]
| ^^^^ `f` is a function, not a module or type, and cannot have associated items
error: unresolved link to `f::A`
--> $DIR/intra-link-errors.rs:40:6
--> $DIR/intra-link-errors.rs:39:6
|
LL | /// [f::A!]
| ^^^^^ `f` is a function, not a module or type, and cannot have associated items
error: unresolved link to `S::A`
--> $DIR/intra-link-errors.rs:44:6
--> $DIR/intra-link-errors.rs:43:6
|
LL | /// [S::A]
| ^^^^ the struct `S` has no field or associated item named `A`
error: unresolved link to `S::fmt`
--> $DIR/intra-link-errors.rs:48:6
--> $DIR/intra-link-errors.rs:47:6
|
LL | /// [S::fmt]
| ^^^^^^ the struct `S` has no field or associated item named `fmt`
error: unresolved link to `E::D`
--> $DIR/intra-link-errors.rs:52:6
--> $DIR/intra-link-errors.rs:51:6
|
LL | /// [E::D]
| ^^^^ the enum `E` has no variant or associated item named `D`
error: unresolved link to `u8::not_found`
--> $DIR/intra-link-errors.rs:56:6
--> $DIR/intra-link-errors.rs:55:6
|
LL | /// [u8::not_found]
| ^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found`
error: unresolved link to `std::primitive::u8::not_found`
--> $DIR/intra-link-errors.rs:60:6
--> $DIR/intra-link-errors.rs:59:6
|
LL | /// [std::primitive::u8::not_found]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found`
error: unresolved link to `Vec::into_iter`
--> $DIR/intra-link-errors.rs:64:6
--> $DIR/intra-link-errors.rs:63:6
|
LL | /// [type@Vec::into_iter]
| ^^^^^^^^^^^^^^^^^^^
@ -98,7 +98,7 @@ LL | /// [type@Vec::into_iter]
| help: to link to the associated function, add parentheses: `Vec::into_iter()`
error: unresolved link to `S`
--> $DIR/intra-link-errors.rs:69:6
--> $DIR/intra-link-errors.rs:68:6
|
LL | /// [S!]
| ^^
@ -107,7 +107,7 @@ LL | /// [S!]
| help: to link to the struct, prefix with `struct@`: `struct@S`
error: unresolved link to `T::g`
--> $DIR/intra-link-errors.rs:87:6
--> $DIR/intra-link-errors.rs:86:6
|
LL | /// [type@T::g]
| ^^^^^^^^^
@ -116,13 +116,13 @@ LL | /// [type@T::g]
| help: to link to the associated function, add parentheses: `T::g()`
error: unresolved link to `T::h`
--> $DIR/intra-link-errors.rs:92:6
--> $DIR/intra-link-errors.rs:91:6
|
LL | /// [T::h!]
| ^^^^^ the trait `T` has no macro named `h`
error: unresolved link to `S::h`
--> $DIR/intra-link-errors.rs:79:6
--> $DIR/intra-link-errors.rs:78:6
|
LL | /// [type@S::h]
| ^^^^^^^^^
@ -131,7 +131,7 @@ LL | /// [type@S::h]
| help: to link to the associated function, add parentheses: `S::h()`
error: unresolved link to `m`
--> $DIR/intra-link-errors.rs:99:6
--> $DIR/intra-link-errors.rs:98:6
|
LL | /// [m()]
| ^^^

View file

@ -2,6 +2,7 @@
//! <p>💩<p>
//~^ ERROR unclosed HTML tag `p`
//~^^ ERROR unclosed HTML tag `p`
/// <img><input>
/// <script>

View file

@ -10,59 +10,65 @@ note: the lint level is defined here
LL | #![deny(invalid_html_tags)]
| ^^^^^^^^^^^^^^^^^
error: unclosed HTML tag `p`
--> $DIR/invalid-html-tags.rs:3:9
|
LL | //! <p>💩<p>
| ^^^
error: unclosed HTML tag `unknown`
--> $DIR/invalid-html-tags.rs:10:5
--> $DIR/invalid-html-tags.rs:11:5
|
LL | /// <unknown>
| ^^^^^^^^^
error: unclosed HTML tag `script`
--> $DIR/invalid-html-tags.rs:13:5
--> $DIR/invalid-html-tags.rs:14:5
|
LL | /// <script>
| ^^^^^^^^
error: unclosed HTML tag `h2`
--> $DIR/invalid-html-tags.rs:18:7
--> $DIR/invalid-html-tags.rs:19:7
|
LL | /// <h2>
| ^^^^
error: unclosed HTML tag `h3`
--> $DIR/invalid-html-tags.rs:20:9
--> $DIR/invalid-html-tags.rs:21:9
|
LL | /// <h3>
| ^^^^
error: unopened HTML tag `hello`
--> $DIR/invalid-html-tags.rs:23:5
--> $DIR/invalid-html-tags.rs:24:5
|
LL | /// </hello>
| ^^^^^^^^
error: unclosed HTML tag `p`
--> $DIR/invalid-html-tags.rs:28:14
--> $DIR/invalid-html-tags.rs:29:14
|
LL | /// <br/> <p>
| ^^^
error: unclosed HTML tag `div`
--> $DIR/invalid-html-tags.rs:40:5
--> $DIR/invalid-html-tags.rs:41:5
|
LL | /// <div style="hello">
| ^^^^
error: unclosed HTML tag `h3`
--> $DIR/invalid-html-tags.rs:42:7
--> $DIR/invalid-html-tags.rs:43:7
|
LL | /// <h3>
| ^^^^
error: unclosed HTML tag `script`
--> $DIR/invalid-html-tags.rs:44:5
--> $DIR/invalid-html-tags.rs:45:5
|
LL | /// <script
| ^^^^^^
error: aborting due to 10 previous errors
error: aborting due to 11 previous errors