Bug 1661961 - Upgrade cstr to 0.2.x. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D98839
This commit is contained in:
Xidorn Quan 2020-12-07 08:01:04 +00:00
parent d88071abc9
commit 8799a09b16
45 changed files with 472 additions and 504 deletions

24
Cargo.lock generated
View File

@ -939,22 +939,12 @@ dependencies = [
[[package]]
name = "cstr"
version = "0.1.3"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6557bdb1dc9647eae1cf7f5601b14cd45fc3c7ccf2df618387416fe542da6ea"
checksum = "c11a39d776a3b35896711da8a04dc1835169dcd36f710878187637314e47941b"
dependencies = [
"cstr-macros",
"procedural-masquerade",
]
[[package]]
name = "cstr-macros"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd670e5ff58768ef624207fb95709ce63b8d05573fb9a05165f0eef471ea6a3a"
dependencies = [
"procedural-masquerade",
"syn",
"proc-macro2",
"quote",
]
[[package]]
@ -3932,12 +3922,6 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "procedural-masquerade"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
[[package]]
name = "processtools"
version = "0.1.0"

View File

@ -258,22 +258,12 @@ dependencies = [
[[package]]
name = "cstr"
version = "0.1.7"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19f7a08ed4ecd7e077d4cee63937473e6f7cf57b702a9114ef41751b2cbc0f60"
checksum = "c11a39d776a3b35896711da8a04dc1835169dcd36f710878187637314e47941b"
dependencies = [
"cstr-macros",
"procedural-masquerade",
]
[[package]]
name = "cstr-macros"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd670e5ff58768ef624207fb95709ce63b8d05573fb9a05165f0eef471ea6a3a"
dependencies = [
"procedural-masquerade",
"syn",
"proc-macro2",
"quote",
]
[[package]]
@ -834,12 +824,6 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "procedural-masquerade"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a1574a51c3fd37b26d2c0032b649d08a7d51d4cca9c41bbc5bf7118fa4509d0"
[[package]]
name = "quote"
version = "1.0.4"

26
gfx/wr/Cargo.lock generated
View File

@ -419,20 +419,11 @@ dependencies = [
[[package]]
name = "cstr"
version = "0.1.7"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cstr-macros 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cstr-macros"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1216,11 +1207,6 @@ dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "procedural-masquerade"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quick-error"
version = "1.2.3"
@ -1800,7 +1786,7 @@ dependencies = [
"core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 19.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cstr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_more 0.99.5 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2095,8 +2081,7 @@ dependencies = [
"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
"checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
"checksum cstr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "19f7a08ed4ecd7e077d4cee63937473e6f7cf57b702a9114ef41751b2cbc0f60"
"checksum cstr-macros 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "cd670e5ff58768ef624207fb95709ce63b8d05573fb9a05165f0eef471ea6a3a"
"checksum cstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c11a39d776a3b35896711da8a04dc1835169dcd36f710878187637314e47941b"
"checksum deflate 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e7e5d2a2273fed52a7f947ee55b092c4057025d7a3e04e5ecdbd25d6c3fb1bd7"
"checksum derive_more 0.99.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2323f3f47db9a0e77ce7a300605d8d2098597fc451ed1a97bb1f6411bb550a7"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
@ -2185,7 +2170,6 @@ dependencies = [
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
"checksum procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9a1574a51c3fd37b26d2c0032b649d08a7d51d4cca9c41bbc5bf7118fa4509d0"
"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"

View File

@ -31,7 +31,7 @@ bincode = "1.0"
bitflags = "1.2"
byteorder = "1.0"
cfg-if = "0.1.2"
cstr = "0.1.2"
cstr = "0.2"
euclid = { version = "0.22.0", features = ["serde"] }
fxhash = "0.2.1"
gleam = "0.13.1"

View File

@ -7,7 +7,7 @@ authors = ["Dana Keeler <dkeeler@mozilla.com>", "Mark Goodwin <mgoodwin@mozilla.
base64 = "0.10"
byteorder = "1.2.7"
crossbeam-utils = "0.6.3"
cstr = "0.1"
cstr = "0.2"
log = "0.4"
memmap = "0.7"
moz_task = { path = "../../../../xpcom/rust/moz_task" }

View File

@ -7,7 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cstr = "0.1"
cstr = "0.2"
golden_gate = { path = "../../../services/sync/golden_gate" }
log = "0.4"
once_cell = "1.4.0"

View File

@ -8,7 +8,7 @@ edition = "2018"
[dependencies]
atomic_refcell = "0.1"
cstr = "0.1"
cstr = "0.2"
libc = "0.2"
once_cell = "1"
paste = "0.1"

View File

@ -7,7 +7,7 @@ edition = "2018"
[dependencies]
atomic_refcell = "0.1"
cstr = "0.1"
cstr = "0.2"
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "8a576fbe79199fa8664f64285524017f74ebcc5f" }
log = "0.4"
moz_task = { path = "../../../xpcom/rust/moz_task" }

View File

@ -17,7 +17,7 @@ gecko_refcount_logging = ["style/gecko_refcount_logging", "servo_arc/gecko_refco
atomic_refcell = "0.1"
bincode = "1.0"
cssparser = "0.28"
cstr = "0.1.2"
cstr = "0.2"
libc = "0.2"
log = {version = "0.4", features = ["release_max_level_info"]}
malloc_size_of = {path = "../../components/malloc_size_of"}

View File

@ -12,7 +12,7 @@ doctest = false
[dependencies]
atomic_refcell = "0.1"
cssparser = "0.28"
cstr = "0.1.2"
cstr = "0.2"
env_logger = { version = "0.8", default-features = false }
geckoservo = {path = "../../../ports/geckolib"}
libc = "0.2"

View File

@ -1 +0,0 @@
{"files":{"Cargo.toml":"5637fc23a942454c72de3d59d855a2bbc72d1ea1e837cbc3bf67044e3c391fc5","LICENSE":"2c6fc9268c3b765da5bf34fe4909425437f61be05674c2516c7f8cf1251c20aa","src/lib.rs":"b1de1d679338b008dd22e4aea5384f89d7a9424d65102b4fa536d8d9eaa56e22"},"package":"cd670e5ff58768ef624207fb95709ce63b8d05573fb9a05165f0eef471ea6a3a"}

View File

@ -1,31 +0,0 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "cstr-macros"
version = "0.1.6"
authors = ["Xidorn Quan <me@upsuper.org>"]
description = "Procedural macros for cstr"
license = "MIT"
repository = "https://github.com/upsuper/cstr"
[lib]
proc-macro = true
[dependencies.procedural-masquerade]
version = "0.1"
[dependencies.syn]
version = "1"
features = ["derive", "parsing"]
default-features = false
[dev-dependencies.quote]
version = "1"

View File

@ -1,25 +0,0 @@
Copyright (c) 2018 Xidorn Quan
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -1,72 +0,0 @@
#[macro_use]
extern crate procedural_masquerade;
extern crate proc_macro;
#[cfg(test)]
#[macro_use]
extern crate quote;
extern crate syn;
use std::ascii::escape_default;
use std::ffi::CString;
define_proc_macros! {
#[allow(non_snake_case)]
pub fn cstr_internal__build_bytes(input: &str) -> String {
let bytes = build_bytes(input);
format!("const BYTES: &'static [u8] = {};", bytes)
}
}
fn input_to_string(input: &str) -> String {
if let Ok(s) = syn::parse_str::<syn::LitStr>(input) {
return s.value();
}
if let Ok(i) = syn::parse_str::<syn::Ident>(input) {
return i.to_string();
}
panic!("expected a string literal or an identifier, got {}", input)
}
fn build_bytes(input: &str) -> String {
let s = input_to_string(input);
let cstr = match CString::new(s.as_bytes()) {
Ok(s) => s,
_ => panic!("literal must not contain NUL byte")
};
let mut bytes = Vec::new();
bytes.extend(br#"b""#);
bytes.extend(cstr.as_bytes().iter().flat_map(|&b| escape_default(b)));
bytes.extend(br#"\0""#);
String::from_utf8(bytes).unwrap()
}
#[cfg(test)]
mod tests {
use super::build_bytes;
macro_rules! build_bytes {
($($t:tt)*) => {
build_bytes(&quote!($($t)*).to_string())
}
}
macro_rules! result {
($($t:tt)*) => {
quote!($($t)*).to_string()
}
}
#[test]
fn test_build_bytes() {
assert_eq!(build_bytes!("aaa"), result!(b"aaa\0"));
assert_eq!(build_bytes!("\t\n\r\"\\'"), result!(b"\t\n\r\"\\\'\0"));
assert_eq!(build_bytes!("\x01\x02 \x7f"), result!(b"\x01\x02 \x7f\0"));
assert_eq!(build_bytes!("你好"), result!(b"\xe4\xbd\xa0\xe5\xa5\xbd\0"));
assert_eq!(build_bytes!(foobar), result!(b"foobar\0"));
}
#[test]
#[should_panic]
fn test_build_bytes_nul_inside() {
build_bytes!("a\x00a");
}
}

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"6906aff00530782954ae2e4ef4a64cf7fc0b6ddbe4557464815921bd4b966d17","LICENSE":"2c6fc9268c3b765da5bf34fe4909425437f61be05674c2516c7f8cf1251c20aa","src/lib.rs":"01e21fd1789ccbaab8d4d46cfcfc4b1997ffae3598cb83db0852f613b93f17b1"},"package":"b6557bdb1dc9647eae1cf7f5601b14cd45fc3c7ccf2df618387416fe542da6ea"}
{"files":{"Cargo.toml":"a9eadcc48a51c9399980e7d0860b668a1277940899a5da781fcbfbc0a9db2660","LICENSE":"5a9bf0e7661617253ca7c12313f51a96aa62dec0bcd15a59c533c88b8093d124","README.md":"555193ce26ab91766d36d9d824ebae66cf18259e8dc37633d98cfa0cec7ce869","src/lib.rs":"2e8f10e1a260a1121cd87190dc67d5ff204258dd1740d64d891524d52424af05","src/parse.rs":"8eb3a7975a2ca73ca16fd3552d3874d04fea0c59a0c45f88194df486b5b2443f","tests/clippy_lints.rs":"4398124cd5bc3a7f295f6203d543fc7d99abfd945eb7418ccfa60535586d7e37","tests/compile_fail/empty.rs":"52dc3c0d4d6ee0bd6d89a34d1caf38d159830401f24ba30f5655f9de92697903","tests/compile_fail/empty.stderr":"c839ce87d482a1e65a668e5267067dd1bd310f60256a795fa8f080888a5c249b","tests/compile_fail/interior-nul.rs":"ecc09440020287377ca18e4b8308d1d516620a87612a5381bafc01fe48734d34","tests/compile_fail/interior-nul.stderr":"8bd003a7dfff248411403bdf666f8a0631307f468d589cf01e475b062db4b101","tests/compile_fail/non-str.rs":"e08be18a524a4482fb7f34cbc6e8448a878b41cf2c26dea99268aaabab6c3f3f","tests/compile_fail/non-str.stderr":"8dff245264d9c69dc151f742542a72400d7422f2a0f2b133a9f4d4fc96a4016a","tests/compile_fail/trash-after.rs":"7dff7a301c9087984c5acda183e34492f3d0f2ebec14b8dc0d2b11aab972a111","tests/compile_fail/trash-after.stderr":"487b5d6b687c52b80f9d9cba691a8654067a88f7d03d2d952d7e97d610ab70f3","tests/compile_test.rs":"13e3e0d22ec0dffa4d0be0c4db6381a03feff50cc25aa65c4950cc7e865d122d","tests/pass/byte_str_lit.rs":"9085e1f1e67dae193d33ff59c253cac23c9e23e9d8c7f92f0aba99097ade132e","tests/pass/const.rs":"777aeb93c3030349529a41ac62b3577b36badc4bada4ec46e45b5055d3676dbd","tests/pass/ident.rs":"5116ee71578d479d899345e039e5955b5dee442234dc504e1a9bfb9260cf8f15","tests/pass/macro.rs":"9596c936ed4d963fb40459ecd98b60610d3d90e41918f350ff45b6129b1aa0b7","tests/pass/str_lit.rs":"955fb887ebc01538bafe10fa810381eb53aebaafb8b36053e8712c081862fe7a"},"package":"c11a39d776a3b35896711da8a04dc1835169dcd36f710878187637314e47941b"}

View File

@ -3,7 +3,7 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
@ -11,15 +11,25 @@
# will likely look very different (and much more reasonable)
[package]
edition = "2018"
name = "cstr"
version = "0.1.3"
version = "0.2.8"
authors = ["Xidorn Quan <me@upsuper.org>"]
description = "Macro for building static CStr reference"
readme = "README.md"
keywords = ["macro", "cstr"]
license = "MIT"
repository = "https://github.com/upsuper/cstr"
[dependencies.cstr-macros]
version = "0.1.2"
[dependencies.procedural-masquerade]
version = "0.1"
[lib]
proc-macro = true
[dependencies.proc-macro2]
version = "1"
[dependencies.quote]
version = "1"
[dev-dependencies.trybuild]
version = "1.0.30"
[badges.travis-ci]
branch = "master"
repository = "upsuper/cstr"

View File

@ -1,4 +1,4 @@
Copyright (c) 2018 Xidorn Quan
Copyright (c) 2018-2020 Xidorn Quan
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated

30
third_party/rust/cstr/README.md vendored Normal file
View File

@ -0,0 +1,30 @@
# cstr
[![CI](https://github.com/upsuper/cstr/workflows/CI/badge.svg)](https://github.com/upsuper/cstr/actions)
[![Crates.io](https://img.shields.io/crates/v/cstr.svg)](https://crates.io/crates/cstr)
[![Docs](https://docs.rs/cstr/badge.svg)](https://docs.rs/cstr)
<!-- cargo-sync-readme start -->
A macro for getting `&'static CStr` from literal or identifier.
This macro checks whether the given literal is valid for `CStr`
at compile time, and returns a static reference of `CStr`.
This macro can be used to to initialize constants on Rust 1.46 and above.
## Example
```rust
use cstr::cstr;
use std::ffi::CStr;
let test = cstr!(b"hello\xff");
assert_eq!(test, CStr::from_bytes_with_nul(b"hello\xff\0").unwrap());
let test = cstr!("hello");
assert_eq!(test, CStr::from_bytes_with_nul(b"hello\0").unwrap());
let test = cstr!(hello);
assert_eq!(test, CStr::from_bytes_with_nul(b"hello\0").unwrap());
```
<!-- cargo-sync-readme end -->

View File

@ -1,48 +1,65 @@
//! A macro for getting `&'static CStr` from literal.
//! A macro for getting `&'static CStr` from literal or identifier.
//!
//! This macro checks whether the given literal is valid for `CStr`
//! at compile time, and returns a static reference of `CStr`.
//!
//! Note that it currently cannot be used to initialize constants due
//! to restriction of Rust.
//! This macro can be used to to initialize constants on Rust 1.46 and above.
//!
//! Also, it currently only supports a UTF-8 string as input because
//! Rust's tokenizer only accepts that without the `b` prefix. This
//! may be expanded in the future if necessary.
//!
//! # Example
//! ## Example
//!
//! ```
//! #[macro_use] extern crate cstr;
//! use cstr::cstr;
//! use std::ffi::CStr;
//!
//! # fn main() {
//! let test = cstr!(b"hello\xff");
//! assert_eq!(test, CStr::from_bytes_with_nul(b"hello\xff\0").unwrap());
//! let test = cstr!("hello");
//! assert_eq!(test, CStr::from_bytes_with_nul(b"hello\0").unwrap());
//! # }
//! let test = cstr!(hello);
//! assert_eq!(test, CStr::from_bytes_with_nul(b"hello\0").unwrap());
//! ```
#[allow(unused_imports)]
#[macro_use]
extern crate cstr_macros;
#[macro_use]
extern crate procedural_masquerade;
// While this isn't necessary when using Cargo >= 1.42, omitting it actually requires path-less
// `--extern proc_macro` to be passed to `rustc` when building this crate. Some tools may not do
// this correctly. So it's added as a precaution.
extern crate proc_macro;
#[doc(hidden)]
pub use cstr_macros::*;
use crate::parse::parse_input;
use proc_macro::TokenStream as RawTokenStream;
use proc_macro2::{Literal, Span, TokenStream};
use quote::{quote, quote_spanned};
use std::ffi::CString;
define_invoke_proc_macro!(cstr__invoke_build_bytes);
mod parse;
#[macro_export]
macro_rules! cstr {
($t: tt) => {
{
cstr__invoke_build_bytes! {
cstr_internal__build_bytes!($t)
}
unsafe {
::std::ffi::CStr::from_bytes_with_nul_unchecked(BYTES)
}
struct Error(Span, &'static str);
#[proc_macro]
pub fn cstr(input: RawTokenStream) -> RawTokenStream {
let tokens = match build_byte_str(input.into()) {
// We can't use `&*ptr` to convert the raw pointer to reference, because as of Rust 1.46,
// dereferencing raw pointer in constants is unstable.
// This is being tracked in https://github.com/rust-lang/rust/issues/51911
// So we explicitly disable the clippy lint for this expression.
Ok(s) => quote!(unsafe {
#[allow(clippy::transmute_ptr_to_ref)]
::std::mem::transmute::<_, &::std::ffi::CStr>(
#s as *const [u8] as *const ::std::ffi::CStr
)
}),
Err(Error(span, msg)) => quote_spanned!(span => compile_error!(#msg)),
};
tokens.into()
}
fn build_byte_str(input: TokenStream) -> Result<Literal, Error> {
let (bytes, span) = parse_input(input)?;
match CString::new(bytes) {
Ok(s) => {
let mut lit = Literal::byte_string(s.as_bytes_with_nul());
lit.set_span(span);
Ok(lit)
}
Err(_) => Err(Error(span, "nul byte found in the literal")),
}
}

225
third_party/rust/cstr/src/parse.rs vendored Normal file
View File

@ -0,0 +1,225 @@
use crate::Error;
use proc_macro2::{Delimiter, Ident, Literal, Span, TokenStream, TokenTree};
use std::char;
macro_rules! unexpected_content {
() => {
"expected one of: byte string literal, string literal, identifier"
};
}
pub(crate) fn parse_input(mut input: TokenStream) -> Result<(Vec<u8>, Span), Error> {
loop {
let mut tokens = input.into_iter();
let token = match tokens.next() {
Some(token) => token,
None => {
return Err(Error(
Span::call_site(),
concat!("unexpected end of input, ", unexpected_content!()),
))
}
};
let span = token.span();
let result = match token {
// Unwrap any empty group which may be created from macro expansion.
TokenTree::Group(group) if group.delimiter() == Delimiter::None => Err(group),
TokenTree::Literal(literal) => match parse_literal(literal) {
Ok(result) => Ok(result),
Err(msg) => return Err(Error(span, msg)),
},
TokenTree::Ident(ident) => Ok(parse_ident(ident)),
_ => return Err(Error(span, unexpected_content!())),
};
if let Some(token) = tokens.next() {
return Err(Error(token.span(), "unexpected token"));
}
match result {
Ok(result) => return Ok((result, span)),
Err(group) => input = group.stream(),
}
}
}
fn parse_literal(literal: Literal) -> Result<Vec<u8>, &'static str> {
let s = literal.to_string();
let s = s.as_bytes();
match s[0] {
b'"' => Ok(parse_cooked_content(&s)),
b'r' => Ok(parse_raw_content(&s[1..])),
b'b' => match s[1] {
b'"' => Ok(parse_cooked_content(&s[1..])),
b'r' => Ok(parse_raw_content(&s[2..])),
_ => Err(unexpected_content!()),
},
_ => Err(unexpected_content!()),
}
}
fn all_pounds(bytes: &[u8]) -> bool {
bytes.iter().all(|b| *b == b'#')
}
/// Parses raw string / bytes content after `r` prefix.
fn parse_raw_content(s: &[u8]) -> Vec<u8> {
let q_start = s.iter().position(|b| *b == b'"').unwrap();
let q_end = s.iter().rposition(|b| *b == b'"').unwrap();
assert!(all_pounds(&s[0..q_start]));
assert!(all_pounds(&s[q_end + 1..q_end + q_start + 1]));
Vec::from(&s[q_start + 1..q_end])
}
/// Parses the cooked string / bytes content within quotes.
fn parse_cooked_content(mut s: &[u8]) -> Vec<u8> {
s = &s[1..s.iter().rposition(|b| *b == b'"').unwrap()];
let mut result = Vec::new();
while !s.is_empty() {
match s[0] {
b'\\' => {}
b'\r' => {
assert_eq!(s[1], b'\n');
result.push(b'\n');
s = &s[2..];
continue;
}
b => {
result.push(b);
s = &s[1..];
continue;
}
}
let b = s[1];
s = &s[2..];
match b {
b'x' => {
let (b, rest) = backslash_x(&s);
result.push(b);
s = rest;
}
b'u' => {
let (c, rest) = backslash_u(&s);
result.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes());
s = rest;
}
b'n' => result.push(b'\n'),
b'r' => result.push(b'\r'),
b't' => result.push(b'\t'),
b'\\' => result.push(b'\\'),
b'0' => result.push(b'\0'),
b'\'' => result.push(b'\''),
b'"' => result.push(b'"'),
b'\r' | b'\n' => {
let next = s.iter().position(|b| {
let ch = char::from_u32(u32::from(*b)).unwrap();
!ch.is_whitespace()
});
match next {
Some(pos) => s = &s[pos..],
None => s = b"",
}
}
b => panic!("unexpected byte {:?} after \\", b),
}
}
result
}
fn backslash_x(s: &[u8]) -> (u8, &[u8]) {
let ch = hex_to_u8(s[0]) * 0x10 + hex_to_u8(s[1]);
(ch, &s[2..])
}
fn hex_to_u8(b: u8) -> u8 {
match b {
b'0'..=b'9' => b - b'0',
b'a'..=b'f' => b - b'a' + 10,
b'A'..=b'F' => b - b'A' + 10,
_ => unreachable!("unexpected non-hex character {:?} after \\x", b),
}
}
fn backslash_u(s: &[u8]) -> (char, &[u8]) {
assert_eq!(s[0], b'{');
let end = s[1..].iter().position(|b| *b == b'}').unwrap();
let mut ch = 0;
for b in &s[1..=end] {
ch *= 0x10;
ch += u32::from(hex_to_u8(*b));
}
(char::from_u32(ch).unwrap(), &s[end + 2..])
}
fn parse_ident(ident: Ident) -> Vec<u8> {
ident.to_string().into_bytes()
}
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;
// Tests below were modified from
// https://github.com/dtolnay/syn/blob/cd5fdc0f530f822446fccaf831669cd0cf4a0fc9/tests/test_lit.rs
fn lit(s: &str) -> Vec<u8> {
match TokenStream::from_str(s)
.unwrap()
.into_iter()
.next()
.unwrap()
{
TokenTree::Literal(lit) => parse_literal(lit).unwrap(),
_ => panic!(),
}
}
#[test]
fn strings() {
#[track_caller]
fn test_string(s: &str, value: &[u8]) {
assert_eq!(lit(s), value);
}
test_string("\"a\"", b"a");
test_string("\"\\n\"", b"\n");
test_string("\"\\r\"", b"\r");
test_string("\"\\t\"", b"\t");
test_string("\"🐕\"", b"\xf0\x9f\x90\x95"); // NOTE: This is an emoji
test_string("\"\\\"\"", b"\"");
test_string("\"'\"", b"'");
test_string("\"\"", b"");
test_string("\"\\u{1F415}\"", b"\xf0\x9f\x90\x95");
test_string(
"\"contains\nnewlines\\\nescaped newlines\"",
b"contains\nnewlinesescaped newlines",
);
test_string("r\"raw\nstring\\\nhere\"", b"raw\nstring\\\nhere");
test_string("\"...\"q", b"...");
test_string("r\"...\"q", b"...");
test_string("r##\"...\"##q", b"...");
}
#[test]
fn byte_strings() {
#[track_caller]
fn test_byte_string(s: &str, value: &[u8]) {
assert_eq!(lit(s), value);
}
test_byte_string("b\"a\"", b"a");
test_byte_string("b\"\\n\"", b"\n");
test_byte_string("b\"\\r\"", b"\r");
test_byte_string("b\"\\t\"", b"\t");
test_byte_string("b\"\\\"\"", b"\"");
test_byte_string("b\"'\"", b"'");
test_byte_string("b\"\"", b"");
test_byte_string(
"b\"contains\nnewlines\\\nescaped newlines\"",
b"contains\nnewlinesescaped newlines",
);
test_byte_string("br\"raw\nstring\\\nhere\"", b"raw\nstring\\\nhere");
test_byte_string("b\"...\"q", b"...");
test_byte_string("br\"...\"q", b"...");
test_byte_string("br##\"...\"##q", b"...");
}
}

View File

@ -0,0 +1,10 @@
use cstr::cstr;
use std::ffi::CStr;
#[test]
#[deny(clippy::transmute_ptr_to_ref)]
fn deny_transmute_ptr_to_ref() {
let s: &'static CStr = cstr!("foo\u{4e00}bar");
let expected = b"foo\xe4\xb8\x80bar\0";
assert_eq!(s, CStr::from_bytes_with_nul(expected).unwrap());
}

View File

@ -0,0 +1,5 @@
use cstr::cstr;
fn main() {
let _foo = cstr!();
}

View File

@ -0,0 +1,7 @@
error: unexpected end of input, expected one of: byte string literal, string literal, identifier
--> $DIR/empty.rs:4:16
|
4 | let _foo = cstr!();
| ^^^^^^^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@ -0,0 +1,5 @@
use cstr::cstr;
fn main() {
let _foo = cstr!("foo\0bar");
}

View File

@ -0,0 +1,5 @@
error: nul byte found in the literal
--> $DIR/interior-nul.rs:4:22
|
4 | let _foo = cstr!("foo\0bar");
| ^^^^^^^^^^

View File

@ -0,0 +1,7 @@
use cstr::cstr;
fn main() {
let _foo = cstr!(1);
let _foo = cstr!(("a"));
let _foo = cstr!(&1);
}

View File

@ -0,0 +1,17 @@
error: expected one of: byte string literal, string literal, identifier
--> $DIR/non-str.rs:4:22
|
4 | let _foo = cstr!(1);
| ^
error: expected one of: byte string literal, string literal, identifier
--> $DIR/non-str.rs:5:22
|
5 | let _foo = cstr!(("a"));
| ^^^^^
error: expected one of: byte string literal, string literal, identifier
--> $DIR/non-str.rs:6:22
|
6 | let _foo = cstr!(&1);
| ^

View File

@ -0,0 +1,5 @@
use cstr::cstr;
fn main() {
let _foo = cstr!("foo" + "bar");
}

View File

@ -0,0 +1,5 @@
error: unexpected token
--> $DIR/trash-after.rs:4:28
|
4 | let _foo = cstr!("foo" + "bar");
| ^

View File

@ -0,0 +1,6 @@
#[test]
fn compile_test() {
let t = trybuild::TestCases::new();
t.pass("tests/pass/*.rs");
t.compile_fail("tests/compile_fail/*.rs");
}

View File

@ -0,0 +1,7 @@
use cstr::cstr;
use std::ffi::CStr;
fn main() {
let foo: &'static CStr = cstr!(b"foo\xffbar");
assert_eq!(foo, CStr::from_bytes_with_nul(b"foo\xffbar\0").unwrap());
}

View File

@ -0,0 +1,10 @@
use cstr::cstr;
use std::ffi::CStr;
const FOO: &CStr = cstr!(b"foo\xffbar");
static BAR: &CStr = cstr!("bar");
fn main() {
assert_eq!(FOO, CStr::from_bytes_with_nul(b"foo\xffbar\0").unwrap());
assert_eq!(BAR, CStr::from_bytes_with_nul(b"bar\0").unwrap());
}

View File

@ -0,0 +1,9 @@
use cstr::cstr;
use std::ffi::CStr;
fn main() {
let foo: &'static CStr = cstr!(foobar);
assert_eq!(foo, CStr::from_bytes_with_nul(b"foobar\0").unwrap());
let foo: &'static CStr = cstr!(r#foobar);
assert_eq!(foo, CStr::from_bytes_with_nul(b"r#foobar\0").unwrap());
}

View File

@ -0,0 +1,21 @@
use cstr::cstr;
use std::ffi::CStr;
macro_rules! cstr_expr {
($s:expr) => {
cstr!($s)
};
}
macro_rules! cstr_literal {
($s:literal) => {
cstr!($s)
};
}
fn main() {
let foo: &'static CStr = cstr_expr!("foo");
assert_eq!(foo, CStr::from_bytes_with_nul(b"foo\0").unwrap());
let bar: &'static CStr = cstr_literal!("bar");
assert_eq!(bar, CStr::from_bytes_with_nul(b"bar\0").unwrap());
}

View File

@ -0,0 +1,8 @@
use cstr::cstr;
use std::ffi::CStr;
fn main() {
let foo: &'static CStr = cstr!("foo\u{4e00}bar");
let expected = b"foo\xe4\xb8\x80bar\0";
assert_eq!(foo, CStr::from_bytes_with_nul(expected).unwrap());
}

View File

@ -1 +0,0 @@
{"files":{"Cargo.toml":"3aad5ce464f7224e4b86fc0a70d89c354635ed624bf4bb12cf4ca597c45879b7","lib.rs":"f0f2793a21bc85ae3ee3e040ef703da87b558a1ce524873ef872bf44de795931"},"package":"9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"}

View File

@ -1,12 +0,0 @@
[package]
name = "procedural-masquerade"
version = "0.1.1"
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
description = "macro_rules for making proc_macro_derive pretending to be proc_macro"
documentation = "https://docs.rs/procedural-masquerade/"
repository = "https://github.com/servo/rust-cssparser"
license = "MIT/Apache-2.0"
[lib]
path = "lib.rs"
doctest = false

View File

@ -1,250 +0,0 @@
//! # Custom `derive` pretending to be functional procedural macros on Rust 1.15
//!
//! This crate enables creating function-like macros (invoked as `foo!(...)`)
//! with a procedural component,
//! based on both custom `derive` (a.k.a. *Macros 1.1*) and `macro_rules!`.
//!
//! This convoluted mechanism enables such macros to run on stable Rust 1.15,
//! even though functional procedural macros (a.k.a. *Macros 2.0*) are not available yet.
//!
//! A library defining such a macro needs two crates: a “normal” one, and a `proc-macro` one.
//! In the example below well call them `libfoo` and `libfoo-macros`, respectively.
//!
//! # Credits
//!
//! The trick that makes this crate work
//! is based on an idea from [David Tolnay](https://github.com/dtolnay).
//! Many thanks!
//!
//! # Example
//!
//! As a simple example, were going to re-implement the `stringify!` macro.
//! This is useless since `stringify!` already exists in the standard library,
//! and a bit absurd since this crate uses `stringify!` internally.
//!
//! Nevertheless, it serves as a simple example to demonstrate the use of this crate.
//!
//! ## The `proc-macro` crate
//!
//! The minimal `Cargo.toml` file is typical for Macros 1.1:
//!
//! ```toml
//! [package]
//! name = "libfoo-macros"
//! version = "1.0.0"
//!
//! [lib]
//! proc-macro = true
//! ```
//!
//! In the code, we define the procedural part of our macro in a function.
//! This function will not be used directly by end users,
//! but it still needs to be re-exported to them
//! (because of limitations in `macro_rules!`).
//!
//! To avoid name collisions, we and a long and explicit prefix in the functions name.
//!
//! The function takes a string containing arbitrary Rust tokens,
//! and returns a string that is parsed as *items*.
//! The returned string can contain constants, statics, functions, `impl`s, etc.,
//! but not expressions directly.
//!
//! ```rust
//! #[macro_use] extern crate procedural_masquerade;
//! extern crate proc_macro;
//!
//! define_proc_macros! {
//! #[allow(non_snake_case)]
//! pub fn foo_internal__stringify_const(input: &str) -> String {
//! format!("const STRINGIFIED: &'static str = {:?};", input)
//! }
//! }
//! ```
//!
//! A less trivial macro would probably use
//! the [`syn`](https://github.com/dtolnay/syn/) crate to parse its input
//! and the [`quote`](https://github.com/dtolnay/quote) crate to generate its output.
//!
//! ## The library crate
//!
//! ```toml
//! [package]
//! name = "libfoo"
//! version = "1.0.0"
//!
//! [dependencies]
//! cssparser-macros = {path = "./macros", version = "1.0"}
//! ```
//!
//! ```rust
//! #[macro_use] extern crate libfoo_macros; // (1)
//!
//! pub use libfoo_macros::*; // (2)
//!
//! define_invoke_proc_macro!(libfoo__invoke_proc_macro); // (3)
//!
//! #[macro_export]
//! macro_rules! foo_stringify { // (4)
//! ( $( $tts: tt ) ) => {
//! { // (5)
//! libfoo__invoke_proc_macro! { // (6)
//! foo_internal__stringify_const!( $( $tts ) ) // (7)
//! }
//! STRINGIFIED // (8)
//! }
//! }
//! }
//! ```
//!
//! Lets go trough the numbered lines one by one:
//!
//! 1. `libfoo` depends on the other `libfoo-macros`, and imports its macros.
//! 2. Everything exported by `libfoo-macros` (which is one custom `derive`)
//! is re-exported to users of `libfoo`.
//! Theyre not expected to use it directly,
//! but expansion of the `foo_stringify` macro needs it.
//! 3. This macro invocation defines yet another macro, called `libfoo__invoke_proc_macro`,
//! which is also exported.
//! This indirection is necessary
//! because re-exporting `macro_rules!` macros doesnt work currently,
//! and once again it is used by the expansion of `foo_stringify`.
//! Again, we use a long prefix to avoid name collisions.
//! 4. Finally, we define the macro that we really want.
//! This one has a name that users will use.
//! 5. The expansion of this macro will define some items,
//! whose names are not hygienic in `macro_rules`.
//! So we wrap everything in an extra `{…}` block to prevent these names for leaking.
//! 6. Here we use the macro defined in (3),
//! which allows us to write something that look like invoking a functional procedural macro,
//! but really uses a custom `derive`.
//! This will define a type called `ProceduralMasqueradeDummyType`,
//! as a placeholder to use `derive`.
//! If `libfoo__invoke_proc_macro!` is to be used more than once,
//! each use needs to be nested in another block
//! so that the names of multiple dummy types dont collide.
//! 7. In addition to the dummy type,
//! the items returned by our procedural component are inserted here.
//! (In this case the `STRINGIFIED` constant.)
//! 8. Finally, we write the expression that we want the macro to evaluate to.
//! This expression can use parts of `foo_stringify`s input,
//! it can contain control-flow statements like `return` or `continue`,
//! and of course refer to procedurally-defined items.
//!
//! This macro can be used in an expression context.
//! It expands to a block-expression that contains some items (as an implementation detail)
//! and ends with another expression.
//!
//! ## For users
//!
//! Users of `libfoo` dont need to worry about any of these implementation details.
//! They can use the `foo_stringify` macro as if it were a simle `macro_rules` macro:
//!
//! ```rust
//! #[macro_use] extern crate libfoo;
//!
//! fn main() {
//! do_something(foo_stringify!(1 + 2));
//! }
//!
//! fn do_something(_: &str) { /* ... */ }
//! ```
//!
//! # More
//!
//! To see a more complex example, look at
//! [`cssparser`s `src/macros.rs](https://github.com/servo/rust-cssparser/blob/master/src/macros.rs)
//! and
//! [`cssparser-macros`s `macros/lib.rs](https://github.com/servo/rust-cssparser/blob/master/macros/lib.rs).
/// This macro wraps `&str -> String` functions
/// in custom `derive` implementations with `#[proc_macro_derive]`.
///
/// See crate documentation for details.
#[macro_export]
macro_rules! define_proc_macros {
(
$(
$( #[$attr:meta] )*
pub fn $proc_macro_name: ident ($input: ident : &str) -> String
$body: block
)+
) => {
$(
$( #[$attr] )*
#[proc_macro_derive($proc_macro_name)]
pub fn $proc_macro_name(derive_input: ::proc_macro::TokenStream)
-> ::proc_macro::TokenStream {
let $input = derive_input.to_string();
let $input = $crate::_extract_input(&$input);
$body.parse().unwrap()
}
)+
}
}
/// Implementation detail of `define_proc_macros!`.
///
/// **This function is not part of the public API. It can change or be removed between any versions.**
#[doc(hidden)]
pub fn _extract_input(derive_input: &str) -> &str {
let mut input = derive_input;
for expected in &["#[allow(unused)]", "enum", "ProceduralMasqueradeDummyType", "{",
"Input", "=", "(0,", "stringify!", "("] {
input = input.trim_left();
assert!(input.starts_with(expected),
"expected prefix {:?} not found in {:?}", expected, derive_input);
input = &input[expected.len()..];
}
for expected in [")", ").0,", "}"].iter().rev() {
input = input.trim_right();
assert!(input.ends_with(expected),
"expected suffix {:?} not found in {:?}", expected, derive_input);
let end = input.len() - expected.len();
input = &input[..end];
}
input
}
/// This macro expands to the definition of another macro (whose name is given as a parameter).
///
/// See crate documentation for details.
#[macro_export]
macro_rules! define_invoke_proc_macro {
($macro_name: ident) => {
/// Implementation detail of other macros in this crate.
#[doc(hidden)]
#[macro_export]
macro_rules! $macro_name {
($proc_macro_name: ident ! $paren: tt) => {
#[derive($proc_macro_name)]
#[allow(unused)]
enum ProceduralMasqueradeDummyType {
// The magic happens here.
//
// We use an `enum` with an explicit discriminant
// because that is the only case where a type definition
// can contain a (const) expression.
//
// `(0, "foo").0` evalutes to 0, with the `"foo"` part ignored.
//
// By the time the `#[proc_macro_derive]` function
// implementing `#[derive($proc_macro_name)]` is called,
// `$paren` has already been replaced with the input of this inner macro,
// but `stringify!` has not been expanded yet.
//
// This how arbitrary tokens can be inserted
// in the input to the `#[proc_macro_derive]` function.
//
// Later, `stringify!(...)` is expanded into a string literal
// which is then ignored.
// Using `stringify!` enables passing arbitrary tokens
// rather than only what can be parsed as a const expression.
Input = (0, stringify! $paren ).0
}
}
}
}
}

View File

@ -7,7 +7,7 @@ edition = "2018"
[dependencies]
atomic_refcell = "0.1"
cstr = "0.1"
cstr = "0.2"
golden_gate = { path = "../../../../../services/sync/golden_gate" }
moz_task = { path = "../../../../../xpcom/rust/moz_task" }
nserror = { path = "../../../../../xpcom/rust/nserror" }

View File

@ -15,7 +15,7 @@ static_prefs = { path = "../../../modules/libpref/init/static_prefs" }
xpcom = { path = "../../../xpcom/rust/xpcom" }
once_cell = "1.2.0"
fog = { path = "./api" }
cstr = "0.1"
cstr = "0.2"
viaduct = { git = "https://github.com/mozilla/application-services", rev = "8a576fbe79199fa8664f64285524017f74ebcc5f" } # Copied from toolkit/library/rust/shared/Cargo.toml
url = "2.1" # Copied from viaduct's deps, see https://github.com/mozilla/application-services/issues/3062

View File

@ -6,7 +6,7 @@ authors = ["Myk Melez <myk@mykzilla.org>"]
[dependencies]
atomic_refcell = "0.1"
crossbeam-utils = "0.6.3"
cstr = "0.1"
cstr = "0.2"
lazy_static = "1"
libc = "0.2"
lmdb-rkv = "0.14"

View File

@ -9,7 +9,7 @@ atomic_refcell = "0.1"
dogear = "0.4.0"
libc = "0.2"
log = "0.4"
cstr = "0.1"
cstr = "0.2"
moz_task = { path = "../../../../xpcom/rust/moz_task" }
nserror = { path = "../../../../xpcom/rust/nserror" }
nsstring = { path = "../../../../xpcom/rust/nsstring" }

View File

@ -6,7 +6,7 @@ license = "MPL-2.0"
[dependencies]
crossbeam-utils = "0.6.3"
cstr = "0.1"
cstr = "0.2"
libc = "0.2"
lmdb-rkv = "0.14"
log = "0.4"

View File

@ -6,7 +6,7 @@ license = "MPL-2.0"
description = "Rust wrappers around XPCOM threading functions"
[dependencies]
cstr = "0.1"
cstr = "0.2"
libc = "0.2"
futures-task = { version = "0.3" }
nserror = { path = "../nserror" }

View File

@ -7,7 +7,6 @@
//! It also provides the Task trait and TaskRunnable struct,
//! which make it easier to dispatch tasks to threads.
#[macro_use]
extern crate cstr;
extern crate futures_task;
extern crate libc;