diff options
author | Jeff Vander Stoep <jeffv@google.com> | 2021-02-19 15:23:06 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-02-19 15:23:06 +0000 |
commit | 4c0731117bc2925a2c7a7323cb67bb8e59a237c5 (patch) | |
tree | af9885dea5f3f7e7a85c7474e48919cdaa820f1a | |
parent | 7e2337a5b9c596ca4c98f1fb287307419e839688 (diff) | |
parent | f39c48adc31772479f1d36fb23eed914afd2cc59 (diff) | |
download | form_urlencoded-4c0731117bc2925a2c7a7323cb67bb8e59a237c5.tar.gz |
Update to 1.0.1 am: 6113c18079 am: 09a022a10c am: b85d306982 am: f39c48adc3
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/form_urlencoded/+/1595312
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I3411f4751ba342dc57e2ad06a301033022839dbb
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Android.bp | 41 | ||||
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | Cargo.toml.orig | 3 | ||||
-rw-r--r-- | METADATA | 10 | ||||
-rw-r--r-- | TEST_MAPPING | 17 | ||||
-rw-r--r-- | src/lib.rs | 117 | ||||
-rw-r--r-- | src/query_encoding.rs | 35 |
8 files changed, 131 insertions, 97 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 0b9773f..cc75365 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "55395ed3099b26a58a82f6fef09e609d52b674b3" + "sha1": "ea7a69e9d69248ca6f69a6294abed225754f92fe" } } @@ -1,50 +1,11 @@ // This file is generated by cargo2android.py --run --device --dependencies --tests --patch=patches/Android.bp.patch. -package { - default_applicable_licenses: [ - "external_rust_crates_form_urlencoded_license", - ], -} - -// Added automatically by a large-scale-change that took the approach of -// 'apply every license found to every target'. While this makes sure we respect -// every license restriction, it may not be entirely correct. -// -// e.g. GPL in an MIT project might only apply to the contrib/ directory. -// -// Please consider splitting the single license below into multiple licenses, -// taking care not to lose any license_kind information, and overriding the -// default license using the 'licenses: [...]' property on targets as needed. -// -// For unused files, consider creating a 'fileGroup' with "//visibility:private" -// to attach the license to, and including a comment whether the files may be -// used in the current project. -// -// large-scale-change included anything that looked like it might be a license -// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc. -// -// Please consider removing redundant or irrelevant files from 'license_text:'. -// See: http://go/android-license-faq -license { - name: "external_rust_crates_form_urlencoded_license", - visibility: [":__subpackages__"], - license_kinds: [ - "SPDX-license-identifier-Apache-2.0", - "SPDX-license-identifier-MIT", - ], - license_text: [ - "LICENSE", - "LICENSE-APACHE", - "LICENSE-MIT", - ], -} - rust_library { name: "libform_urlencoded", host_supported: true, crate_name: "form_urlencoded", srcs: ["src/lib.rs"], - edition: "2015", + edition: "2018", rustlibs: [ "libmatches", "libpercent_encoding", @@ -11,8 +11,9 @@ # will likely look very different (and much more reasonable) [package] +edition = "2018" name = "form_urlencoded" -version = "1.0.0" +version = "1.0.1" authors = ["The rust-url developers"] description = "Parser and serializer for the application/x-www-form-urlencoded syntax, as used by HTML forms." license = "MIT/Apache-2.0" diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 6b0a635..0c603bd 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,10 +1,11 @@ [package] name = "form_urlencoded" -version = "1.0.0" +version = "1.0.1" authors = ["The rust-url developers"] description = "Parser and serializer for the application/x-www-form-urlencoded syntax, as used by HTML forms." repository = "https://github.com/servo/rust-url" license = "MIT/Apache-2.0" +edition = "2018" [lib] test = false @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/form_urlencoded/form_urlencoded-1.0.0.crate" + value: "https://static.crates.io/crates/form_urlencoded/form_urlencoded-1.0.1.crate" } - version: "1.0.0" + version: "1.0.1" license_type: NOTICE last_upgrade_date { - year: 2020 - month: 12 - day: 15 + year: 2021 + month: 2 + day: 19 } } diff --git a/TEST_MAPPING b/TEST_MAPPING new file mode 100644 index 0000000..8f984d7 --- /dev/null +++ b/TEST_MAPPING @@ -0,0 +1,17 @@ +// Generated by update_crate_tests.py for tests that depend on this crate. +{ + "presubmit": [ + { + "name": "url_device_test_src_lib" + }, + { + "name": "quiche_device_test_src_lib" + }, + { + "name": "url_device_test_tests_data" + }, + { + "name": "url_device_test_tests_unit" + } + ] +} @@ -13,19 +13,13 @@ //! Converts between a string (such as an URL’s query string) //! and a sequence of (name, value) pairs. -extern crate percent_encoding; #[macro_use] extern crate matches; use percent_encoding::{percent_decode, percent_encode_byte}; -use query_encoding::decode_utf8_lossy; use std::borrow::{Borrow, Cow}; use std::str; -mod query_encoding; - -pub use query_encoding::EncodingOverride; - /// Convert a byte string in the `application/x-www-form-urlencoded` syntax /// into a iterator of (name, value) pairs. /// @@ -34,7 +28,7 @@ pub use query_encoding::EncodingOverride; /// The names and values are percent-decoded. For instance, `%23first=%25try%25` will be /// converted to `[("#first", "%try%")]`. #[inline] -pub fn parse(input: &[u8]) -> Parse { +pub fn parse(input: &[u8]) -> Parse<'_> { Parse { input } } /// The return type of `parse()`. @@ -65,7 +59,7 @@ impl<'a> Iterator for Parse<'a> { } } -fn decode(input: &[u8]) -> Cow<str> { +fn decode(input: &[u8]) -> Cow<'_, str> { let replaced = replace_plus(input); decode_utf8_lossy(match percent_decode(&replaced).into() { Cow::Owned(vec) => Cow::Owned(vec), @@ -74,7 +68,7 @@ fn decode(input: &[u8]) -> Cow<str> { } /// Replace b'+' with b' ' -fn replace_plus(input: &[u8]) -> Cow<[u8]> { +fn replace_plus(input: &[u8]) -> Cow<'_, [u8]> { match input.iter().position(|&b| b == b'+') { None => Cow::Borrowed(input), Some(first_position) => { @@ -116,7 +110,7 @@ impl<'a> Iterator for ParseIntoOwned<'a> { /// https://url.spec.whatwg.org/#concept-urlencoded-byte-serializer). /// /// Return an iterator of `&str` slices. -pub fn byte_serialize(input: &[u8]) -> ByteSerialize { +pub fn byte_serialize(input: &[u8]) -> ByteSerialize<'_> { ByteSerialize { bytes: input } } @@ -150,6 +144,10 @@ impl<'a> Iterator for ByteSerialize<'a> { None => (self.bytes, &[][..]), }; self.bytes = remaining; + // This unsafe is appropriate because we have already checked these + // bytes in byte_serialized_unchanged, which checks for a subset + // of UTF-8. So we know these bytes are valid UTF-8, and doing + // another UTF-8 check would be wasteful. Some(unsafe { str::from_utf8_unchecked(unchanged_slice) }) } else { None @@ -214,7 +212,14 @@ impl<'a, T: Target> Serializer<'a, T> { /// If that suffix is non-empty, /// its content is assumed to already be in `application/x-www-form-urlencoded` syntax. pub fn for_suffix(mut target: T, start_position: usize) -> Self { - &target.as_mut_string()[start_position..]; // Panic if out of bounds + if target.as_mut_string().len() < start_position { + panic!( + "invalid length {} for target of length {}", + start_position, + target.as_mut_string().len() + ); + } + Serializer { target: Some(target), start_position, @@ -250,6 +255,19 @@ impl<'a, T: Target> Serializer<'a, T> { self } + /// Serialize and append a name of parameter without any value. + /// + /// Panics if called after `.finish()`. + pub fn append_key_only(&mut self, name: &str) -> &mut Self { + append_key_only( + string(&mut self.target), + self.start_position, + self.encoding, + name, + ); + self + } + /// Serialize and append a number of name/value pairs. /// /// This simply calls `append_pair` repeatedly. @@ -280,6 +298,29 @@ impl<'a, T: Target> Serializer<'a, T> { self } + /// Serialize and append a number of names without values. + /// + /// This simply calls `append_key_only` repeatedly. + /// This can be more convenient, so the user doesn’t need to introduce a block + /// to limit the scope of `Serializer`’s borrow of its string. + /// + /// Panics if called after `.finish()`. + pub fn extend_keys_only<I, K>(&mut self, iter: I) -> &mut Self + where + I: IntoIterator, + I::Item: Borrow<K>, + K: AsRef<str>, + { + { + let string = string(&mut self.target); + for key in iter { + let k = key.borrow().as_ref(); + append_key_only(string, self.start_position, self.encoding, k); + } + } + self + } + /// If this serializer was constructed with a string, take and return that string. /// /// ```rust @@ -316,7 +357,7 @@ fn string<T: Target>(target: &mut Option<T>) -> &mut String { fn append_pair( string: &mut String, start_position: usize, - encoding: EncodingOverride, + encoding: EncodingOverride<'_>, name: &str, value: &str, ) { @@ -326,6 +367,54 @@ fn append_pair( append_encoded(value, string, encoding); } -fn append_encoded(s: &str, string: &mut String, encoding: EncodingOverride) { - string.extend(byte_serialize(&query_encoding::encode(encoding, s.into()))) +fn append_key_only( + string: &mut String, + start_position: usize, + encoding: EncodingOverride, + name: &str, +) { + append_separator_if_needed(string, start_position); + append_encoded(name, string, encoding); } + +fn append_encoded(s: &str, string: &mut String, encoding: EncodingOverride<'_>) { + string.extend(byte_serialize(&encode(encoding, s))) +} + +pub(crate) fn encode<'a>(encoding_override: EncodingOverride<'_>, input: &'a str) -> Cow<'a, [u8]> { + if let Some(o) = encoding_override { + return o(input); + } + input.as_bytes().into() +} + +pub(crate) fn decode_utf8_lossy(input: Cow<'_, [u8]>) -> Cow<'_, str> { + // Note: This function is duplicated in `percent_encoding/lib.rs`. + match input { + Cow::Borrowed(bytes) => String::from_utf8_lossy(bytes), + Cow::Owned(bytes) => { + match String::from_utf8_lossy(&bytes) { + Cow::Borrowed(utf8) => { + // If from_utf8_lossy returns a Cow::Borrowed, then we can + // be sure our original bytes were valid UTF-8. This is because + // if the bytes were invalid UTF-8 from_utf8_lossy would have + // to allocate a new owned string to back the Cow so it could + // replace invalid bytes with a placeholder. + + // First we do a debug_assert to confirm our description above. + let raw_utf8: *const [u8]; + raw_utf8 = utf8.as_bytes(); + debug_assert!(raw_utf8 == &*bytes as *const [u8]); + + // Given we know the original input bytes are valid UTF-8, + // and we have ownership of those bytes, we re-use them and + // return a Cow::Owned here. + Cow::Owned(unsafe { String::from_utf8_unchecked(bytes) }) + } + Cow::Owned(s) => Cow::Owned(s), + } + } + } +} + +pub type EncodingOverride<'a> = Option<&'a dyn Fn(&str) -> Cow<'_, [u8]>>; diff --git a/src/query_encoding.rs b/src/query_encoding.rs deleted file mode 100644 index 76aed15..0000000 --- a/src/query_encoding.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2019 The rust-url developers. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::borrow::Cow; - -pub type EncodingOverride<'a> = Option<&'a dyn Fn(&str) -> Cow<[u8]>>; - -pub(crate) fn encode<'a>(encoding_override: EncodingOverride, input: &'a str) -> Cow<'a, [u8]> { - if let Some(o) = encoding_override { - return o(input); - } - input.as_bytes().into() -} - -pub(crate) fn decode_utf8_lossy(input: Cow<[u8]>) -> Cow<str> { - match input { - Cow::Borrowed(bytes) => String::from_utf8_lossy(bytes), - Cow::Owned(bytes) => { - let raw_utf8: *const [u8]; - match String::from_utf8_lossy(&bytes) { - Cow::Borrowed(utf8) => raw_utf8 = utf8.as_bytes(), - Cow::Owned(s) => return s.into(), - } - // from_utf8_lossy returned a borrow of `bytes` unchanged. - debug_assert!(raw_utf8 == &*bytes as *const [u8]); - // Reuse the existing `Vec` allocation. - unsafe { String::from_utf8_unchecked(bytes) }.into() - } - } -} |