Skip to content

Commit f447500

Browse files
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
1 parent 92f356e commit f447500

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

idna/src/punycode.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ fn adapt(mut delta: u32, num_points: u32, first_time: bool) -> u32 {
4141

4242
/// Convert Punycode to an Unicode `String`.
4343
///
44-
/// This is a convenience wrapper around `decode`.
44+
/// Return None on malformed input or overflow.
45+
/// Overflow can only happen on inputs that take more than
46+
/// 63 encoded bytes, the DNS limit on domain name labels.
4547
#[inline]
4648
pub fn decode_to_string(input: &str) -> Option<String> {
47-
decode(input).map(|chars| chars.into_iter().collect())
49+
Some(Decoder::default().decode(input).ok()?.collect())
4850
}
4951

5052
/// Convert Punycode to Unicode.

idna/tests/punycode.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// except according to those terms.
88

99
use crate::test::TestFn;
10-
use idna::punycode::{decode, encode_str};
10+
use idna::punycode::{decode, decode_to_string, encode_str};
1111
use serde_json::map::Map;
1212
use serde_json::Value;
1313
use std::panic::catch_unwind;
@@ -28,6 +28,17 @@ fn one_test(decoded: &str, encoded: &str) {
2828
}
2929
}
3030

31+
match decode_to_string(encoded) {
32+
None => panic!("Decoding {} failed.", encoded),
33+
Some(result) => assert!(
34+
result == decoded,
35+
"Incorrect decoding of \"{}\":\n \"{}\"\n!= \"{}\"\n",
36+
encoded,
37+
result,
38+
decoded
39+
),
40+
}
41+
3142
match encode_str(decoded) {
3243
None => panic!("Encoding {} failed.", decoded),
3344
Some(result) => assert!(

0 commit comments

Comments
 (0)