summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Vander Stoep <jeffv@google.com>2021-02-19 15:23:15 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-02-19 15:23:15 +0000
commit551b605d2d101bb0f6d35b36b8f966cc16acfa27 (patch)
treeaf9885dea5f3f7e7a85c7474e48919cdaa820f1a
parentede645d7a2613ba8b7a35c6acd65587299fa6bbf (diff)
parentf39c48adc31772479f1d36fb23eed914afd2cc59 (diff)
downloadform_urlencoded-551b605d2d101bb0f6d35b36b8f966cc16acfa27.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: I6c4b5dc455028ed1b0d1aa319f99eba458b8ccb7
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp41
-rw-r--r--Cargo.toml3
-rw-r--r--Cargo.toml.orig3
-rw-r--r--METADATA10
-rw-r--r--TEST_MAPPING17
-rw-r--r--src/lib.rs117
-rw-r--r--src/query_encoding.rs35
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"
}
}
diff --git a/Android.bp b/Android.bp
index 3212c1e..e9a461b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -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",
diff --git a/Cargo.toml b/Cargo.toml
index cbbcc11..4c9fae2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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
diff --git a/METADATA b/METADATA
index ff04fe4..cffa7b4 100644
--- a/METADATA
+++ b/METADATA
@@ -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"
+ }
+ ]
+}
diff --git a/src/lib.rs b/src/lib.rs
index e1cf571..765ee16 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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()
- }
- }
-}