Use char_indices() instead of chars() to prevent more than one-byte characters issue
This commit is contained in:
parent
5bc148957e
commit
ca199b16e5
5 changed files with 43 additions and 48 deletions
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![allow(invalid_html_tags)]
|
||||
#![deny(broken_intra_doc_links)]
|
||||
//~^ NOTE lint level is defined
|
||||
|
||||
|
|
|
|||
|
|
@ -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()]
|
||||
| ^^^
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
//! <p>💩<p>
|
||||
//~^ ERROR unclosed HTML tag `p`
|
||||
//~^^ ERROR unclosed HTML tag `p`
|
||||
|
||||
/// <img><input>
|
||||
/// <script>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue