When parsing UUIDs through format-specific types, some invalid inputs produce incorrect error diagnostics.
Reproduction
use std::str::FromStr;
use uuid::fmt::{Hyphenated, Simple, Urn, Braced};
fn main() {
// Misleading and internally inconsistent error: "expected length 32 ... found 32".
// This is parsed as Hyphenated, but it is reported as a Simple-style length error.
println!("{}", Hyphenated::from_str("550e8400e29b41d4a716446655440000").unwrap_err());
// Self-contradictory and misclassified error: "expected 12, found 12".
// Simple has no groups at all.
println!("{}", Simple::from_str("550e8400-e29b-41d4-a716-446655440000").unwrap_err());
// Self-contradictory and misclassified error: "expected 12, found 12".
// The actual problem, the missing `urn:uuid:` prefix, is never mentioned.
println!("{}", Urn::from_str("550e8400-e29b-41d4-a716-446655440000").unwrap_err());
// Self-contradictory and misclassified error: "expected 12, found 12".
// The actual problem, the missing braces, is never mentioned.
println!("{}", Braced::from_str("550e8400-e29b-41d4-a716-446655440000").unwrap_err());
}
Output:
invalid length: expected length 32 for simple format, found 32
invalid group length in group 4: expected 12, found 12
invalid group length in group 4: expected 12, found 12
invalid group length in group 4: expected 12, found 12
Expected behavior
The parsers should still reject these inputs. However, a format-specific parser should not report an error as if a different UUID format had been requested. The diagnostic should also not report equal expected and actual values, such as expected 12, found 12.
Suspected cause
|
impl FromStr for Hyphenated { |
|
type Err = Error; |
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> { |
|
crate::parser::parse_hyphenated(s.as_bytes()) |
|
.map(|b| Hyphenated(Uuid(b))) |
|
.map_err(|invalid| invalid.into_err()) |
|
} |
|
} |
|
|
|
impl FromStr for Simple { |
|
type Err = Error; |
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> { |
|
crate::parser::parse_simple(s.as_bytes()) |
|
.map(|b| Simple(Uuid(b))) |
|
.map_err(|invalid| invalid.into_err()) |
|
} |
|
} |
|
|
|
impl FromStr for Urn { |
|
type Err = Error; |
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> { |
|
crate::parser::parse_urn(s.as_bytes()) |
|
.map(|b| Urn(Uuid(b))) |
|
.map_err(|invalid| invalid.into_err()) |
|
} |
|
} |
|
|
|
impl FromStr for Braced { |
|
type Err = Error; |
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> { |
|
crate::parser::parse_braced(s.as_bytes()) |
|
.map(|b| Braced(Uuid(b))) |
|
.map_err(|invalid| invalid.into_err()) |
|
} |
|
} |
The format-specific parsers call their corresponding strict parser first, then convert the lightweight parse failure through InvalidUuid::into_err(). InvalidUuid::into_err() re-analyzes the input string generically in order to construct a detailed Error. As a result, the generated diagnostic may be based on a perspective other than the originally requested format, which can lead to inaccurate error reporting.
When parsing UUIDs through format-specific types, some invalid inputs produce incorrect error diagnostics.
Reproduction
Output:
Expected behavior
The parsers should still reject these inputs. However, a format-specific parser should not report an error as if a different UUID format had been requested. The diagnostic should also not report equal expected and actual values, such as
expected 12, found 12.Suspected cause
uuid/src/fmt.rs
Lines 871 to 909 in ca0c85f
The format-specific parsers call their corresponding strict parser first, then convert the lightweight parse failure through
InvalidUuid::into_err().InvalidUuid::into_err()re-analyzes the input string generically in order to construct a detailed Error. As a result, the generated diagnostic may be based on a perspective other than the originally requested format, which can lead to inaccurate error reporting.