Upgrade idna to 0.5.0

This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update external/rust/crates/idna
For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md

Test: TreeHugger
Change-Id: I96d7c0adb55f3ef853a1acee00c92f64964c832a
diff --git a/src/lib.rs b/src/lib.rs
index 37d6387..92914f9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -31,11 +31,23 @@
 //! > This document specifies a mechanism
 //! > that minimizes the impact of this transition for client software,
 //! > allowing client software to access domains that are valid under either system.
+#![no_std]
+
+// For forwards compatibility
+#[cfg(feature = "std")]
+extern crate std;
+
+extern crate alloc;
+
+#[cfg(not(feature = "alloc"))]
+compile_error!("the `alloc` feature must be enabled");
 
 #[cfg(test)]
 #[macro_use]
 extern crate assert_matches;
 
+use alloc::string::String;
+
 pub mod punycode;
 mod uts46;
 
diff --git a/src/punycode.rs b/src/punycode.rs
index 21955f3..b1afc96 100644
--- a/src/punycode.rs
+++ b/src/punycode.rs
@@ -13,8 +13,9 @@
 //! `encode_str` and `decode_to_string` provide convenience wrappers
 //! that convert from and to Rust’s UTF-8 based `str` and `String` types.
 
-use std::char;
-use std::u32;
+use alloc::{string::String, vec::Vec};
+use core::char;
+use core::u32;
 
 // Bootstring parameters for Punycode
 static BASE: u32 = 36;
@@ -168,7 +169,7 @@
 }
 
 pub(crate) struct Decode<'a> {
-    base: std::str::Chars<'a>,
+    base: core::str::Chars<'a>,
     pub(crate) insertions: &'a [(usize, char)],
     inserted: usize,
     position: usize,
@@ -214,6 +215,9 @@
 /// This is a convenience wrapper around `encode`.
 #[inline]
 pub fn encode_str(input: &str) -> Option<String> {
+    if input.len() > u32::MAX as usize {
+        return None;
+    }
     let mut buf = String::with_capacity(input.len());
     encode_into(input.chars(), &mut buf).ok().map(|()| buf)
 }
@@ -223,6 +227,9 @@
 /// Return None on overflow, which can only happen on inputs that would take more than
 /// 63 encoded bytes, the DNS limit on domain name labels.
 pub fn encode(input: &[char]) -> Option<String> {
+    if input.len() > u32::MAX as usize {
+        return None;
+    }
     let mut buf = String::with_capacity(input.len());
     encode_into(input.iter().copied(), &mut buf)
         .ok()
@@ -234,9 +241,9 @@
     I: Iterator<Item = char> + Clone,
 {
     // Handle "basic" (ASCII) code points. They are encoded as-is.
-    let (mut input_length, mut basic_length) = (0, 0);
+    let (mut input_length, mut basic_length) = (0u32, 0);
     for c in input.clone() {
-        input_length += 1;
+        input_length = input_length.checked_add(1).ok_or(())?;
         if c.is_ascii() {
             output.push(c);
             basic_length += 1;
@@ -268,10 +275,7 @@
         for c in input.clone() {
             let c = c as u32;
             if c < code_point {
-                delta += 1;
-                if delta == 0 {
-                    return Err(()); // Overflow
-                }
+                delta = delta.checked_add(1).ok_or(())?;
             }
             if c == code_point {
                 // Represent delta as a generalized variable-length integer:
@@ -313,3 +317,12 @@
         _ => panic!(),
     }
 }
+
+#[test]
+#[ignore = "slow"]
+#[cfg(target_pointer_width = "64")]
+fn huge_encode() {
+    let mut buf = String::new();
+    assert!(encode_into(std::iter::repeat('ß').take(u32::MAX as usize + 1), &mut buf).is_err());
+    assert_eq!(buf.len(), 0);
+}
diff --git a/src/uts46.rs b/src/uts46.rs
index ec2fd0b..b082416 100644
--- a/src/uts46.rs
+++ b/src/uts46.rs
@@ -11,7 +11,9 @@
 
 use self::Mapping::*;
 use crate::punycode;
-use std::{error::Error as StdError, fmt};
+
+use alloc::string::String;
+use core::fmt;
 use unicode_bidi::{bidi_class, BidiClass};
 use unicode_normalization::char::is_combining_mark;
 use unicode_normalization::{is_nfc, UnicodeNormalization};
@@ -70,10 +72,10 @@
 }
 
 struct Mapper<'a> {
-    chars: std::str::Chars<'a>,
+    chars: core::str::Chars<'a>,
     config: Config,
     errors: &'a mut Errors,
-    slice: Option<std::str::Chars<'static>>,
+    slice: Option<core::str::Chars<'static>>,
 }
 
 impl<'a> Iterator for Mapper<'a> {
@@ -274,7 +276,7 @@
 /// http://www.unicode.org/reports/tr46/#Validity_Criteria
 fn check_validity(label: &str, config: Config, errors: &mut Errors) {
     let first_char = label.chars().next();
-    if first_char == None {
+    if first_char.is_none() {
         // Empty string, pass
         return;
     }
@@ -451,7 +453,7 @@
             return Errors::default();
         }
         let mut errors = processing(domain, self.config, &mut self.normalized, out);
-        self.output = std::mem::replace(out, String::with_capacity(out.len()));
+        self.output = core::mem::replace(out, String::with_capacity(out.len()));
         let mut first = true;
         for label in self.output.split('.') {
             if !first {
@@ -475,7 +477,7 @@
 
     /// http://www.unicode.org/reports/tr46/#ToASCII
     #[allow(clippy::wrong_self_convention)]
-    pub fn to_ascii<'a>(&'a mut self, domain: &str, out: &mut String) -> Result<(), Errors> {
+    pub fn to_ascii(&mut self, domain: &str, out: &mut String) -> Result<(), Errors> {
         let mut errors = self.to_ascii_inner(domain, out);
 
         if self.config.verify_dns_length {
@@ -497,7 +499,7 @@
 
     /// http://www.unicode.org/reports/tr46/#ToUnicode
     #[allow(clippy::wrong_self_convention)]
-    pub fn to_unicode<'a>(&'a mut self, domain: &str, out: &mut String) -> Result<(), Errors> {
+    pub fn to_unicode(&mut self, domain: &str, out: &mut String) -> Result<(), Errors> {
         if is_simple(domain) {
             out.push_str(domain);
             return Errors::default().into();
@@ -507,6 +509,7 @@
 }
 
 #[derive(Clone, Copy)]
+#[must_use]
 pub struct Config {
     use_std3_ascii_rules: bool,
     transitional_processing: bool,
@@ -685,7 +688,7 @@
                 if !empty {
                     f.write_str(", ")?;
                 }
-                f.write_str(*name)?;
+                f.write_str(name)?;
                 empty = false;
             }
         }
@@ -708,7 +711,8 @@
     }
 }
 
-impl StdError for Errors {}
+#[cfg(feature = "std")]
+impl std::error::Error for Errors {}
 
 impl fmt::Display for Errors {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {