Просмотр исходного кода

perf(punycode): avoid double allocation in decode_to_string (#894)

* perf(punycode): avoid double allocation in decode_to_string

* include decode_to_string in tests
bishopcheckmate 2 лет назад
Родитель
Сommit
f447500049
2 измененных файлов с 16 добавлено и 3 удалено
  1. 4 2
      idna/src/punycode.rs
  2. 12 1
      idna/tests/punycode.rs

+ 4 - 2
idna/src/punycode.rs

@@ -41,10 +41,12 @@ fn adapt(mut delta: u32, num_points: u32, first_time: bool) -> u32 {
 
 /// Convert Punycode to an Unicode `String`.
 ///
-/// This is a convenience wrapper around `decode`.
+/// Return None on malformed input or overflow.
+/// Overflow can only happen on inputs that take more than
+/// 63 encoded bytes, the DNS limit on domain name labels.
 #[inline]
 pub fn decode_to_string(input: &str) -> Option<String> {
-    decode(input).map(|chars| chars.into_iter().collect())
+    Some(Decoder::default().decode(input).ok()?.collect())
 }
 
 /// Convert Punycode to Unicode.

+ 12 - 1
idna/tests/punycode.rs

@@ -7,7 +7,7 @@
 // except according to those terms.
 
 use crate::test::TestFn;
-use idna::punycode::{decode, encode_str};
+use idna::punycode::{decode, decode_to_string, encode_str};
 use serde_json::map::Map;
 use serde_json::Value;
 use std::panic::catch_unwind;
@@ -28,6 +28,17 @@ fn one_test(decoded: &str, encoded: &str) {
         }
     }
 
+    match decode_to_string(encoded) {
+        None => panic!("Decoding {} failed.", encoded),
+        Some(result) => assert!(
+            result == decoded,
+            "Incorrect decoding of \"{}\":\n   \"{}\"\n!= \"{}\"\n",
+            encoded,
+            result,
+            decoded
+        ),
+    }
+
     match encode_str(decoded) {
         None => panic!("Encoding {} failed.", decoded),
         Some(result) => assert!(