Skip to content

Commit 467ef63

Browse files
authored
fix panic on xn--55555577 (#940)
* reproduce a panic when parsing a specific URL Details can be found here: GitoxideLabs/gitoxide#1401 * fix overflow when processing punycode encoded URLs like `xn--55555577` * fix clippy error
1 parent 3d6dbbb commit 467ef63

File tree

4 files changed

+10
-5
lines changed

4 files changed

+10
-5
lines changed

idna/src/punycode.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use alloc::{string::String, vec::Vec};
1717
use core::char;
1818
use core::fmt::Write;
1919
use core::marker::PhantomData;
20-
use core::u32;
2120

2221
// Bootstring parameters for Punycode
2322
const BASE: u32 = 36;
@@ -215,7 +214,7 @@ impl Decoder {
215214
if C::EXTERNAL_CALLER && (digit > (u32::MAX - i) / weight) {
216215
return Err(()); // Overflow
217216
}
218-
i += digit * weight;
217+
i = i.checked_add(digit * weight).ok_or(())?;
219218
let t = if k <= bias {
220219
T_MIN
221220
} else if k >= bias + T_MAX {

idna/tests/unit.rs

+6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ fn test_punycode_prefix_without_length_check() {
4040
assert!(config.to_ascii("xn--.example.org").is_err());
4141
}
4242

43+
#[test]
44+
fn test_punycode_invalid_encoding() {
45+
let config = idna::Config::default();
46+
assert!(config.to_ascii("xn--55555577").is_err());
47+
}
48+
4349
// http://www.unicode.org/reports/tr46/#Table_Example_Processing
4450
#[test]
4551
fn test_examples() {

url/src/host.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ fn parse_ipv4addr(input: &str) -> ParseResult<Ipv4Addr> {
309309
}
310310
let mut ipv4 = numbers.pop().expect("a non-empty list of numbers");
311311
// Equivalent to: ipv4 >= 256 ** (4 − numbers.len())
312-
if ipv4 > u32::max_value() >> (8 * numbers.len() as u32) {
312+
if ipv4 > u32::MAX >> (8 * numbers.len() as u32) {
313313
return Err(ParseError::InvalidIpv4Address);
314314
}
315315
if numbers.iter().any(|x| *x > 255) {

url/src/parser.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,7 @@ impl<'a> Parser<'a> {
11091109
while let (Some(c), remaining) = input.split_first() {
11101110
if let Some(digit) = c.to_digit(10) {
11111111
port = port * 10 + digit;
1112-
if port > ::std::u16::MAX as u32 {
1112+
if port > u16::MAX as u32 {
11131113
return Err(ParseError::InvalidPort);
11141114
}
11151115
has_any_digit = true;
@@ -1590,7 +1590,7 @@ pub fn ascii_alpha(ch: char) -> bool {
15901590

15911591
#[inline]
15921592
pub fn to_u32(i: usize) -> ParseResult<u32> {
1593-
if i <= ::std::u32::MAX as usize {
1593+
if i <= u32::MAX as usize {
15941594
Ok(i as u32)
15951595
} else {
15961596
Err(ParseError::Overflow)

0 commit comments

Comments
 (0)