Bladeren bron

fix panic on `xn--55555577` (#940)

* reproduce a panic when parsing a specific URL

Details can be found here: https://github.com/Byron/gitoxide/issues/1401

* fix overflow when processing punycode encoded URLs like `xn--55555577`

* fix clippy error
Sebastian Thiel 2 jaren geleden
bovenliggende
commit
467ef63969
4 gewijzigde bestanden met toevoegingen van 10 en 5 verwijderingen
  1. 1 2
      idna/src/punycode.rs
  2. 6 0
      idna/tests/unit.rs
  3. 1 1
      url/src/host.rs
  4. 2 2
      url/src/parser.rs

+ 1 - 2
idna/src/punycode.rs

@@ -17,7 +17,6 @@ use alloc::{string::String, vec::Vec};
 use core::char;
 use core::fmt::Write;
 use core::marker::PhantomData;
-use core::u32;
 
 // Bootstring parameters for Punycode
 const BASE: u32 = 36;
@@ -215,7 +214,7 @@ impl Decoder {
                 if C::EXTERNAL_CALLER && (digit > (u32::MAX - i) / weight) {
                     return Err(()); // Overflow
                 }
-                i += digit * weight;
+                i = i.checked_add(digit * weight).ok_or(())?;
                 let t = if k <= bias {
                     T_MIN
                 } else if k >= bias + T_MAX {

+ 6 - 0
idna/tests/unit.rs

@@ -40,6 +40,12 @@ fn test_punycode_prefix_without_length_check() {
     assert!(config.to_ascii("xn--.example.org").is_err());
 }
 
+#[test]
+fn test_punycode_invalid_encoding() {
+    let config = idna::Config::default();
+    assert!(config.to_ascii("xn--55555577").is_err());
+}
+
 // http://www.unicode.org/reports/tr46/#Table_Example_Processing
 #[test]
 fn test_examples() {

+ 1 - 1
url/src/host.rs

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

+ 2 - 2
url/src/parser.rs

@@ -1109,7 +1109,7 @@ impl<'a> Parser<'a> {
         while let (Some(c), remaining) = input.split_first() {
             if let Some(digit) = c.to_digit(10) {
                 port = port * 10 + digit;
-                if port > ::std::u16::MAX as u32 {
+                if port > u16::MAX as u32 {
                     return Err(ParseError::InvalidPort);
                 }
                 has_any_digit = true;
@@ -1590,7 +1590,7 @@ pub fn ascii_alpha(ch: char) -> bool {
 
 #[inline]
 pub fn to_u32(i: usize) -> ParseResult<u32> {
-    if i <= ::std::u32::MAX as usize {
+    if i <= u32::MAX as usize {
         Ok(i as u32)
     } else {
         Err(ParseError::Overflow)