Bug 1888683 - Checking in automated code changes. r=janerik,supply-chain-reviewers,glandium

This is the result of running `mach vendor rust`, `mach cargo vet prune` and `mach uniffi generate`

Depends on D206130

Differential Revision: https://phabricator.services.mozilla.com/D206131
This commit is contained in:
Ben Dean-Kawamura 2024-04-09 20:15:16 +00:00
parent 3c47b31e06
commit 2d4dca0936
432 changed files with 20953 additions and 6988 deletions

View File

@ -55,9 +55,9 @@ git = "https://github.com/mozilla-spidermonkey/jsparagus"
rev = "61f399c53a641ebd3077c1f39f054f6d396a633c"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706"]
[source."git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584"]
git = "https://github.com/mozilla/application-services"
rev = "9054db4bb5031881550ceab3448665ef6499a706"
rev = "e6ccfed09ebe663f464a33968f42e656c152e584"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/audioipc?rev=409e11f8de6288e9ddfe269654523735302e59e6"]
@ -90,9 +90,9 @@ git = "https://github.com/mozilla/neqo"
tag = "v0.7.4"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/uniffi-rs.git?rev=afb29ebdc1d9edf15021b1c5332fc9f285bbe13b"]
[source."git+https://github.com/mozilla/uniffi-rs.git?rev=d52c5460ae42ecad1e73a5b394ac96d48f4769de"]
git = "https://github.com/mozilla/uniffi-rs.git"
rev = "afb29ebdc1d9edf15021b1c5332fc9f285bbe13b"
rev = "d52c5460ae42ecad1e73a5b394ac96d48f4769de"
replace-with = "vendored-sources"
[source."git+https://github.com/seanmonstar/warp?rev=9d081461ae1167eb321585ce424f4fef6cf0092b"]

149
Cargo.lock generated
View File

@ -1655,7 +1655,7 @@ dependencies = [
[[package]]
name = "error-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"error-support-macros",
"lazy_static",
@ -1667,7 +1667,7 @@ dependencies = [
[[package]]
name = "error-support-macros"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"proc-macro2",
"quote",
@ -2370,9 +2370,9 @@ dependencies = [
[[package]]
name = "glean"
version = "58.1.0"
version = "59.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f58388f10d013e2d12bb58e6e76983ede120789956fe827913a3d2560c66d44d"
checksum = "0ceede8fb9c90ba1b77fb8290d3ae7b62bfcb422ad1d6e46bae1c8af3f22f12d"
dependencies = [
"glean-core",
"inherent",
@ -2383,9 +2383,9 @@ dependencies = [
[[package]]
name = "glean-core"
version = "58.1.0"
version = "59.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed9acc46fd38c5c995a0537e76364496addace660839dc279079e5957e3c1093"
checksum = "ea06a592b1395e0a16a5f4d6872f009ca7c98acc5127a8119088f1b435b5aaae"
dependencies = [
"android_logger",
"bincode",
@ -2447,20 +2447,20 @@ dependencies = [
[[package]]
name = "goblin"
version = "0.6.999"
version = "0.7.999"
dependencies = [
"goblin 0.7.1",
"goblin 0.8.0",
]
[[package]]
name = "goblin"
version = "0.7.1"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27c1b4369c2cd341b5de549380158b105a04c331be5db9110eef7b6d2742134"
checksum = "bb07a4ffed2093b118a525b1d8f5204ae274faed5604537caf7135d0f18d9887"
dependencies = [
"log",
"plain",
"scroll",
"scroll 0.12.0",
]
[[package]]
@ -2935,7 +2935,7 @@ dependencies = [
[[package]]
name = "interrupt-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"lazy_static",
"parking_lot",
@ -3619,7 +3619,7 @@ dependencies = [
"num-derive",
"num-traits",
"range-map",
"scroll",
"scroll 0.11.999",
"smart-default",
]
@ -3633,7 +3633,7 @@ dependencies = [
"byteorder",
"cfg-if 1.0.0",
"crash-context",
"goblin 0.7.1",
"goblin 0.7.999",
"libc",
"mach2",
"memmap2 0.8.999",
@ -3641,7 +3641,7 @@ dependencies = [
"minidump-common",
"nix 0.27.1",
"procfs-core",
"scroll",
"scroll 0.11.999",
"tempfile",
"thiserror",
]
@ -4131,7 +4131,7 @@ dependencies = [
[[package]]
name = "nss_build_common"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
[[package]]
name = "nsstring"
@ -4254,9 +4254,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "oneshot-uniffi"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ae4988774e7a7e6a0783d119bdc683ea8c1d01a24d4fff9b4bdc280e07bd99e"
checksum = "6c548d5c78976f6955d72d0ced18c48ca07030f7a1d4024529fedd7c1c01b29c"
[[package]]
name = "ordered-float"
@ -4575,7 +4575,7 @@ dependencies = [
name = "process_reader"
version = "0.1.0"
dependencies = [
"goblin 0.7.1",
"goblin 0.7.999",
"libc",
"mach2",
"memoffset 0.9.0",
@ -4816,7 +4816,7 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "relevancy"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"error-support",
"log",
@ -4832,7 +4832,7 @@ dependencies = [
[[package]]
name = "remote_settings"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"parking_lot",
"serde",
@ -5057,18 +5057,25 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "scroll"
version = "0.11.0"
version = "0.11.999"
dependencies = [
"scroll 0.12.0",
]
[[package]]
name = "scroll"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da"
checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6"
dependencies = [
"scroll_derive",
]
[[package]]
name = "scroll_derive"
version = "0.11.1"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae"
checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932"
dependencies = [
"proc-macro2",
"quote",
@ -5323,6 +5330,12 @@ dependencies = [
"syn",
]
[[package]]
name = "smawk"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
[[package]]
name = "smoosh"
version = "0.1.0"
@ -5355,7 +5368,7 @@ dependencies = [
[[package]]
name = "sql-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"ffi-support",
"interrupt-support",
@ -5536,7 +5549,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "suggest"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"anyhow",
"chrono",
@ -5585,7 +5598,7 @@ dependencies = [
[[package]]
name = "sync-guid"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"base64 0.21.3",
"rand",
@ -5596,7 +5609,7 @@ dependencies = [
[[package]]
name = "sync15"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"anyhow",
"error-support",
@ -5628,7 +5641,7 @@ dependencies = [
[[package]]
name = "tabs"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"anyhow",
"error-support",
@ -5673,6 +5686,17 @@ dependencies = [
name = "terminal_size"
version = "0.3.999"
[[package]]
name = "textwrap"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
dependencies = [
"smawk",
"unicode-linebreak",
"unicode-width",
]
[[package]]
name = "thin-vec"
version = "0.2.12"
@ -5988,6 +6012,12 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "unicode-linebreak"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
@ -6011,9 +6041,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "uniffi"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21345172d31092fd48c47fd56c53d4ae9e41c4b1f559fb8c38c1ab1685fd919f"
checksum = "a5566fae48a5cb017005bf9cd622af5236b2a203a13fb548afde3506d3c68277"
dependencies = [
"anyhow",
"uniffi_build",
@ -6040,7 +6070,7 @@ dependencies = [
[[package]]
name = "uniffi-example-arithmetic"
version = "0.22.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=afb29ebdc1d9edf15021b1c5332fc9f285bbe13b#afb29ebdc1d9edf15021b1c5332fc9f285bbe13b"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=d52c5460ae42ecad1e73a5b394ac96d48f4769de#d52c5460ae42ecad1e73a5b394ac96d48f4769de"
dependencies = [
"thiserror",
"uniffi",
@ -6060,7 +6090,7 @@ dependencies = [
[[package]]
name = "uniffi-example-geometry"
version = "0.22.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=afb29ebdc1d9edf15021b1c5332fc9f285bbe13b#afb29ebdc1d9edf15021b1c5332fc9f285bbe13b"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=d52c5460ae42ecad1e73a5b394ac96d48f4769de#d52c5460ae42ecad1e73a5b394ac96d48f4769de"
dependencies = [
"uniffi",
]
@ -6068,7 +6098,7 @@ dependencies = [
[[package]]
name = "uniffi-example-rondpoint"
version = "0.22.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=afb29ebdc1d9edf15021b1c5332fc9f285bbe13b#afb29ebdc1d9edf15021b1c5332fc9f285bbe13b"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=d52c5460ae42ecad1e73a5b394ac96d48f4769de#d52c5460ae42ecad1e73a5b394ac96d48f4769de"
dependencies = [
"uniffi",
]
@ -6076,7 +6106,7 @@ dependencies = [
[[package]]
name = "uniffi-example-sprites"
version = "0.22.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=afb29ebdc1d9edf15021b1c5332fc9f285bbe13b#afb29ebdc1d9edf15021b1c5332fc9f285bbe13b"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=d52c5460ae42ecad1e73a5b394ac96d48f4769de#d52c5460ae42ecad1e73a5b394ac96d48f4769de"
dependencies = [
"uniffi",
]
@ -6084,7 +6114,7 @@ dependencies = [
[[package]]
name = "uniffi-example-todolist"
version = "0.22.0"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=afb29ebdc1d9edf15021b1c5332fc9f285bbe13b#afb29ebdc1d9edf15021b1c5332fc9f285bbe13b"
source = "git+https://github.com/mozilla/uniffi-rs.git?rev=d52c5460ae42ecad1e73a5b394ac96d48f4769de#d52c5460ae42ecad1e73a5b394ac96d48f4769de"
dependencies = [
"once_cell",
"thiserror",
@ -6117,9 +6147,9 @@ dependencies = [
[[package]]
name = "uniffi_bindgen"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd992f2929a053829d5875af1eff2ee3d7a7001cb3b9a46cc7895f2caede6940"
checksum = "4a77bb514bcd4bf27c9bd404d7c3f2a6a8131b957eba9c22cfeb7751c4278e09"
dependencies = [
"anyhow",
"askama",
@ -6127,11 +6157,12 @@ dependencies = [
"cargo_metadata",
"fs-err",
"glob",
"goblin 0.6.999",
"goblin 0.8.0",
"heck",
"once_cell",
"paste",
"serde",
"textwrap",
"toml",
"uniffi_meta",
"uniffi_testing",
@ -6140,9 +6171,9 @@ dependencies = [
[[package]]
name = "uniffi_build"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "001964dd3682d600084b3aaf75acf9c3426699bc27b65e96bb32d175a31c74e9"
checksum = "45cba427aeb7b3a8b54830c4c915079a7a3c62608dd03dddba1d867a8a023eb4"
dependencies = [
"anyhow",
"camino",
@ -6151,9 +6182,9 @@ dependencies = [
[[package]]
name = "uniffi_checksum_derive"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c"
checksum = "ae7e5a6c33b1dec3f255f57ec0b6af0f0b2bb3021868be1d5eec7a38e2905ebc"
dependencies = [
"quote",
"syn",
@ -6161,9 +6192,9 @@ dependencies = [
[[package]]
name = "uniffi_core"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6121a127a3af1665cd90d12dd2b3683c2643c5103281d0fed5838324ca1fad5b"
checksum = "0ea3eb5474d50fc149b7e4d86b9c5bd4a61dcc167f0683902bf18ae7bbb3deef"
dependencies = [
"anyhow",
"bytes",
@ -6177,9 +6208,9 @@ dependencies = [
[[package]]
name = "uniffi_macros"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11cf7a58f101fcedafa5b77ea037999b88748607f0ef3a33eaa0efc5392e92e4"
checksum = "18331d35003f46f0d04047fbe4227291815b83a937a8c32bc057f990962182c4"
dependencies = [
"bincode",
"camino",
@ -6190,15 +6221,14 @@ dependencies = [
"serde",
"syn",
"toml",
"uniffi_build",
"uniffi_meta",
]
[[package]]
name = "uniffi_meta"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71dc8573a7b1ac4b71643d6da34888273ebfc03440c525121f1b3634ad3417a2"
checksum = "f7224422c4cfd181c7ca9fca2154abca4d21db962f926f270f996edd38b0c4b8"
dependencies = [
"anyhow",
"bytes",
@ -6208,9 +6238,9 @@ dependencies = [
[[package]]
name = "uniffi_testing"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "118448debffcb676ddbe8c5305fb933ab7e0123753e659a71dc4a693f8d9f23c"
checksum = "f8ce878d0bdfc288b58797044eaaedf748526c56eef3575380bb4d4b19d69eee"
dependencies = [
"anyhow",
"camino",
@ -6221,11 +6251,12 @@ dependencies = [
[[package]]
name = "uniffi_udl"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "889edb7109c6078abe0e53e9b4070cf74a6b3468d141bdf5ef1bd4d1dc24a1c3"
checksum = "8c43c9ed40a8d20a5c3eae2d23031092db6b96dc8e571beb449ba9757484cea0"
dependencies = [
"anyhow",
"textwrap",
"uniffi_meta",
"uniffi_testing",
"weedle2",
@ -6287,7 +6318,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "viaduct"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"ffi-support",
"log",
@ -6435,7 +6466,7 @@ dependencies = [
[[package]]
name = "webext-storage"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9054db4bb5031881550ceab3448665ef6499a706#9054db4bb5031881550ceab3448665ef6499a706"
source = "git+https://github.com/mozilla/application-services?rev=e6ccfed09ebe663f464a33968f42e656c152e584#e6ccfed09ebe663f464a33968f42e656c152e584"
dependencies = [
"anyhow",
"error-support",
@ -6585,9 +6616,9 @@ dependencies = [
[[package]]
name = "weedle2"
version = "4.0.0"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e79c5206e1f43a2306fd64bdb95025ee4228960f2e6c5a8b173f3caaf807741"
checksum = "998d2c24ec099a87daf9467808859f9d82b61f1d9c9701251aea037f514eae0e"
dependencies = [
"nom",
]

100
gfx/wr/Cargo.lock generated
View File

@ -347,7 +347,7 @@ dependencies = [
"indexmap",
"strsim",
"termcolor",
"textwrap",
"textwrap 0.15.0",
"yaml-rust",
]
@ -996,9 +996,9 @@ dependencies = [
[[package]]
name = "glean"
version = "58.1.0"
version = "59.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f58388f10d013e2d12bb58e6e76983ede120789956fe827913a3d2560c66d44d"
checksum = "0ceede8fb9c90ba1b77fb8290d3ae7b62bfcb422ad1d6e46bae1c8af3f22f12d"
dependencies = [
"glean-core",
"inherent",
@ -1009,9 +1009,9 @@ dependencies = [
[[package]]
name = "glean-core"
version = "58.1.0"
version = "59.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed9acc46fd38c5c995a0537e76364496addace660839dc279079e5957e3c1093"
checksum = "ea06a592b1395e0a16a5f4d6872f009ca7c98acc5127a8119088f1b435b5aaae"
dependencies = [
"android_logger",
"bincode",
@ -1189,9 +1189,9 @@ dependencies = [
[[package]]
name = "goblin"
version = "0.6.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "572564d6cba7d09775202c8e7eebc4d534d5ae36578ab402fb21e182a0ac9505"
checksum = "bb07a4ffed2093b118a525b1d8f5204ae274faed5604537caf7135d0f18d9887"
dependencies = [
"log",
"plain",
@ -1873,9 +1873,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "oneshot-uniffi"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ae4988774e7a7e6a0783d119bdc683ea8c1d01a24d4fff9b4bdc280e07bd99e"
checksum = "6c548d5c78976f6955d72d0ced18c48ca07030f7a1d4024529fedd7c1c01b29c"
[[package]]
name = "ordered-float"
@ -2338,22 +2338,22 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "scroll"
version = "0.11.0"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da"
checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6"
dependencies = [
"scroll_derive",
]
[[package]]
name = "scroll_derive"
version = "0.11.0"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdbda6ac5cd1321e724fa9cee216f3a61885889b896f073b8f82322789c5250e"
checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.91",
"syn 2.0.25",
]
[[package]]
@ -2451,6 +2451,12 @@ dependencies = [
"serde",
]
[[package]]
name = "smawk"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
[[package]]
name = "smithay-client-toolkit"
version = "0.15.4"
@ -2617,6 +2623,17 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]]
name = "textwrap"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
dependencies = [
"smawk",
"unicode-linebreak",
"unicode-width",
]
[[package]]
name = "thiserror"
version = "1.0.38"
@ -2717,6 +2734,12 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
[[package]]
name = "unicode-linebreak"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
[[package]]
name = "unicode-normalization"
version = "0.1.19"
@ -2726,6 +2749,12 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-width"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "unicode-xid"
version = "0.2.0"
@ -2734,9 +2763,9 @@ checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "uniffi"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21345172d31092fd48c47fd56c53d4ae9e41c4b1f559fb8c38c1ab1685fd919f"
checksum = "a5566fae48a5cb017005bf9cd622af5236b2a203a13fb548afde3506d3c68277"
dependencies = [
"anyhow",
"uniffi_build",
@ -2746,9 +2775,9 @@ dependencies = [
[[package]]
name = "uniffi_bindgen"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd992f2929a053829d5875af1eff2ee3d7a7001cb3b9a46cc7895f2caede6940"
checksum = "4a77bb514bcd4bf27c9bd404d7c3f2a6a8131b957eba9c22cfeb7751c4278e09"
dependencies = [
"anyhow",
"askama",
@ -2761,6 +2790,7 @@ dependencies = [
"once_cell",
"paste",
"serde",
"textwrap 0.16.1",
"toml",
"uniffi_meta",
"uniffi_testing",
@ -2769,9 +2799,9 @@ dependencies = [
[[package]]
name = "uniffi_build"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "001964dd3682d600084b3aaf75acf9c3426699bc27b65e96bb32d175a31c74e9"
checksum = "45cba427aeb7b3a8b54830c4c915079a7a3c62608dd03dddba1d867a8a023eb4"
dependencies = [
"anyhow",
"camino",
@ -2780,9 +2810,9 @@ dependencies = [
[[package]]
name = "uniffi_checksum_derive"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c"
checksum = "ae7e5a6c33b1dec3f255f57ec0b6af0f0b2bb3021868be1d5eec7a38e2905ebc"
dependencies = [
"quote",
"syn 2.0.25",
@ -2790,9 +2820,9 @@ dependencies = [
[[package]]
name = "uniffi_core"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6121a127a3af1665cd90d12dd2b3683c2643c5103281d0fed5838324ca1fad5b"
checksum = "0ea3eb5474d50fc149b7e4d86b9c5bd4a61dcc167f0683902bf18ae7bbb3deef"
dependencies = [
"anyhow",
"bytes",
@ -2806,9 +2836,9 @@ dependencies = [
[[package]]
name = "uniffi_macros"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11cf7a58f101fcedafa5b77ea037999b88748607f0ef3a33eaa0efc5392e92e4"
checksum = "18331d35003f46f0d04047fbe4227291815b83a937a8c32bc057f990962182c4"
dependencies = [
"bincode",
"camino",
@ -2819,15 +2849,14 @@ dependencies = [
"serde",
"syn 2.0.25",
"toml",
"uniffi_build",
"uniffi_meta",
]
[[package]]
name = "uniffi_meta"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71dc8573a7b1ac4b71643d6da34888273ebfc03440c525121f1b3634ad3417a2"
checksum = "f7224422c4cfd181c7ca9fca2154abca4d21db962f926f270f996edd38b0c4b8"
dependencies = [
"anyhow",
"bytes",
@ -2837,9 +2866,9 @@ dependencies = [
[[package]]
name = "uniffi_testing"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "118448debffcb676ddbe8c5305fb933ab7e0123753e659a71dc4a693f8d9f23c"
checksum = "f8ce878d0bdfc288b58797044eaaedf748526c56eef3575380bb4d4b19d69eee"
dependencies = [
"anyhow",
"camino",
@ -2850,11 +2879,12 @@ dependencies = [
[[package]]
name = "uniffi_udl"
version = "0.25.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "889edb7109c6078abe0e53e9b4070cf74a6b3468d141bdf5ef1bd4d1dc24a1c3"
checksum = "8c43c9ed40a8d20a5c3eae2d23031092db6b96dc8e571beb449ba9757484cea0"
dependencies = [
"anyhow",
"textwrap 0.16.1",
"uniffi_meta",
"uniffi_testing",
"weedle2",
@ -3141,9 +3171,9 @@ dependencies = [
[[package]]
name = "weedle2"
version = "4.0.0"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e79c5206e1f43a2306fd64bdb95025ee4228960f2e6c5a8b173f3caaf807741"
checksum = "998d2c24ec099a87daf9467808859f9d82b61f1d9c9701251aea037f514eae0e"
dependencies = [
"nom 7.1.1",
]

View File

@ -226,15 +226,15 @@ user-login = "jrmuizel"
user-name = "Jeff Muizelaar"
[[publisher.glean]]
version = "58.1.0"
when = "2024-03-12"
version = "59.0.0"
when = "2024-03-28"
user-id = 48
user-login = "badboy"
user-name = "Jan-Erik Rediger"
[[publisher.glean-core]]
version = "58.1.0"
when = "2024-03-12"
version = "59.0.0"
when = "2024-03-28"
user-id = 48
user-login = "badboy"
user-name = "Jan-Erik Rediger"
@ -602,58 +602,67 @@ user-login = "Manishearth"
user-name = "Manish Goregaokar"
[[publisher.uniffi]]
version = "0.25.3"
when = "2023-12-07"
user-id = 127697
user-login = "bendk"
version = "0.27.1"
when = "2024-04-03"
user-id = 111105
user-login = "mhammond"
user-name = "Mark Hammond"
[[publisher.uniffi_bindgen]]
version = "0.25.3"
when = "2023-12-07"
user-id = 127697
user-login = "bendk"
version = "0.27.1"
when = "2024-04-03"
user-id = 111105
user-login = "mhammond"
user-name = "Mark Hammond"
[[publisher.uniffi_build]]
version = "0.25.3"
when = "2023-12-07"
user-id = 127697
user-login = "bendk"
version = "0.27.1"
when = "2024-04-03"
user-id = 111105
user-login = "mhammond"
user-name = "Mark Hammond"
[[publisher.uniffi_checksum_derive]]
version = "0.25.3"
when = "2023-12-07"
user-id = 127697
user-login = "bendk"
version = "0.27.1"
when = "2024-04-03"
user-id = 111105
user-login = "mhammond"
user-name = "Mark Hammond"
[[publisher.uniffi_core]]
version = "0.25.3"
when = "2023-12-07"
user-id = 127697
user-login = "bendk"
version = "0.27.1"
when = "2024-04-03"
user-id = 111105
user-login = "mhammond"
user-name = "Mark Hammond"
[[publisher.uniffi_macros]]
version = "0.25.3"
when = "2023-12-07"
user-id = 127697
user-login = "bendk"
version = "0.27.1"
when = "2024-04-03"
user-id = 111105
user-login = "mhammond"
user-name = "Mark Hammond"
[[publisher.uniffi_meta]]
version = "0.25.3"
when = "2023-12-07"
user-id = 127697
user-login = "bendk"
version = "0.27.1"
when = "2024-04-03"
user-id = 111105
user-login = "mhammond"
user-name = "Mark Hammond"
[[publisher.uniffi_testing]]
version = "0.25.3"
when = "2023-12-07"
user-id = 127697
user-login = "bendk"
version = "0.27.1"
when = "2024-04-03"
user-id = 111105
user-login = "mhammond"
user-name = "Mark Hammond"
[[publisher.uniffi_udl]]
version = "0.25.3"
when = "2023-12-07"
user-id = 127697
user-login = "bendk"
version = "0.27.1"
when = "2024-04-03"
user-id = 111105
user-login = "mhammond"
user-name = "Mark Hammond"
[[publisher.utf8_iter]]
version = "1.0.3"
@ -683,45 +692,30 @@ user-id = 1
user-login = "alexcrichton"
user-name = "Alex Crichton"
[[publisher.wasm-encoder]]
version = "0.40.0"
when = "2024-01-24"
user-id = 1
user-login = "alexcrichton"
user-name = "Alex Crichton"
[[publisher.wasm-encoder]]
version = "0.201.0"
when = "2024-02-27"
user-id = 73222
user-login = "wasmtime-publish"
[[publisher.wasm-smith]]
version = "0.15.0"
when = "2024-01-24"
user-id = 1
user-login = "alexcrichton"
user-name = "Alex Crichton"
[[publisher.wasm-smith]]
version = "0.201.0"
when = "2024-02-27"
user-id = 73222
user-login = "wasmtime-publish"
[[publisher.wast]]
version = "70.0.1"
when = "2024-01-24"
user-id = 1
user-login = "alexcrichton"
user-name = "Alex Crichton"
[[publisher.wast]]
version = "201.0.0"
when = "2024-02-27"
user-id = 73222
user-login = "wasmtime-publish"
[[publisher.weedle2]]
version = "5.0.0"
when = "2024-01-24"
user-id = 127697
user-login = "bendk"
[[publisher.winapi-util]]
version = "0.1.5"
when = "2020-04-20"
@ -780,45 +774,6 @@ start = "2020-01-14"
end = "2024-04-27"
notes = "I am an author of this crate"
[[audits.bytecode-alliance.wildcard-audits.wasm-encoder]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
user-id = 1 # Alex Crichton (alexcrichton)
start = "2020-12-11"
end = "2024-04-14"
notes = """
This is a Bytecode Alliance authored crate maintained in the `wasm-tools`
repository of which I'm one of the primary maintainers and publishers for.
I am employed by a member of the Bytecode Alliance and plan to continue doing
so and will actively maintain this crate over time.
"""
[[audits.bytecode-alliance.wildcard-audits.wasm-smith]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
user-id = 1 # Alex Crichton (alexcrichton)
start = "2020-09-03"
end = "2024-04-14"
notes = """
This is a Bytecode Alliance authored crate maintained in the `wasm-tools`
repository of which I'm one of the primary maintainers and publishers for.
I am employed by a member of the Bytecode Alliance and plan to continue doing
so and will actively maintain this crate over time.
"""
[[audits.bytecode-alliance.wildcard-audits.wast]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
user-id = 1 # Alex Crichton (alexcrichton)
start = "2019-10-16"
end = "2024-04-14"
notes = """
This is a Bytecode Alliance authored crate maintained in the `wasm-tools`
repository of which I'm one of the primary maintainers and publishers for.
I am employed by a member of the Bytecode Alliance and plan to continue doing
so and will actively maintain this crate over time.
"""
[[audits.bytecode-alliance.audits.adler]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
@ -873,12 +828,6 @@ who = "Benjamin Bouvier <public@benj.me>"
criteria = "safe-to-deploy"
delta = "0.9.0 -> 0.10.2"
[[audits.bytecode-alliance.audits.bumpalo]]
who = "Nick Fitzgerald <fitzgen@gmail.com>"
criteria = "safe-to-deploy"
version = "3.11.1"
notes = "I am the author of this crate."
[[audits.bytecode-alliance.audits.cargo-platform]]
who = "Pat Hickey <phickey@fastly.com>"
criteria = "safe-to-deploy"
@ -1335,6 +1284,20 @@ criteria = "safe-to-run"
version = "0.2.3"
aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT"
[[audits.google.audits.unicode-linebreak]]
who = "Lukasz Anforowicz <lukasza@chromium.org>"
criteria = "safe-to-deploy"
version = "0.1.5"
notes = """
Grepped for `-i cipher`, `-i crypto`, `'\bfs\b'``, `'\bnet\b'``, `'\bunsafe\b'``
and there were no hits.
Version `0.1.2` of this crate has been added to Chromium in
https://source.chromium.org/chromium/chromium/src/+/591a0f30c5eac93b6a3d981c2714ffa4db28dbcb
The CL description contains a link to a Google-internal document with audit details.
"""
aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT"
[[audits.google.audits.version_check]]
who = "George Burgess IV <gbiv@google.com>"
criteria = "safe-to-deploy"
@ -1440,6 +1403,87 @@ who = "Brandon Pitman <bran@bran.land>"
criteria = "safe-to-deploy"
delta = "0.10.7 -> 0.10.8"
[[audits.mozilla.wildcard-audits.uniffi]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
user-id = 111105 # Mark Hammond (mhammond)
start = "2021-11-22"
end = "2024-11-28"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.wildcard-audits.uniffi_bindgen]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
user-id = 111105 # Mark Hammond (mhammond)
start = "2021-11-22"
end = "2024-11-28"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.wildcard-audits.uniffi_build]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
user-id = 111105 # Mark Hammond (mhammond)
start = "2021-11-22"
end = "2024-11-28"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.wildcard-audits.uniffi_checksum_derive]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
user-id = 111105 # Mark Hammond (mhammond)
start = "2023-11-20"
end = "2024-11-28"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.wildcard-audits.uniffi_core]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
user-id = 111105 # Mark Hammond (mhammond)
start = "2023-11-20"
end = "2024-11-28"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.wildcard-audits.uniffi_macros]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
user-id = 111105 # Mark Hammond (mhammond)
start = "2021-11-22"
end = "2024-11-28"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.wildcard-audits.uniffi_meta]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
user-id = 111105 # Mark Hammond (mhammond)
start = "2023-11-20"
end = "2024-11-28"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.wildcard-audits.uniffi_testing]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
user-id = 111105 # Mark Hammond (mhammond)
start = "2023-11-20"
end = "2024-11-28"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.wildcard-audits.uniffi_udl]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
user-id = 111105 # Mark Hammond (mhammond)
start = "2023-11-20"
end = "2024-11-28"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.wildcard-audits.weedle2]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
user-id = 127697 # bendk
start = "2022-06-16"
end = "2025-03-05"
notes = "Maintained by Mozilla"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.wildcard-audits.zeitstempel]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
@ -1487,6 +1531,13 @@ no unsafe code.
"""
aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml"
[[audits.mozilla.audits.goblin]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.7.1 -> 0.8.0"
notes = "MSRV bump, no unsafe changes"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.lazy_static]]
who = "Nika Layzell <nika@thelayzells.com>"
criteria = "safe-to-deploy"
@ -1508,9 +1559,40 @@ delta = "0.4.18 -> 0.4.20"
notes = "Only cfg attribute and internal macro changes and module refactorings"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.oneshot-uniffi]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.1.5 -> 0.1.6"
notes = "Synced with the orginal crate, no new unsafe"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.rkv]]
who = "Kagami Sascha Rosylight <krosylight@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.18.4 -> 0.19.0"
notes = "Maintained by Mozilla, no addition of unsafe blocks"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.scroll]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.11.0 -> 0.12.0"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.scroll_derive]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.11.1 -> 0.12.0"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.smawk]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
version = "0.3.2"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.textwrap]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
version = "0.15.0"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"49ef90bd388b59229db34b35fe06eb769183431c88b5712e6e9992851aef605d","README.md":"8030b4a314b1be31ba018ac12c3b586bb736db5307c3c395f2857fffe0130322","build.rs":"c8d3c38c1208eea36224662b284d8daf3e7ad1b07d22d750524f3da1cc66ccca","src/errorsupport.udl":"e793034d01a2608298528051757f38405e006ee1abc4cf65dc6f18c53590ace8","src/handling.rs":"6e0568b18d426531cb2ae9967c8dd0d51ece5a065f68b15eeb308b995edaa167","src/lib.rs":"96ae3cc2c1077ae45442ace6b5b5311b86267d0b9067f3ff58396af30ccbbc07","src/macros.rs":"0d03f82fab20c96a182f941baf3fcf2a286b00fea871ee7fd8e339abc14f9522","src/redact.rs":"c9a4df1a87be68b15d583587bda941d4c60a1d0449e2d43ff99f3611a290a863","src/reporting.rs":"38efd24d86ba8facfb181cb27e8b698d2831db0afab85691ffda034a4dc68dfa","uniffi.toml":"644fe81c12fe3c01ee81e017ca3c00d0e611f014b7eade51aadaf208179a3450"},"package":null}
{"files":{"Cargo.toml":"bd2f0908b3576a3ad9a416ecb0e4f8441a48a95036cf0439a65e37d836178142","README.md":"8030b4a314b1be31ba018ac12c3b586bb736db5307c3c395f2857fffe0130322","build.rs":"c8d3c38c1208eea36224662b284d8daf3e7ad1b07d22d750524f3da1cc66ccca","src/errorsupport.udl":"e793034d01a2608298528051757f38405e006ee1abc4cf65dc6f18c53590ace8","src/handling.rs":"6e0568b18d426531cb2ae9967c8dd0d51ece5a065f68b15eeb308b995edaa167","src/lib.rs":"96ae3cc2c1077ae45442ace6b5b5311b86267d0b9067f3ff58396af30ccbbc07","src/macros.rs":"0d03f82fab20c96a182f941baf3fcf2a286b00fea871ee7fd8e339abc14f9522","src/redact.rs":"c9a4df1a87be68b15d583587bda941d4c60a1d0449e2d43ff99f3611a290a863","src/reporting.rs":"38efd24d86ba8facfb181cb27e8b698d2831db0afab85691ffda034a4dc68dfa","uniffi.toml":"644fe81c12fe3c01ee81e017ca3c00d0e611f014b7eade51aadaf208179a3450"},"package":null}

View File

@ -21,7 +21,7 @@ license = "MPL-2.0"
[dependencies]
log = "0.4"
uniffi = "0.25.2"
uniffi = "0.27.1"
[dependencies.backtrace]
version = "0.3"
@ -37,5 +37,5 @@ version = "1.4"
version = ">=0.11,<=0.12"
[build-dependencies.uniffi]
version = "0.25.2"
version = "0.27.1"
features = ["build"]

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.66"
name = "glean-core"
version = "58.1.0"
version = "59.0.0"
authors = [
"Jan-Erik Rediger <jrediger@mozilla.com>",
"The Glean Team <glean-team@mozilla.com>",
@ -80,7 +80,7 @@ version = "1.0.4"
version = "0.1.40"
[dependencies.uniffi]
version = "0.25.2"
version = "0.27.0"
default-features = false
[dependencies.uuid]
@ -105,7 +105,7 @@ version = "0.4"
version = "3.8.0"
[build-dependencies.uniffi]
version = "0.25.2"
version = "0.27.0"
features = ["build"]
default-features = false

View File

@ -2,7 +2,6 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::convert::TryFrom;
use std::sync::atomic::{AtomicU8, Ordering};
use crate::error::{Error, ErrorKind};

View File

@ -120,6 +120,7 @@ where
/// rate_limit: None,
/// enable_event_timestamps: true,
/// experimentation_id: None,
/// enable_internal_pings: true,
/// };
/// let mut glean = Glean::new(cfg).unwrap();
/// let ping = PingType::new("sample", true, false, true, true, vec![]);
@ -208,7 +209,7 @@ impl Glean {
core_metrics: CoreMetrics::new(),
additional_metrics: AdditionalMetrics::new(),
database_metrics: DatabaseMetrics::new(),
internal_pings: InternalPings::new(),
internal_pings: InternalPings::new(cfg.enable_internal_pings),
upload_manager,
data_path: PathBuf::from(&cfg.data_path),
application_id,
@ -288,7 +289,9 @@ impl Glean {
}
// We set this only for non-subprocess situations.
glean.schedule_metrics_pings = cfg.use_core_mps;
// If internal pings are disabled, we don't set up the MPS either,
// it wouldn't send any data anyway.
glean.schedule_metrics_pings = cfg.enable_internal_pings && cfg.use_core_mps;
// We only scan the pendings pings directories **after** dealing with the upload state.
// If upload is disabled, we delete all pending pings files
@ -305,6 +308,7 @@ impl Glean {
data_path: &str,
application_id: &str,
upload_enabled: bool,
enable_internal_pings: bool,
) -> Self {
let cfg = InternalConfiguration {
data_path: data_path.into(),
@ -320,6 +324,7 @@ impl Glean {
rate_limit: None,
enable_event_timestamps: true,
experimentation_id: None,
enable_internal_pings,
};
let mut glean = Self::new(cfg).unwrap();

View File

@ -824,7 +824,6 @@ mod test {
use super::*;
use crate::tests::new_glean;
use std::collections::HashMap;
use std::path::Path;
use tempfile::tempdir;
#[test]

View File

@ -240,7 +240,6 @@ fn validate_source_tags(tags: &Vec<String>) -> bool {
#[cfg(test)]
mod test {
use super::*;
use std::env;
#[test]
fn debug_option_is_correctly_loaded_from_env() {

View File

@ -360,9 +360,8 @@ impl Dispatcher {
#[cfg(test)]
mod test {
use super::*;
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
use std::sync::{Arc, Mutex};
use std::{thread, time::Duration};
use std::sync::atomic::AtomicU8;
use std::sync::Mutex;
fn enable_test_logging() {
// When testing we want all logs to go to stdout/stderr by default,

View File

@ -12,7 +12,6 @@
//! but are not actually used directly, since the `send_in_pings` value needs to match the pings of the metric that is erroring (plus the "metrics" ping),
//! not some constant value that we could define in `metrics.yaml`.
use std::convert::TryFrom;
use std::fmt::Display;
use crate::common_metric_data::CommonMetricDataInternal;

View File

@ -4,7 +4,6 @@
use std::cmp::Ordering;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::fs;
use std::fs::{create_dir_all, File, OpenOptions};
use std::io::BufRead;
@ -638,8 +637,8 @@ impl EventDatabase {
#[cfg(test)]
mod test {
use super::*;
use crate::test_get_num_recorded_errors;
use crate::tests::new_glean;
use crate::{test_get_num_recorded_errors, CommonMetricData};
use chrono::{TimeZone, Timelike};
#[test]

View File

@ -90,6 +90,7 @@ dictionary InternalConfiguration {
PingRateLimit? rate_limit;
boolean enable_event_timestamps;
string? experimentation_id;
boolean enable_internal_pings;
};
// How to specify the rate pings may be uploaded before they are throttled.

View File

@ -5,7 +5,6 @@
//! A simple histogram implementation for exponential histograms.
use std::collections::HashMap;
use std::convert::TryFrom;
use serde::{Deserialize, Serialize};

View File

@ -19,9 +19,9 @@ pub struct InternalPings {
}
impl InternalPings {
pub fn new() -> InternalPings {
pub fn new(enabled: bool) -> InternalPings {
InternalPings {
baseline: PingType::new(
baseline: PingType::new_internal(
"baseline",
true,
true,
@ -32,8 +32,9 @@ impl InternalPings {
"dirty_startup".to_string(),
"inactive".to_string(),
],
enabled,
),
metrics: PingType::new(
metrics: PingType::new_internal(
"metrics",
true,
false,
@ -46,8 +47,9 @@ impl InternalPings {
"tomorrow".to_string(),
"upgrade".to_string(),
],
enabled,
),
events: PingType::new(
events: PingType::new_internal(
"events",
true,
false,
@ -58,6 +60,7 @@ impl InternalPings {
"inactive".to_string(),
"max_capacity".to_string(),
],
enabled,
),
deletion_request: PingType::new(
"deletion-request",

View File

@ -17,7 +17,6 @@
use std::borrow::Cow;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::fmt;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
@ -25,7 +24,7 @@ use std::thread;
use std::time::Duration;
use crossbeam_channel::unbounded;
use log::{self, LevelFilter};
use log::LevelFilter;
use once_cell::sync::{Lazy, OnceCell};
use uuid::Uuid;
@ -136,6 +135,8 @@ pub struct InternalConfiguration {
/// be noted that this has an underlying StringMetric and so should conform to the limitations that
/// StringMetric places on length, etc.
pub experimentation_id: Option<String>,
/// Whether to enable internal pings. Default: true
pub enable_internal_pings: bool,
}
/// How to specify the rate at which pings may be uploaded before they are throttled.

View File

@ -6,12 +6,10 @@
// the lib.rs file.
use std::collections::HashSet;
use std::iter::FromIterator;
use serde_json::json;
use super::*;
use crate::metrics::{StringMetric, TimeUnit, TimespanMetric, TimingDistributionMetric};
const GLOBAL_APPLICATION_ID: &str = "org.mozilla.glean.test.app";
pub fn new_glean(tempdir: Option<tempfile::TempDir>) -> (Glean, tempfile::TempDir) {
@ -21,7 +19,7 @@ pub fn new_glean(tempdir: Option<tempfile::TempDir>) -> (Glean, tempfile::TempDi
None => tempfile::tempdir().unwrap(),
};
let tmpname = dir.path().display().to_string();
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
(glean, dir)
}
@ -41,7 +39,7 @@ fn path_is_constructed_from_data() {
fn experiment_id_and_branch_get_truncated_if_too_long() {
let t = tempfile::tempdir().unwrap();
let name = t.path().display().to_string();
let glean = Glean::with_options(&name, "org.mozilla.glean.tests", true);
let glean = Glean::with_options(&name, "org.mozilla.glean.tests", true, true);
// Generate long strings for the used ids.
let very_long_id = "test-experiment-id".repeat(10);
@ -82,7 +80,7 @@ fn experiment_id_and_branch_get_truncated_if_too_long() {
fn limits_on_experiments_extras_are_applied_correctly() {
let t = tempfile::tempdir().unwrap();
let name = t.path().display().to_string();
let glean = Glean::with_options(&name, "org.mozilla.glean.tests", true);
let glean = Glean::with_options(&name, "org.mozilla.glean.tests", true, true);
let experiment_id = "test-experiment_id".to_string();
let branch_id = "test-branch-id".to_string();
@ -138,7 +136,7 @@ fn limits_on_experiments_extras_are_applied_correctly() {
fn experiments_status_is_correctly_toggled() {
let t = tempfile::tempdir().unwrap();
let name = t.path().display().to_string();
let glean = Glean::with_options(&name, "org.mozilla.glean.tests", true);
let glean = Glean::with_options(&name, "org.mozilla.glean.tests", true, true);
// Define the experiment's data.
let experiment_id: String = "test-toggle-experiment".into();
@ -199,6 +197,7 @@ fn experimentation_id_is_set_correctly() {
rate_limit: None,
enable_event_timestamps: true,
experimentation_id: Some(experimentation_id.to_string()),
enable_internal_pings: true,
})
.unwrap();
@ -219,7 +218,7 @@ fn client_id_and_first_run_date_must_be_regenerated() {
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().display().to_string();
{
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
glean.data_store.as_ref().unwrap().clear_all();
@ -236,7 +235,7 @@ fn client_id_and_first_run_date_must_be_regenerated() {
}
{
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
assert!(glean
.core_metrics
.client_id
@ -339,7 +338,7 @@ fn client_id_is_managed_correctly_when_toggling_uploading() {
fn client_id_is_set_to_known_value_when_uploading_disabled_at_start() {
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().display().to_string();
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, false);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, false, true);
assert_eq!(
*KNOWN_CLIENT_ID,
@ -355,7 +354,7 @@ fn client_id_is_set_to_known_value_when_uploading_disabled_at_start() {
fn client_id_is_set_to_random_value_when_uploading_enabled_at_start() {
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().display().to_string();
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
let current_client_id = glean
.core_metrics
@ -369,7 +368,7 @@ fn client_id_is_set_to_random_value_when_uploading_enabled_at_start() {
fn enabling_when_already_enabled_is_a_noop() {
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().display().to_string();
let mut glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let mut glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
assert!(!glean.set_upload_enabled(true));
}
@ -378,7 +377,7 @@ fn enabling_when_already_enabled_is_a_noop() {
fn disabling_when_already_disabled_is_a_noop() {
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().display().to_string();
let mut glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, false);
let mut glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, false, true);
assert!(!glean.set_upload_enabled(false));
}
@ -601,14 +600,14 @@ fn test_first_run() {
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().display().to_string();
{
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
// Check that this is indeed the first run.
assert!(glean.is_first_run());
}
{
// Other runs must be not marked as "first run".
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
assert!(!glean.is_first_run());
}
}
@ -618,7 +617,7 @@ fn test_dirty_bit() {
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().display().to_string();
{
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
// The dirty flag must not be set the first time Glean runs.
assert!(!glean.is_dirty_flag_set());
@ -630,7 +629,7 @@ fn test_dirty_bit() {
{
// Check that next time Glean runs, it correctly picks up the "dirty flag".
// It is expected to be 'true'.
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
assert!(glean.is_dirty_flag_set());
// Set the dirty flag to false.
@ -641,7 +640,7 @@ fn test_dirty_bit() {
{
// Check that next time Glean runs, it correctly picks up the "dirty flag".
// It is expected to be 'false'.
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
assert!(!glean.is_dirty_flag_set());
}
}
@ -1065,7 +1064,7 @@ fn test_empty_application_id() {
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().display().to_string();
let glean = Glean::with_options(&tmpname, "", true);
let glean = Glean::with_options(&tmpname, "", true, true);
// Check that this is indeed the first run.
assert!(glean.is_first_run());
}
@ -1080,7 +1079,7 @@ fn records_database_file_size() {
let tmpname = dir.path().display().to_string();
// Initialize Glean once to ensure we create the database and did not error.
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
let database_size = &glean.database_metrics.size;
let data = database_size.get_value(&glean, "metrics");
@ -1089,7 +1088,7 @@ fn records_database_file_size() {
drop(glean);
// Initialize Glean again to record file size.
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true);
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, true);
let database_size = &glean.database_metrics.size;
let data = database_size.get_value(&glean, "metrics");
@ -1161,3 +1160,46 @@ fn test_activity_api() {
// Check that we set everything we needed for the 'inactive' status.
assert!(!glean.is_dirty_flag_set());
}
#[test]
fn disabled_pings_are_not_submitted() {
let _ = env_logger::builder().is_test(true).try_init();
let dir = tempfile::tempdir().unwrap();
let (mut glean, _t) = new_glean(Some(dir));
let ping = PingType::new_internal("custom-disabled", true, false, true, true, vec![], false);
glean.register_ping_type(&ping);
// We need to store a metric as an empty ping is not stored.
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
category: "local".into(),
send_in_pings: vec!["custom-disabled".into()],
..Default::default()
});
counter.add_sync(&glean, 1);
assert!(!ping.submit_sync(&glean, None));
}
#[test]
fn internal_pings_can_be_disabled() {
let _ = env_logger::builder().is_test(true).try_init();
let dir = tempfile::tempdir().unwrap();
let tmpname = dir.path().display().to_string();
let glean = Glean::with_options(&tmpname, GLOBAL_APPLICATION_ID, true, false);
// We need to store a metric as an empty ping is not stored.
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
category: "local".into(),
send_in_pings: vec!["baseline".into()],
..Default::default()
});
counter.add_sync(&glean, 1);
let submitted = glean.internal_pings.baseline.submit_sync(&glean, None);
assert!(!submitted);
}

View File

@ -175,9 +175,21 @@ impl EventMetric {
.into()
.unwrap_or_else(|| &self.meta().inner.send_in_pings[0]);
glean
let events = glean
.event_storage()
.test_get_value(&self.meta, queried_ping_name)
.test_get_value(&self.meta, queried_ping_name);
events.map(|mut evts| {
for ev in &mut evts {
let Some(extra) = &mut ev.extra else { continue };
extra.remove("glean_timestamp");
if extra.is_empty() {
ev.extra = None;
}
}
evts
})
}
/// **Test-only API (exported for FFI purposes).**

View File

@ -2,8 +2,6 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::convert::TryFrom;
use serde::{Deserialize, Serialize};
use crate::error::{Error, ErrorKind};

View File

@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::{collections::HashMap, convert::TryFrom};
use std::collections::HashMap;
use serde::{Deserialize, Serialize};

View File

@ -31,6 +31,11 @@ struct InnerPing {
pub include_info_sections: bool,
/// The "reason" codes that this ping can send
pub reason_codes: Vec<String>,
/// Whether this ping is enabled.
/// Note: Data for disabled pings is still recorded.
/// It will not be cleared out on submit.
enabled: bool,
}
impl fmt::Debug for PingType {
@ -67,6 +72,26 @@ impl PingType {
precise_timestamps: bool,
include_info_sections: bool,
reason_codes: Vec<String>,
) -> Self {
Self::new_internal(
name,
include_client_id,
send_if_empty,
precise_timestamps,
include_info_sections,
reason_codes,
true,
)
}
pub(crate) fn new_internal<A: Into<String>>(
name: A,
include_client_id: bool,
send_if_empty: bool,
precise_timestamps: bool,
include_info_sections: bool,
reason_codes: Vec<String>,
enabled: bool,
) -> Self {
let this = Self(Arc::new(InnerPing {
name: name.into(),
@ -75,6 +100,7 @@ impl PingType {
precise_timestamps,
include_info_sections,
reason_codes,
enabled,
}));
// Register this ping.
@ -140,6 +166,11 @@ impl PingType {
/// Whether the ping was succesfully assembled and queued.
#[doc(hidden)]
pub fn submit_sync(&self, glean: &Glean, reason: Option<&str>) -> bool {
if !self.0.enabled {
log::info!("Ping disabled: not submitting '{}' ping.", self.0.name);
return false;
}
if !glean.is_upload_enabled() {
log::info!("Glean disabled: not submitting any pings.");
return false;

View File

@ -149,10 +149,8 @@ impl StringMetric {
#[cfg(test)]
mod test {
use super::*;
use crate::test_get_num_recorded_errors;
use crate::tests::new_glean;
use crate::util::truncate_string_at_boundary;
use crate::ErrorType;
use crate::Lifetime;
#[test]

View File

@ -153,10 +153,8 @@ impl TextMetric {
#[cfg(test)]
mod test {
use super::*;
use crate::test_get_num_recorded_errors;
use crate::tests::new_glean;
use crate::util::truncate_string_at_boundary;
use crate::ErrorType;
use crate::Lifetime;
#[test]

View File

@ -2,7 +2,6 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::convert::TryFrom;
use std::time::Duration;
use serde::{Deserialize, Serialize};

View File

@ -2,7 +2,6 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::convert::TryInto;
use std::sync::{Arc, RwLock};
use std::time::Duration;

View File

@ -96,7 +96,7 @@ impl TimingDistributionMetric {
Self {
meta: Arc::new(meta.into()),
time_unit,
next_id: Arc::new(AtomicUsize::new(0)),
next_id: Arc::new(AtomicUsize::new(1)),
start_times: Arc::new(Mutex::new(Default::default())),
}
}

View File

@ -168,9 +168,7 @@ impl UrlMetric {
#[cfg(test)]
mod test {
use super::*;
use crate::test_get_num_recorded_errors;
use crate::tests::new_glean;
use crate::ErrorType;
use crate::Lifetime;
#[test]

View File

@ -235,7 +235,7 @@ mod test {
fn test_experiments_json_serialization() {
let t = tempfile::tempdir().unwrap();
let name = t.path().display().to_string();
let glean = Glean::with_options(&name, "org.mozilla.glean", true);
let glean = Glean::with_options(&name, "org.mozilla.glean", true, true);
let extra: HashMap<String, String> = [("test-key".into(), "test-value".into())]
.iter()
@ -264,7 +264,7 @@ mod test {
fn test_experiments_json_serialization_empty() {
let t = tempfile::tempdir().unwrap();
let name = t.path().display().to_string();
let glean = Glean::with_options(&name, "org.mozilla.glean", true);
let glean = Glean::with_options(&name, "org.mozilla.glean", true, true);
let metric = ExperimentMetric::new(&glean, "some-experiment".to_string());

View File

@ -3,7 +3,6 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::collections::HashMap;
use std::convert::TryFrom;
use std::hash::Hash;
use crate::event_database::RecordedEvent;

View File

@ -317,8 +317,6 @@ impl PingDirectoryManager {
#[cfg(test)]
mod test {
use std::fs::File;
use super::*;
use crate::metrics::PingType;
use crate::tests::new_glean;

View File

@ -14,7 +14,6 @@
use std::collections::HashMap;
use std::collections::VecDeque;
use std::convert::TryInto;
use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
use std::sync::{Arc, RwLock, RwLockWriteGuard};
@ -856,9 +855,6 @@ pub fn chunked_log_info(_path: &str, payload: &str) {
#[cfg(test)]
mod test {
use std::thread;
use std::time::Duration;
use uuid::Uuid;
use super::*;

View File

@ -8,7 +8,7 @@ use std::collections::HashMap;
use chrono::prelude::{DateTime, Utc};
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
use serde_json::{self, Value as JsonValue};
use serde_json::Value as JsonValue;
use std::io::prelude::*;
use crate::error::{ErrorKind, Result};

View File

@ -63,6 +63,7 @@ pub fn new_glean(tempdir: Option<tempfile::TempDir>) -> (Glean, tempfile::TempDi
rate_limit: None,
enable_event_timestamps: false,
experimentation_id: None,
enable_internal_pings: true,
};
let glean = Glean::new(cfg).unwrap();

View File

@ -481,6 +481,7 @@ fn with_event_timestamps() {
rate_limit: None,
enable_event_timestamps: true,
experimentation_id: None, // Enabling event timestamps
enable_internal_pings: true,
};
let glean = Glean::new(cfg).unwrap();

View File

@ -91,6 +91,7 @@ fn test_metrics_must_report_experimentation_id() {
rate_limit: None,
enable_event_timestamps: true,
experimentation_id: Some("test-experimentation-id".to_string()),
enable_internal_pings: true,
})
.unwrap();
let ping_maker = PingMaker::new();
@ -143,6 +144,7 @@ fn experimentation_id_is_removed_if_send_if_empty_is_false() {
rate_limit: None,
enable_event_timestamps: true,
experimentation_id: Some("test-experimentation-id".to_string()),
enable_internal_pings: true,
})
.unwrap();
let ping_maker = PingMaker::new();

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"29b8551de6fff2f0fa3a821eb933f71a2a326b3ce3d37c25bcef3001f9146dfb","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"5627cc81e6187ab6c2b4dff061af16d559edcab64ba786bac39daa69c703c595","src/common_test.rs":"454df3d99eef045270e813946f921f56c39b16c18a5fadedc32829c3d44129cf","src/configuration.rs":"82b3a7933d913e1e2a4f328a76621db2d2e618d209d9785086d64c5c78c2a2d6","src/core_metrics.rs":"fef8fb4e5fa57c179836c6eb2cf59278fe3b8b036dbe57b0ff02971b4acd822f","src/lib.rs":"aa9c81fc6dc19ca1cb4bede25d554377a5d717fb3b246967edb1be12a395ce61","src/net/http_uploader.rs":"01ad5bd91384411a12c74434cd1c5cd585078cb34faba4615c70bdb669a9bccb","src/net/mod.rs":"f47b96bb878f1a6c771cedbaeaeefb270bc87fb1d1bbbed1b282dddca16216ed","src/private/event.rs":"d7c70c02648584c19c73af89e5180d3c6153c911f2c6830f7d1599b18d6150eb","src/private/mod.rs":"3565eb569d2b96f938f130abe0fc3ee3f55e7e03fd6501e309d3ef6af72ef6ee","src/private/object.rs":"3f70363a196aea46cc163af025a53e48c117c6208babc4bce772bb4c337cced8","src/private/ping.rs":"a6262a3453c77cbf30766c19b535a1bf66a37b2a316e8f87baee03025255c33e","src/system.rs":"6eae5b41c15eba9cad6dbd116abe3519ee3e1fe034e79bdd692b029829a8c384","src/test.rs":"6388b9e8bf96e0fb56ad71b7a5b5630d209ae62f1a65c62e878cbc1757ddd585","tests/common/mod.rs":"08fb9483d9b6ed9fe873b4395245166ae8a15263be750c7a8e298c41d9604745","tests/init_fails.rs":"906bbf0faa613976623e0cf782bd86545b49d76afaab182af7634690b747ebf7","tests/never_init.rs":"19bad996e22f7d6958cc1a650528530aa7d1aeb4a8ab42229a90bbc0315c8ed1","tests/no_time_to_init.rs":"06c81148c27d383cb708c0c80a2e806024c9955337d7adfba8c53aaeade9be67","tests/overflowing_preinit.rs":"7ad4b2274dd9240b53430859a4eb1d2597cf508a5a678333f3d3abbadd2ed4a7","tests/persist_ping_lifetime.rs":"81415dc1d74743f02269f0d0dfa524003147056853f080276972e64a0b761d3c","tests/persist_ping_lifetime_nopanic.rs":"18379d3ffbf4a2c8c684c04ff7a0660b86dfbbb447db2d24dfed6073cb7ddf8f","tests/schema.rs":"9d24028cab4dc60fe3c4d7a0bafbff0815cbc0249fa3e23625d42c3b4fa71734","tests/simple.rs":"1b8b227249ae9d3cc281db07ed779bc75252c7849b1c48b4ac3d765228d65b20","tests/test-shutdown-blocking.sh":"9b16a01c190c7062474dd92182298a3d9a27928c8fa990340fdd798e6cdb7ab2","tests/test-thread-crashing.sh":"ff1bc8e5d7e4ba3a10d0d38bef222db8bfba469e7d30e45b1053d177a4084f09","tests/upload_timing.rs":"3024b7999a0c23f2c3d7e59725b5455522e4e9fdf63e3265b93fea4cec18725f"},"package":"f58388f10d013e2d12bb58e6e76983ede120789956fe827913a3d2560c66d44d"}
{"files":{"Cargo.toml":"af0535de86b60e3e08cadcdb9e61ce4a699c168608d7e9e2ebb92d949e7f31ef","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"5627cc81e6187ab6c2b4dff061af16d559edcab64ba786bac39daa69c703c595","src/common_test.rs":"de47b53dcca37985c0a2b8c02daecbf32309aa54f5a4dd9290719c2c1fd0fa55","src/configuration.rs":"27075b12236021c54d0c99427bcbd417933ca02545275604d3c13f32ca25af13","src/core_metrics.rs":"fef8fb4e5fa57c179836c6eb2cf59278fe3b8b036dbe57b0ff02971b4acd822f","src/lib.rs":"d4010f265de330081467673df05bbd45efbdfeef28823f7dc11a903b11fb8976","src/net/http_uploader.rs":"01ad5bd91384411a12c74434cd1c5cd585078cb34faba4615c70bdb669a9bccb","src/net/mod.rs":"f47b96bb878f1a6c771cedbaeaeefb270bc87fb1d1bbbed1b282dddca16216ed","src/private/event.rs":"d7c70c02648584c19c73af89e5180d3c6153c911f2c6830f7d1599b18d6150eb","src/private/mod.rs":"3565eb569d2b96f938f130abe0fc3ee3f55e7e03fd6501e309d3ef6af72ef6ee","src/private/object.rs":"3f70363a196aea46cc163af025a53e48c117c6208babc4bce772bb4c337cced8","src/private/ping.rs":"a6262a3453c77cbf30766c19b535a1bf66a37b2a316e8f87baee03025255c33e","src/system.rs":"6eae5b41c15eba9cad6dbd116abe3519ee3e1fe034e79bdd692b029829a8c384","src/test.rs":"6388b9e8bf96e0fb56ad71b7a5b5630d209ae62f1a65c62e878cbc1757ddd585","tests/common/mod.rs":"08fb9483d9b6ed9fe873b4395245166ae8a15263be750c7a8e298c41d9604745","tests/init_fails.rs":"906bbf0faa613976623e0cf782bd86545b49d76afaab182af7634690b747ebf7","tests/never_init.rs":"19bad996e22f7d6958cc1a650528530aa7d1aeb4a8ab42229a90bbc0315c8ed1","tests/no_time_to_init.rs":"06c81148c27d383cb708c0c80a2e806024c9955337d7adfba8c53aaeade9be67","tests/overflowing_preinit.rs":"7ad4b2274dd9240b53430859a4eb1d2597cf508a5a678333f3d3abbadd2ed4a7","tests/persist_ping_lifetime.rs":"81415dc1d74743f02269f0d0dfa524003147056853f080276972e64a0b761d3c","tests/persist_ping_lifetime_nopanic.rs":"18379d3ffbf4a2c8c684c04ff7a0660b86dfbbb447db2d24dfed6073cb7ddf8f","tests/schema.rs":"9615eded31a2582c8f04c729d551c0c81a57029ba62a19184221c2e1cd39baf0","tests/simple.rs":"1b8b227249ae9d3cc281db07ed779bc75252c7849b1c48b4ac3d765228d65b20","tests/test-shutdown-blocking.sh":"9b16a01c190c7062474dd92182298a3d9a27928c8fa990340fdd798e6cdb7ab2","tests/test-thread-crashing.sh":"ff1bc8e5d7e4ba3a10d0d38bef222db8bfba469e7d30e45b1053d177a4084f09","tests/upload_timing.rs":"3024b7999a0c23f2c3d7e59725b5455522e4e9fdf63e3265b93fea4cec18725f"},"package":"0ceede8fb9c90ba1b77fb8290d3ae7b62bfcb422ad1d6e46bae1c8af3f22f12d"}

View File

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.66"
name = "glean"
version = "58.1.0"
version = "59.0.0"
authors = [
"Jan-Erik Rediger <jrediger@mozilla.com>",
"The Glean Team <glean-team@mozilla.com>",
@ -35,7 +35,7 @@ license = "MPL-2.0"
repository = "https://github.com/mozilla/glean"
[dependencies.glean-core]
version = "58.1.0"
version = "59.0.0"
[dependencies.inherent]
version = "1"

View File

@ -42,7 +42,6 @@ pub(crate) fn new_glean(
Some(c) => c,
None => ConfigurationBuilder::new(true, tmpname, GLOBAL_APPLICATION_ID)
.with_server_endpoint("invalid-test-host")
.with_event_timestamps(false)
.build(),
};

View File

@ -46,6 +46,8 @@ pub struct Configuration {
/// be noted that this has an underlying StringMetric and so should conform to the limitations that
/// StringMetric places on length, etc.
pub experimentation_id: Option<String>,
/// Whether to enable internal pings. Default: true
pub enable_internal_pings: bool,
}
/// Configuration builder.
@ -92,6 +94,8 @@ pub struct Builder {
/// be noted that this has an underlying StringMetric and so should conform to the limitations that
/// StringMetric places on length, etc.
pub experimentation_id: Option<String>,
/// Whether to enable internal pings. Default: true
pub enable_internal_pings: bool,
}
impl Builder {
@ -115,6 +119,7 @@ impl Builder {
rate_limit: None,
enable_event_timestamps: true,
experimentation_id: None,
enable_internal_pings: true,
}
}
@ -134,6 +139,7 @@ impl Builder {
rate_limit: self.rate_limit,
enable_event_timestamps: self.enable_event_timestamps,
experimentation_id: self.experimentation_id,
enable_internal_pings: self.enable_internal_pings,
}
}
@ -184,4 +190,10 @@ impl Builder {
self.experimentation_id = Some(value);
self
}
/// Set whether to enable internal pings.
pub fn with_internal_pings(mut self, value: bool) -> Self {
self.enable_internal_pings = value;
self
}
}

View File

@ -122,6 +122,7 @@ fn initialize_internal(cfg: Configuration, client_info: ClientInfoMetrics) -> Op
rate_limit: cfg.rate_limit,
enable_event_timestamps: cfg.enable_event_timestamps,
experimentation_id: cfg.experimentation_id,
enable_internal_pings: cfg.enable_internal_pings,
};
glean_core::glean_initialize(core_cfg, client_info.into(), callbacks);

View File

@ -6,8 +6,7 @@ use std::collections::HashMap;
use std::io::Read;
use flate2::read::GzDecoder;
use glean_core::TextMetric;
use jsonschema_valid::{self, schemas::Draft};
use jsonschema_valid::schemas::Draft;
use serde_json::Value;
use glean::net::{PingUploadRequest, UploadResult};

View File

@ -1 +1 @@
{"files":{"CHANGELOG.md":"ade9f25d4bd1545f2ff2661d6a1301fe228cf2551a9cb27fcaa17c8119b73c8b","Cargo.toml":"09b271ef4ee3491cb1f6309cef8b60471b960c057c6e57fc90ed579adcc57453","LICENSE":"036bf6b6d6fd6dd1abda2ff6cdb672a63bdf32c468048720072910f2268a965f","README.md":"c09b08f3d5e7e33c4a8fd647708d313ee2ba98b165a1d077fb90f280dcb4da31","src/archive/mod.rs":"ae739638d7267011bedf51712516d3485171d8f2df2ab6746a0d942d86efd6a6","src/elf/compression_header.rs":"2eb5fdda9177c1c897310d86714967de019b39c6e23b1f3a890dd3a659be0acc","src/elf/constants_header.rs":"f2ede290ecacf60b1719e9994aa45612bf0f7baf63806a293d4530a674e5861a","src/elf/constants_relocation.rs":"a010071cd2a25ab71e0c7181eb1d9f417daa2d1ec25a09c74bd12ad944892225","src/elf/dynamic.rs":"c26e75311f2da9e34dc4c0a2120dfcc20df88a41d67c52b9bf703258de018fd8","src/elf/gnu_hash.rs":"7a9fcaf6cb38167d20527364bdf9bc2379c44dede5d7666275a1eb20dc665179","src/elf/header.rs":"3391a1fa9b8e3923f7ce74caff0668d8ddb5b34767bf3da309ff497fd81c34c7","src/elf/mod.rs":"2ee0faa0917deb5e90ca60e9c852434745a4c7f553e609e9603a57b7d55b739f","src/elf/note.rs":"bf5e45e2697f7700d5adbb52f890ea4c63b70b7077ca0e7c751420bb92923529","src/elf/program_header.rs":"4c322eb124c4e2bdeec4915067d2bb11fe9e7fba1811dc351a3f7581df121da0","src/elf/reloc.rs":"8b29162055b2846342b49e5e9e0a1482786fb92b4787bb9eb1c6d04f38b94e87","src/elf/section_header.rs":"f55f4d263f618bd1dec76ff0483f3b2dc3791c8e5c5c2b6ff296a5bc26001666","src/elf/sym.rs":"045c01107f4e100d6827cb819b82a28ea10c0d9bc00a1cdddb04a0865f1162ec","src/elf/symver.rs":"3f899201f64a702653d44288f860003e7acd75e38111d36479af823ed92b1341","src/error.rs":"af620a5692bca070dc727d49cdbb566a533bfb97724ca68932ae7fec7dc05cf6","src/lib.rs":"465eb53b540dfd142d204984ee7280130542d7f83d6c53691299d773f7394faf","src/mach/bind_opcodes.rs":"1dcacfb853d05c2c7e6dbb4509ee705a8ea645db0d334991a2293fef92eee851","src/mach/constants.rs":"c2a2381a0b9c3047d37582465e8965d995dca414d0da21fb7bcc6b8334e49eb6","src/mach/exports.rs":"d22122744673a3ce5f54b2b4b20bfa47d17378e64d3dda2858dd13add74ed3dc","src/mach/fat.rs":"45a3228aaa1ab8b77f322dd4924b7383f1357e226ffc079846d67c0268389ea7","src/mach/header.rs":"006619188f51fa43051dc04aa4b2ecd5f89136cf05cb6a7b23a228228008e6ae","src/mach/imports.rs":"2153269dfff32e23d72f76a82d658be06bd79b7e35d79b7e17115e4eb24b13d5","src/mach/load_command.rs":"0a689e774ae96212666165909c026037f22a3c4e3645250b9bae60c957d50ca4","src/mach/mod.rs":"53ad219fd2265a5689ab38d5031722268eab6bbb649c75756e74295df4b611b7","src/mach/relocation.rs":"11b0b76ed7d997c87e396100515f931fe84473c228bed0e980fbab311530070a","src/mach/segment.rs":"0dc29bf42b25f60c7258bc8b757f6a862e846582dd6d2e70737933ad6334a0e4","src/mach/symbols.rs":"d2505fa8d65ea267abfcb6a9fc4d1acd47d5605aa6775935757e2fa8e92af507","src/pe/authenticode.rs":"c3df9266c4f0a865e0da4b10fa1494eca083953fc4ded0b707b547a7d4ef296a","src/pe/certificate_table.rs":"75ab5dce6bc0c28d3687a5c119c0fa0d00e4796c8959a32d9d208f2369273c50","src/pe/characteristic.rs":"6f810a6e5646b922cf7e3ca6d314677a4e1e1ad5695278c2b1b527a05f4299f3","src/pe/data_directories.rs":"d4e156f0c5b509860ceb3c7d42e1621e6c2143b90fc412806b3cefab1acc577a","src/pe/debug.rs":"3811c616a9b6d6b54e15348bb369b794bb89532e04fe19eca91b745d7c51a553","src/pe/exception.rs":"de2c9c07812ecd315c8400fc8fdcadc6a44d7a8be96e69a3f4ccf14ef8cf8426","src/pe/export.rs":"c98f5ce0b1b18bb87f06d1d41dbf70f443d65ecb1624cb23a1ef6c5f93a892e1","src/pe/header.rs":"f02a4beddc00ddd6624df7defc42991ceb507360b5aa1003cf33332c1c89a743","src/pe/import.rs":"855276e46c01ccd7631104e4d1265592e36c9468aadcacc937a40c29d94aabe3","src/pe/mod.rs":"ec958ee9a717672dec7b56d9d7d33e444c37eb781f299a920a60eb7fa39ef7a1","src/pe/optional_header.rs":"4fd94187fb343756817f23ccc58ec035a1b462b69457c706d9e2f11225d0cb1c","src/pe/options.rs":"b38f4e87f13ae381712621786f89e931452b2b4857a7bb6f140c4c21a63aa652","src/pe/relocation.rs":"c479b80bb1d6910f2168505dda4f2d8925b7edc34bed4e25d069546f88f52bb3","src/pe/section_table.rs":"d7144c7be3242d7aa653d22dca1cf15f7110f79a946a15cbe6ecf531e0cacb19","src/pe/symbol.rs":"9a65226c93c4499e21d094ceb838d58db706951580a1c43dfb36b95dbaff70f0","src/pe/utils.rs":"88e1cd9114c5d4ad58a09c39b312689de20ddd7382654ec660b00424f5c3129c","src/strtab.rs":"6d122084cf5d5244b2bd734b1d6d2c018116cc537ffc0c81d042d5b8815d7782","tests/bins/elf/gnu_hash/README.md":"52581e2ea7067a55bd8aedf4079200fb76448573ae9ffef7d886b9556e980db9"},"package":"f27c1b4369c2cd341b5de549380158b105a04c331be5db9110eef7b6d2742134"}
{"files":{"CHANGELOG.md":"2d45bc2d0db50fd4416e2123f8b98c7288935b3be7985bdd115ecbd236acea41","Cargo.toml":"0d8dade295950e9f63574e7a74390ddec56c039cb44d2507df7e6ff832b49a0d","LICENSE":"036bf6b6d6fd6dd1abda2ff6cdb672a63bdf32c468048720072910f2268a965f","README.md":"302466b411dc5bc705cdf563b928c14755342ab6f2dff371be064446fa0aa0a9","src/archive/mod.rs":"ae739638d7267011bedf51712516d3485171d8f2df2ab6746a0d942d86efd6a6","src/elf/compression_header.rs":"2eb5fdda9177c1c897310d86714967de019b39c6e23b1f3a890dd3a659be0acc","src/elf/constants_header.rs":"f2ede290ecacf60b1719e9994aa45612bf0f7baf63806a293d4530a674e5861a","src/elf/constants_relocation.rs":"a010071cd2a25ab71e0c7181eb1d9f417daa2d1ec25a09c74bd12ad944892225","src/elf/dynamic.rs":"c26e75311f2da9e34dc4c0a2120dfcc20df88a41d67c52b9bf703258de018fd8","src/elf/gnu_hash.rs":"7a9fcaf6cb38167d20527364bdf9bc2379c44dede5d7666275a1eb20dc665179","src/elf/header.rs":"3391a1fa9b8e3923f7ce74caff0668d8ddb5b34767bf3da309ff497fd81c34c7","src/elf/mod.rs":"2ee0faa0917deb5e90ca60e9c852434745a4c7f553e609e9603a57b7d55b739f","src/elf/note.rs":"bf5e45e2697f7700d5adbb52f890ea4c63b70b7077ca0e7c751420bb92923529","src/elf/program_header.rs":"4c322eb124c4e2bdeec4915067d2bb11fe9e7fba1811dc351a3f7581df121da0","src/elf/reloc.rs":"a5d21f9d1ddae8e730e852fcaf1cd2dd194e35fbac8f86fb8fd9033a03bdc66d","src/elf/section_header.rs":"f55f4d263f618bd1dec76ff0483f3b2dc3791c8e5c5c2b6ff296a5bc26001666","src/elf/sym.rs":"045c01107f4e100d6827cb819b82a28ea10c0d9bc00a1cdddb04a0865f1162ec","src/elf/symver.rs":"3f899201f64a702653d44288f860003e7acd75e38111d36479af823ed92b1341","src/error.rs":"a1bb56d82db52ac627e55b163f489f06a78c939a8ccfdec210b4f726d6ed6e9d","src/lib.rs":"f29832bdf7d7f7d9e34f65704afea2710d578df60cc171dd179b5ce889faaf12","src/mach/bind_opcodes.rs":"1dcacfb853d05c2c7e6dbb4509ee705a8ea645db0d334991a2293fef92eee851","src/mach/constants.rs":"c2a2381a0b9c3047d37582465e8965d995dca414d0da21fb7bcc6b8334e49eb6","src/mach/exports.rs":"d22122744673a3ce5f54b2b4b20bfa47d17378e64d3dda2858dd13add74ed3dc","src/mach/fat.rs":"45a3228aaa1ab8b77f322dd4924b7383f1357e226ffc079846d67c0268389ea7","src/mach/header.rs":"006619188f51fa43051dc04aa4b2ecd5f89136cf05cb6a7b23a228228008e6ae","src/mach/imports.rs":"2153269dfff32e23d72f76a82d658be06bd79b7e35d79b7e17115e4eb24b13d5","src/mach/load_command.rs":"42e6f0973092185db233230e71e9312bbac7c2e1090bb6d713804020319dfa33","src/mach/mod.rs":"53ad219fd2265a5689ab38d5031722268eab6bbb649c75756e74295df4b611b7","src/mach/relocation.rs":"11b0b76ed7d997c87e396100515f931fe84473c228bed0e980fbab311530070a","src/mach/segment.rs":"0dc29bf42b25f60c7258bc8b757f6a862e846582dd6d2e70737933ad6334a0e4","src/mach/symbols.rs":"d2505fa8d65ea267abfcb6a9fc4d1acd47d5605aa6775935757e2fa8e92af507","src/pe/authenticode.rs":"ad9c77e42392b49114cf8ce2839111f3231dcfe21cbb8e402ee14e568f5ae657","src/pe/certificate_table.rs":"f6c31ba518d9fc4b6e12d2f24d6c9d58b21b341a1f189cbcf2aae0ae51304ad3","src/pe/characteristic.rs":"6f810a6e5646b922cf7e3ca6d314677a4e1e1ad5695278c2b1b527a05f4299f3","src/pe/data_directories.rs":"d0352ccc03e0ab2935235e91b391cc55828406087f026f90ec11ca5906fd8c8c","src/pe/debug.rs":"3811c616a9b6d6b54e15348bb369b794bb89532e04fe19eca91b745d7c51a553","src/pe/exception.rs":"de2c9c07812ecd315c8400fc8fdcadc6a44d7a8be96e69a3f4ccf14ef8cf8426","src/pe/export.rs":"c98f5ce0b1b18bb87f06d1d41dbf70f443d65ecb1624cb23a1ef6c5f93a892e1","src/pe/header.rs":"879c2ddc8318ab37b4577ac34241fa039d106e0e530dab07edfc9b4e13b08356","src/pe/import.rs":"855276e46c01ccd7631104e4d1265592e36c9468aadcacc937a40c29d94aabe3","src/pe/mod.rs":"ffaeca313ea2fb31c41eb0ede0ef28fede2276b0bb7d81dfc08b4ead6289600d","src/pe/optional_header.rs":"4048151649a7fe3f8f2d7bb67e784bae889eeb1651bf924f9fbe92400b809217","src/pe/options.rs":"457877197f768c331437297d787dc718b1053b813e3a1dd9b968133fb1540d44","src/pe/relocation.rs":"c479b80bb1d6910f2168505dda4f2d8925b7edc34bed4e25d069546f88f52bb3","src/pe/section_table.rs":"e4b1a2f78c2336aaa0355b5ef102dbe29138c4fa1ba29ed3f379aad1fc64bdff","src/pe/symbol.rs":"1a5fb5bec5727752a6506682ed2ab57829ea810f21f951932a0107861ec0e092","src/pe/utils.rs":"e6da9979ba5f2ae7d1274eef8230cdc4dd90c90a79c7bb9438f8b8ff0aef74be","src/strtab.rs":"dcbd0592c7f032980d112a5f752c175fe8dd257a948892e1f060d25ab52328f5","tests/bins/elf/gnu_hash/README.md":"52581e2ea7067a55bd8aedf4079200fb76448573ae9ffef7d886b9556e980db9"},"package":"bb07a4ffed2093b118a525b1d8f5204ae274faed5604537caf7135d0f18d9887"}

View File

@ -3,9 +3,32 @@ All notable changes to this project will be documented in this file.
Before 1.0, this project does not adhere to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
Goblin is now 0.7, which means we will try our best to ease breaking changes. Tracking issue is here: https://github.com/m4b/goblin/issues/97
Goblin is now 0.8, which means we will try our best to ease breaking changes. Tracking issue is here: https://github.com/m4b/goblin/issues/97
## [0.7.0] - unreleased
## [0.8.0] - 2023-12-31 - Happy New Years!
### Breaking
msrv: bumped to 1.63.0 since scroll bumped as well
pe: new field added to parse options: https://github.com/m4b/goblin/pull/377
pe: attribute certs now non-exhaustive: https://github.com/m4b/goblin/pull/378
goblin: hint and object enum is now non-exhaustive
pe: write support introduced some breaking changes, e.g., data directories array adds a tuple of usize and data directory,
DosHeader has all the fields filled out, Header struct has a dos_stub field added,
symbols and strings fields is made optional in Coff struct, see: https://github.com/m4b/goblin/pull/361
### Fixed
elf: fix documentation, thanks @crzysdrs: https://github.com/m4b/goblin/pull/374
pe: attribute certificates non-exhaustive, thanks @RaitoBezarius: https://github.com/m4b/goblin/pull/378
pe: fix authenticode parsing, thanks @baloo: https://github.com/m4b/goblin/pull/383
### Added
strtab: len method added to return number of bytes of the strtab
pe: absolutely epic pe write support PR, thanks @RaitoBezarius and @Baloo: https://github.com/m4b/goblin/pull/361
pe: add coff object file support, thanks @vadimcn, https://github.com/m4b/goblin/pull/379
pe: allow toggling parsing of attribute certs, thanks @suttonbradley: https://github.com/m4b/goblin/pull/377
mach: add new mach-o constants, thanks @keith: https://github.com/m4b/goblin/pull/372
## [0.7.1] - 2023-6-11
### MSRV bump from log
## [0.7.0] - 2023-6-11
### Breaking
mach: Implement `LC_NOTE`, (breakage=load commands are marked non-exhaustive), thanks @messense: https://github.com/m4b/goblin/pull/342
### Fixed

View File

@ -11,9 +11,9 @@
[package]
edition = "2021"
rust-version = "1.60.0"
rust-version = "1.63.0"
name = "goblin"
version = "0.7.1"
version = "0.8.0"
authors = [
"m4b <m4b.github.io@gmail.com>",
"seu <seu@panopticon.re>",
@ -44,6 +44,7 @@ categories = [
]
license = "MIT"
repository = "https://github.com/m4b/goblin"
resolver = "2"
[dependencies.log]
version = "0.4"
@ -54,9 +55,12 @@ default-features = false
version = "0.2.3"
[dependencies.scroll]
version = "0.11"
version = "0.12"
default_features = false
[dev-dependencies.stderrlog]
version = "0.5.4"
[features]
alloc = [
"scroll/derive",

View File

@ -20,13 +20,13 @@ https://docs.rs/goblin/
### Usage
Goblin requires `rustc` 1.60.0 (Rust 2021 edition).
Goblin requires `rustc` 1.63.0 (Rust 2021 edition).
Add to your `Cargo.toml`
```toml
[dependencies]
goblin = "0.7"
goblin = "0.8"
```
### Features
@ -190,6 +190,7 @@ In lexicographic order:
[@baloo]: https://github.com/baloo
[@burjui]: https://github.com/burjui
[@connorkuehl]: https://github.com/connorkuehl
[@crzysdrs]: https://github.com/crzysdrs
[@dancrossnyc]: https://github.com/dancrossnyc
[@dureuill]: https://github.com/dureuill
[@Evian-Zhang]: https://github.com/Evian-Zhang
@ -238,6 +239,7 @@ In lexicographic order:
[@sanxiyn]: https://github.com/sanxiyn
[@skdltmxn]: https://github.com/skdltmxn
[@sollyucko]: https://github.com/sollyucko
[@suttonbradley]: https://github.com/suttonbradley
[@Swatinem]: https://github.com/Swatinem
[@SweetVishnya]: https://github.com/SweetVishnya
[@SquareMan]: https://github.com/SquareMan
@ -248,6 +250,7 @@ In lexicographic order:
[@Tiwalun]: https://github.com/Tiwalun
[@track-5]: https://github.com/track-5
[@tux3]: https://github.com/tux3
[@vadimcn]: https://github.com/vadimcn
[@wickerwacka]: https://github.com/wickerwaka
[@willglynn]: https://github.com/willglynn
[@woodruffw]: https://github.com/woodruffw

View File

@ -51,7 +51,7 @@
//! | `R_X86_64_GOTPC32` | 26 | 32 | GOT + A - P |
//! | `R_X86_64_SIZE32` | 32 | 32 | Z + A |
//! | `R_X86_64_SIZE64` | 33 | 64 | Z + A |
//! | `R_X86_64_GOTPC32_TLSDESC` 34 | 32 | |
//! | `R_X86_64_GOTPC32_TLSDESC`| 34 | 32 | |
//! | `R_X86_64_TLSDESC_CALL` | 35 | NONE | |
//! | `R_X86_64_TLSDESC` | 36 | 64 × 2 | |
//! | `R_X86_64_IRELATIVE` | 37 | 64 | indirect (B + A) |

View File

@ -3,6 +3,7 @@
use alloc::string::String;
use core::fmt;
use core::num::TryFromIntError;
use core::result;
#[cfg(feature = "std")]
use std::{error, io};
@ -42,6 +43,12 @@ impl From<io::Error> for Error {
}
}
impl From<TryFromIntError> for Error {
fn from(err: TryFromIntError) -> Error {
Error::Malformed(format!("Integer do not fit: {err}"))
}
}
impl From<scroll::Error> for Error {
fn from(err: scroll::Error) -> Error {
Error::Scroll(err)

View File

@ -42,13 +42,17 @@
//! Object::PE(pe) => {
//! println!("pe: {:#?}", &pe);
//! },
//! Object::COFF(coff) => {
//! println!("coff: {:#?}", &coff);
//! },
//! Object::Mach(mach) => {
//! println!("mach: {:#?}", &mach);
//! },
//! Object::Archive(archive) => {
//! println!("archive: {:#?}", &archive);
//! },
//! Object::Unknown(magic) => { println!("unknown magic: {:#x}", magic) }
//! Object::Unknown(magic) => { println!("unknown magic: {:#x}", magic) },
//! _ => { }
//! }
//! }
//! }
@ -218,12 +222,14 @@ pub struct HintData {
}
#[derive(Debug)]
#[non_exhaustive]
/// A hint at the underlying binary format for 16 bytes of arbitrary data
pub enum Hint {
Elf(HintData),
Mach(HintData),
MachFat(usize),
PE,
COFF,
Archive,
Unknown(u64),
}
@ -253,10 +259,14 @@ if_everything! {
Ok(Hint::Elf(HintData { is_lsb, is_64 }))
} else if &bytes[0..archive::SIZEOF_MAGIC] == archive::MAGIC {
Ok(Hint::Archive)
} else if (&bytes[0..2]).pread_with::<u16>(0, LE)? == pe::header::DOS_MAGIC {
Ok(Hint::PE)
} else {
mach::peek_bytes(bytes)
match *&bytes[0..2].pread_with::<u16>(0, LE)? {
pe::header::DOS_MAGIC => Ok(Hint::PE),
pe::header::COFF_MACHINE_X86 |
pe::header::COFF_MACHINE_X86_64 |
pe::header::COFF_MACHINE_ARM64 => Ok(Hint::COFF),
_ => mach::peek_bytes(bytes)
}
}
}
@ -273,12 +283,15 @@ if_everything! {
#[derive(Debug)]
#[allow(clippy::large_enum_variant)]
#[non_exhaustive]
/// A parseable object that goblin understands
pub enum Object<'a> {
/// An ELF32/ELF64!
Elf(elf::Elf<'a>),
/// A PE32/PE32+!
PE(pe::PE<'a>),
/// A COFF
COFF(pe::Coff<'a>),
/// A 32/64-bit Mach-o binary _OR_ it is a multi-architecture binary container!
Mach(mach::Mach<'a>),
/// A Unix archive
@ -296,7 +309,8 @@ if_everything! {
Hint::Mach(_) | Hint::MachFat(_) => Ok(Object::Mach(mach::Mach::parse(bytes)?)),
Hint::Archive => Ok(Object::Archive(archive::Archive::parse(bytes)?)),
Hint::PE => Ok(Object::PE(pe::PE::parse(bytes)?)),
Hint::Unknown(magic) => Ok(Object::Unknown(magic))
Hint::COFF => Ok(Object::COFF(pe::Coff::parse(bytes)?)),
Hint::Unknown(magic) => Ok(Object::Unknown(magic)),
}
} else {
Err(error::Error::Malformed(format!("Object is too small.")))

View File

@ -1343,9 +1343,12 @@ pub const PLATFORM_IOSSIMULATOR: u32 = 7;
pub const PLATFORM_TVOSSIMULATOR: u32 = 8;
pub const PLATFORM_WATCHOSSIMULATOR: u32 = 9;
pub const PLATFORM_DRIVERKIT: u32 = 10;
pub const PLATFORM_VISIONOS: u32 = 11;
pub const PLATFORM_VISIONOSSIMULATOR: u32 = 12;
pub const TOOL_CLANG: u32 = 1;
pub const TOOL_SWIFT: u32 = 2;
pub const TOOL_LD: u32 = 3;
pub const TOOL_LLD: u32 = 4;
pub fn cmd_to_str(cmd: u32) -> &'static str {
match cmd {

View File

@ -8,9 +8,13 @@
// - data directory entry for certtable
// - certtable
use alloc::collections::VecDeque;
use core::ops::Range;
use log::debug;
use super::PE;
use super::{section_table::SectionTable, PE};
static PADDING: [u8; 7] = [0; 7];
impl PE<'_> {
/// [`authenticode_ranges`] returns the various ranges of the binary that are relevant for
@ -19,6 +23,7 @@ impl PE<'_> {
ExcludedSectionsIter {
pe: self,
state: IterState::default(),
sections: VecDeque::default(),
}
}
}
@ -29,19 +34,22 @@ impl PE<'_> {
pub(super) struct ExcludedSections {
checksum: Range<usize>,
datadir_entry_certtable: Range<usize>,
certtable: Option<Range<usize>>,
certificate_table_size: usize,
end_image_header: usize,
}
impl ExcludedSections {
pub(super) fn new(
checksum: Range<usize>,
datadir_entry_certtable: Range<usize>,
certtable: Option<Range<usize>>,
certificate_table_size: usize,
end_image_header: usize,
) -> Self {
Self {
checksum,
datadir_entry_certtable,
certtable,
certificate_table_size,
end_image_header,
}
}
}
@ -49,14 +57,26 @@ impl ExcludedSections {
pub struct ExcludedSectionsIter<'s> {
pe: &'s PE<'s>,
state: IterState,
sections: VecDeque<SectionTable>,
}
#[derive(Debug, PartialEq)]
enum IterState {
Initial,
DatadirEntry(usize),
CertTable(usize),
Final(usize),
ChecksumEnd(usize),
CertificateTableEnd(usize),
HeaderEnd {
end_image_header: usize,
sum_of_bytes_hashed: usize,
},
Sections {
tail: usize,
sum_of_bytes_hashed: usize,
},
Final {
sum_of_bytes_hashed: usize,
},
Padding(usize),
Done,
}
@ -76,24 +96,166 @@ impl<'s> Iterator for ExcludedSectionsIter<'s> {
loop {
match self.state {
IterState::Initial => {
self.state = IterState::DatadirEntry(sections.checksum.end);
return Some(&bytes[..sections.checksum.start]);
// 3. Hash the image header from its base to immediately before the start of the
// checksum address, as specified in Optional Header Windows-Specific Fields.
let out = Some(&bytes[..sections.checksum.start]);
debug!("hashing {:#x} {:#x}", 0, sections.checksum.start);
// 4. Skip over the checksum, which is a 4-byte field.
debug_assert_eq!(sections.checksum.end - sections.checksum.start, 4);
self.state = IterState::ChecksumEnd(sections.checksum.end);
return out;
}
IterState::DatadirEntry(start) => {
self.state = IterState::CertTable(sections.datadir_entry_certtable.end);
return Some(&bytes[start..sections.datadir_entry_certtable.start]);
IterState::ChecksumEnd(checksum_end) => {
// 5. Hash everything from the end of the checksum field to immediately before the start
// of the Certificate Table entry, as specified in Optional Header Data Directories.
let out =
Some(&bytes[checksum_end..sections.datadir_entry_certtable.start]);
debug!(
"hashing {checksum_end:#x} {:#x}",
sections.datadir_entry_certtable.start
);
// 6. Get the Attribute Certificate Table address and size from the Certificate Table entry.
// For details, see section 5.7 of the PE/COFF specification.
// 7. Exclude the Certificate Table entry from the calculation
self.state =
IterState::CertificateTableEnd(sections.datadir_entry_certtable.end);
return out;
}
IterState::CertTable(start) => {
if let Some(certtable) = sections.certtable.as_ref() {
self.state = IterState::Final(certtable.end);
return Some(&bytes[start..certtable.start]);
IterState::CertificateTableEnd(start) => {
// 7. Exclude the Certificate Table entry from the calculation and hash everything from
// the end of the Certificate Table entry to the end of image header, including
// Section Table (headers). The Certificate Table entry is 8 bytes long, as specified
// in Optional Header Data Directories.
let end_image_header = sections.end_image_header;
let buf = Some(&bytes[start..end_image_header]);
debug!("hashing {start:#x} {:#x}", end_image_header - start);
// 8. Create a counter called SUM_OF_BYTES_HASHED, which is not part of the signature.
// Set this counter to the SizeOfHeaders field, as specified in
// Optional Header Windows-Specific Field.
let sum_of_bytes_hashed = end_image_header;
self.state = IterState::HeaderEnd {
end_image_header,
sum_of_bytes_hashed,
};
return buf;
}
IterState::HeaderEnd {
end_image_header,
sum_of_bytes_hashed,
} => {
// 9. Build a temporary table of pointers to all of the section headers in the
// image. The NumberOfSections field of COFF File Header indicates how big
// the table should be. Do not include any section headers in the table whose
// SizeOfRawData field is zero.
// Implementation detail:
// We require allocation here because the section table has a variable size and
// needs to be sorted.
let mut sections: VecDeque<SectionTable> = self
.pe
.sections
.iter()
.filter(|section| section.size_of_raw_data != 0)
.cloned()
.collect();
// 10. Using the PointerToRawData field (offset 20) in the referenced SectionHeader
// structure as a key, arrange the table's elements in ascending order. In
// other words, sort the section headers in ascending order according to the
// disk-file offset of the sections.
sections
.make_contiguous()
.sort_by_key(|section| section.pointer_to_raw_data);
self.sections = sections;
self.state = IterState::Sections {
tail: end_image_header,
sum_of_bytes_hashed,
};
}
IterState::Sections {
mut tail,
mut sum_of_bytes_hashed,
} => {
// 11. Walk through the sorted table, load the corresponding section into memory,
// and hash the entire section. Use the SizeOfRawData field in the SectionHeader
// structure to determine the amount of data to hash.
if let Some(section) = self.sections.pop_front() {
let start = section.pointer_to_raw_data as usize;
let end = start + section.size_of_raw_data as usize;
tail = end;
// 12. Add the sections SizeOfRawData value to SUM_OF_BYTES_HASHED.
sum_of_bytes_hashed += section.size_of_raw_data as usize;
debug!("hashing {start:#x} {:#x}", end - start);
let buf = &bytes[start..end];
// 13. Repeat steps 11 and 12 for all of the sections in the sorted table.
self.state = IterState::Sections {
tail,
sum_of_bytes_hashed,
};
return Some(buf);
} else {
self.state = IterState::Final(start)
self.state = IterState::Final {
sum_of_bytes_hashed,
};
}
}
IterState::Final(start) => {
IterState::Final {
sum_of_bytes_hashed,
} => {
// 14. Create a value called FILE_SIZE, which is not part of the signature.
// Set this value to the images file size, acquired from the underlying
// file system. If FILE_SIZE is greater than SUM_OF_BYTES_HASHED, the
// file contains extra data that must be added to the hash. This data
// begins at the SUM_OF_BYTES_HASHED file offset, and its length is:
// (File Size) - ((Size of AttributeCertificateTable) + SUM_OF_BYTES_HASHED)
//
// Note: The size of Attribute Certificate Table is specified in the second
// ULONG value in the Certificate Table entry (32 bit: offset 132,
// 64 bit: offset 148) in Optional Header Data Directories.
let file_size = bytes.len();
// If FILE_SIZE is not a multiple of 8 bytes, the data added to the hash must
// be appended with zero padding of length (8 (FILE_SIZE % 8)) bytes
let pad_size = (8 - file_size % 8) % 8;
self.state = IterState::Padding(pad_size);
if file_size > sum_of_bytes_hashed {
let extra_data_start = sum_of_bytes_hashed;
let len =
file_size - sections.certificate_table_size - sum_of_bytes_hashed;
debug!("hashing {extra_data_start:#x} {len:#x}",);
let buf = &bytes[extra_data_start..extra_data_start + len];
return Some(buf);
}
}
IterState::Padding(pad_size) => {
self.state = IterState::Done;
return Some(&bytes[start..]);
if pad_size != 0 {
debug!("hashing {pad_size:#x}");
// NOTE (safety): pad size will be at most 7, and PADDING has a size of 7
// pad_size is computed ~10 lines above.
debug_assert!(pad_size <= 7);
debug_assert_eq!(PADDING.len(), 7);
return Some(&PADDING[..pad_size]);
}
}
IterState::Done => return None,
}

View File

@ -3,12 +3,15 @@
/// https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#the-attribute-certificate-table-image-only
/// https://learn.microsoft.com/en-us/windows/win32/api/wintrust/ns-wintrust-win_certificate
use crate::error;
use scroll::Pread;
use scroll::{ctx, Pread, Pwrite};
use alloc::string::ToString;
use alloc::vec::Vec;
use super::utils::pad;
#[repr(u16)]
#[non_exhaustive]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum AttributeCertificateRevision {
/// WIN_CERT_REVISION_1_0
@ -38,7 +41,7 @@ impl TryFrom<u16> for AttributeCertificateRevision {
}
#[repr(u16)]
#[derive(Debug)]
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum AttributeCertificateType {
/// WIN_CERT_TYPE_X509
X509 = 0x0001,
@ -127,7 +130,28 @@ impl<'a> AttributeCertificate<'a> {
}
}
impl<'a> ctx::TryIntoCtx<scroll::Endian> for &AttributeCertificate<'a> {
type Error = error::Error;
/// Writes an aligned attribute certificate in the buffer.
fn try_into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) -> Result<usize, Self::Error> {
let offset = &mut 0;
bytes.gwrite_with(self.length, offset, ctx)?;
bytes.gwrite_with(self.revision as u16, offset, ctx)?;
bytes.gwrite_with(self.certificate_type as u16, offset, ctx)?;
// Extend by zero the buffer until it is aligned on a quadword (16 bytes).
let maybe_certificate_padding = pad(self.certificate.len(), Some(16usize));
bytes.gwrite(self.certificate, offset)?;
if let Some(cert_padding) = maybe_certificate_padding {
bytes.gwrite(&cert_padding[..], offset)?;
}
Ok(*offset)
}
}
pub type CertificateDirectoryTable<'a> = Vec<AttributeCertificate<'a>>;
pub(crate) fn enumerate_certificates(
bytes: &[u8],
table_virtual_address: u32,

View File

@ -1,5 +1,8 @@
use crate::error;
use scroll::{Pread, Pwrite, SizeWith};
use scroll::{
ctx::{self},
Pread, Pwrite, SizeWith,
};
#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone, Default, Pread, Pwrite, SizeWith)]
@ -13,14 +16,86 @@ const NUM_DATA_DIRECTORIES: usize = 16;
impl DataDirectory {
pub fn parse(bytes: &[u8], offset: &mut usize) -> error::Result<Self> {
let dd = bytes.gread_with(offset, scroll::LE)?;
Ok(dd)
Ok(bytes.gread_with(offset, scroll::LE)?)
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum DataDirectoryType {
ExportTable,
ImportTable,
ResourceTable,
ExceptionTable,
CertificateTable,
BaseRelocationTable,
DebugTable,
Architecture,
GlobalPtr,
TlsTable,
LoadConfigTable,
BoundImportTable,
ImportAddressTable,
DelayImportDescriptor,
ClrRuntimeHeader,
}
impl TryFrom<usize> for DataDirectoryType {
type Error = error::Error;
fn try_from(value: usize) -> Result<Self, Self::Error> {
Ok(match value {
0 => Self::ExportTable,
1 => Self::ImportTable,
2 => Self::ResourceTable,
3 => Self::ExceptionTable,
4 => Self::CertificateTable,
5 => Self::BaseRelocationTable,
6 => Self::DebugTable,
7 => Self::Architecture,
8 => Self::GlobalPtr,
9 => Self::TlsTable,
10 => Self::LoadConfigTable,
11 => Self::BoundImportTable,
12 => Self::ImportAddressTable,
13 => Self::DelayImportDescriptor,
14 => Self::ClrRuntimeHeader,
_ => {
return Err(error::Error::Malformed(
"Wrong data directory index number".into(),
))
}
})
}
}
#[derive(Debug, PartialEq, Copy, Clone, Default)]
pub struct DataDirectories {
pub data_directories: [Option<DataDirectory>; NUM_DATA_DIRECTORIES],
pub data_directories: [Option<(usize, DataDirectory)>; NUM_DATA_DIRECTORIES],
}
impl ctx::TryIntoCtx<scroll::Endian> for DataDirectories {
type Error = error::Error;
fn try_into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) -> Result<usize, Self::Error> {
let offset = &mut 0;
for opt_dd in self.data_directories {
if let Some((dd_offset, dd)) = opt_dd {
bytes.pwrite_with(dd, dd_offset, ctx)?;
*offset += dd_offset;
} else {
bytes.gwrite(&[0; SIZEOF_DATA_DIRECTORY][..], offset)?;
}
}
Ok(NUM_DATA_DIRECTORIES * SIZEOF_DATA_DIRECTORY)
}
}
macro_rules! build_dd_getter {
($dd_name:tt, $index:tt) => {
pub fn $dd_name(&self) -> Option<&DataDirectory> {
let idx = $index;
self.data_directories[idx].as_ref().map(|(_, dd)| dd)
}
};
}
impl DataDirectories {
@ -37,70 +112,42 @@ impl DataDirectories {
let dd = if dd.virtual_address == 0 && dd.size == 0 {
None
} else {
Some(dd)
Some((*offset, dd))
};
*dir = dd;
}
Ok(DataDirectories { data_directories })
}
pub fn get_export_table(&self) -> &Option<DataDirectory> {
let idx = 0;
&self.data_directories[idx]
}
pub fn get_import_table(&self) -> &Option<DataDirectory> {
let idx = 1;
&self.data_directories[idx]
}
pub fn get_resource_table(&self) -> &Option<DataDirectory> {
let idx = 2;
&self.data_directories[idx]
}
pub fn get_exception_table(&self) -> &Option<DataDirectory> {
let idx = 3;
&self.data_directories[idx]
}
pub fn get_certificate_table(&self) -> &Option<DataDirectory> {
let idx = 4;
&self.data_directories[idx]
}
pub fn get_base_relocation_table(&self) -> &Option<DataDirectory> {
let idx = 5;
&self.data_directories[idx]
}
pub fn get_debug_table(&self) -> &Option<DataDirectory> {
let idx = 6;
&self.data_directories[idx]
}
pub fn get_architecture(&self) -> &Option<DataDirectory> {
let idx = 7;
&self.data_directories[idx]
}
pub fn get_global_ptr(&self) -> &Option<DataDirectory> {
let idx = 8;
&self.data_directories[idx]
}
pub fn get_tls_table(&self) -> &Option<DataDirectory> {
let idx = 9;
&self.data_directories[idx]
}
pub fn get_load_config_table(&self) -> &Option<DataDirectory> {
let idx = 10;
&self.data_directories[idx]
}
pub fn get_bound_import_table(&self) -> &Option<DataDirectory> {
let idx = 11;
&self.data_directories[idx]
}
pub fn get_import_address_table(&self) -> &Option<DataDirectory> {
let idx = 12;
&self.data_directories[idx]
}
pub fn get_delay_import_descriptor(&self) -> &Option<DataDirectory> {
let idx = 13;
&self.data_directories[idx]
}
pub fn get_clr_runtime_header(&self) -> &Option<DataDirectory> {
let idx = 14;
&self.data_directories[idx]
build_dd_getter!(get_export_table, 0);
build_dd_getter!(get_import_table, 1);
build_dd_getter!(get_resource_table, 2);
build_dd_getter!(get_exception_table, 3);
build_dd_getter!(get_certificate_table, 4);
build_dd_getter!(get_base_relocation_table, 5);
build_dd_getter!(get_debug_table, 6);
build_dd_getter!(get_architecture, 7);
build_dd_getter!(get_global_ptr, 8);
build_dd_getter!(get_tls_table, 9);
build_dd_getter!(get_load_config_table, 10);
build_dd_getter!(get_bound_import_table, 11);
build_dd_getter!(get_import_address_table, 12);
build_dd_getter!(get_delay_import_descriptor, 13);
build_dd_getter!(get_clr_runtime_header, 14);
pub fn dirs(&self) -> impl Iterator<Item = (DataDirectoryType, DataDirectory)> {
self.data_directories
.into_iter()
.enumerate()
// (Index, Option<DD>) -> Option<(Index, DD)> -> (DDT, DD)
.filter_map(|(i, o)|
// We should not have invalid indexes.
// Indeed: `data_directories: &[_; N]` where N is the number
// of data directories.
// The `TryFrom` trait for integers to DataDirectoryType
// takes into account the N possible data directories.
// Therefore, the unwrap can never fail as long as Rust guarantees
// on types are honored.
o.map(|(_, v)| (i.try_into().unwrap(), v)))
}
}

View File

@ -3,24 +3,60 @@ use crate::pe::{optional_header, section_table, symbol};
use crate::strtab;
use alloc::vec::Vec;
use log::debug;
use scroll::{IOread, IOwrite, Pread, Pwrite, SizeWith};
use scroll::{ctx, IOread, IOwrite, Pread, Pwrite, SizeWith};
/// DOS header present in all PE binaries
#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone, Default)]
#[derive(Debug, PartialEq, Copy, Clone, Default, Pwrite)]
pub struct DosHeader {
/// Magic number: 5a4d
pub signature: u16,
/// Pointer to PE header, always at offset 0x3c
/// e_cblp
pub bytes_on_last_page: u16,
/// e_cp
pub pages_in_file: u16,
/// e_crlc
pub relocations: u16,
/// e_cparhdr
pub size_of_header_in_paragraphs: u16,
/// e_minalloc
pub minimum_extra_paragraphs_needed: u16,
/// e_maxalloc
pub maximum_extra_paragraphs_needed: u16,
/// e_ss
pub initial_relative_ss: u16,
/// e_sp
pub initial_sp: u16,
/// e_csum
pub checksum: u16,
/// e_ip
pub initial_ip: u16,
/// e_cs
pub initial_relative_cs: u16,
/// e_lfarlc
pub file_address_of_relocation_table: u16,
/// e_ovno
pub overlay_number: u16,
/// e_res[4]
pub reserved: [u16; 4],
/// e_oemid
pub oem_id: u16,
/// e_oeminfo
pub oem_info: u16,
/// e_res2[10]
pub reserved2: [u16; 10],
/// e_lfanew: pointer to PE header, always at offset 0x3c
pub pe_pointer: u32,
}
pub const DOS_MAGIC: u16 = 0x5a4d;
pub const PE_POINTER_OFFSET: u32 = 0x3c;
pub const DOS_STUB_OFFSET: u32 = PE_POINTER_OFFSET + (core::mem::size_of::<u32>() as u32);
impl DosHeader {
pub fn parse(bytes: &[u8]) -> error::Result<Self> {
let signature = bytes.pread_with(0, scroll::LE).map_err(|_| {
let mut offset = 0;
let signature = bytes.gread_with(&mut offset, scroll::LE).map_err(|_| {
error::Error::Malformed(format!("cannot parse DOS signature (offset {:#x})", 0))
})?;
if signature != DOS_MAGIC {
@ -29,6 +65,33 @@ impl DosHeader {
signature
)));
}
let bytes_on_last_page = bytes.gread_with(&mut offset, scroll::LE)?;
let pages_in_file = bytes.gread_with(&mut offset, scroll::LE)?;
let relocations = bytes.gread_with(&mut offset, scroll::LE)?;
let size_of_header_in_paragraphs = bytes.gread_with(&mut offset, scroll::LE)?;
let minimum_extra_paragraphs_needed = bytes.gread_with(&mut offset, scroll::LE)?;
let maximum_extra_paragraphs_needed = bytes.gread_with(&mut offset, scroll::LE)?;
let initial_relative_ss = bytes.gread_with(&mut offset, scroll::LE)?;
let initial_sp = bytes.gread_with(&mut offset, scroll::LE)?;
let checksum = bytes.gread_with(&mut offset, scroll::LE)?;
let initial_ip = bytes.gread_with(&mut offset, scroll::LE)?;
let initial_relative_cs = bytes.gread_with(&mut offset, scroll::LE)?;
let file_address_of_relocation_table = bytes.gread_with(&mut offset, scroll::LE)?;
let overlay_number = bytes.gread_with(&mut offset, scroll::LE)?;
let reserved = [0x0; 4];
offset += core::mem::size_of_val(&reserved);
let oem_id = bytes.gread_with(&mut offset, scroll::LE)?;
let oem_info = bytes.gread_with(&mut offset, scroll::LE)?;
let reserved2 = [0x0; 10];
offset += core::mem::size_of_val(&reserved2);
debug_assert!(
offset == PE_POINTER_OFFSET as usize,
"expected offset ({:#x}) after reading DOS header to be at 0x3C",
offset
);
let pe_pointer = bytes
.pread_with(PE_POINTER_OFFSET as usize, scroll::LE)
.map_err(|_| {
@ -37,6 +100,7 @@ impl DosHeader {
PE_POINTER_OFFSET
))
})?;
let pe_signature: u32 =
bytes
.pread_with(pe_pointer as usize, scroll::LE)
@ -52,13 +116,48 @@ impl DosHeader {
pe_signature
)));
}
Ok(DosHeader {
signature,
bytes_on_last_page,
pages_in_file,
relocations,
size_of_header_in_paragraphs,
minimum_extra_paragraphs_needed,
maximum_extra_paragraphs_needed,
initial_relative_ss,
initial_sp,
checksum,
initial_ip,
initial_relative_cs,
file_address_of_relocation_table,
overlay_number,
reserved,
oem_id,
oem_info,
reserved2,
pe_pointer,
})
}
}
#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone, Pread, Pwrite)]
/// The DOS stub program which should be executed in DOS mode
pub struct DosStub(pub [u8; 0x40]);
impl Default for DosStub {
fn default() -> Self {
// "This program cannot be run in DOS mode" error program
Self([
0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21,
0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, 0x63,
0x61, 0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x69,
0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20, 0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0D, 0x0A,
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
])
}
}
/// COFF Header
#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone, Default, Pread, Pwrite, IOread, IOwrite, SizeWith)]
@ -163,14 +262,24 @@ impl CoffHeader {
}
/// Return the COFF symbol table.
pub fn symbols<'a>(&self, bytes: &'a [u8]) -> error::Result<symbol::SymbolTable<'a>> {
pub fn symbols<'a>(&self, bytes: &'a [u8]) -> error::Result<Option<symbol::SymbolTable<'a>>> {
let offset = self.pointer_to_symbol_table as usize;
let number = self.number_of_symbol_table as usize;
symbol::SymbolTable::parse(bytes, offset, number)
if offset == 0 {
Ok(None)
} else {
symbol::SymbolTable::parse(bytes, offset, number).map(Some)
}
}
/// Return the COFF string table.
pub fn strings<'a>(&self, bytes: &'a [u8]) -> error::Result<strtab::Strtab<'a>> {
pub fn strings<'a>(&self, bytes: &'a [u8]) -> error::Result<Option<strtab::Strtab<'a>>> {
// > The file offset of the COFF symbol table, or zero if no COFF symbol table is present.
// > This value should be zero for an image because COFF debugging information is deprecated.
if self.pointer_to_symbol_table == 0 {
return Ok(None);
}
let mut offset = self.pointer_to_symbol_table as usize
+ symbol::SymbolTable::size(self.number_of_symbol_table as usize);
@ -180,13 +289,15 @@ impl CoffHeader {
// The offset needs to be advanced in order to read the strings.
offset += length_field_size;
Ok(strtab::Strtab::parse(bytes, offset, length, 0)?)
Ok(Some(strtab::Strtab::parse(bytes, offset, length, 0)?))
}
}
#[derive(Debug, PartialEq, Copy, Clone, Default)]
pub struct Header {
pub dos_header: DosHeader,
/// DOS program for legacy loaders
pub dos_stub: DosStub,
/// PE Magic: PE\0\0, little endian
pub signature: u32,
pub coff_header: CoffHeader,
@ -196,6 +307,12 @@ pub struct Header {
impl Header {
pub fn parse(bytes: &[u8]) -> error::Result<Self> {
let dos_header = DosHeader::parse(&bytes)?;
let dos_stub = bytes.pread(DOS_STUB_OFFSET as usize).map_err(|_| {
error::Error::Malformed(format!(
"cannot parse DOS stub (offset {:#x})",
DOS_STUB_OFFSET
))
})?;
let mut offset = dos_header.pe_pointer as usize;
let signature = bytes.gread_with(&mut offset, scroll::LE).map_err(|_| {
error::Error::Malformed(format!("cannot parse PE signature (offset {:#x})", offset))
@ -208,6 +325,7 @@ impl Header {
};
Ok(Header {
dos_header,
dos_stub,
signature,
coff_header,
optional_header,
@ -215,6 +333,22 @@ impl Header {
}
}
impl ctx::TryIntoCtx<scroll::Endian> for Header {
type Error = error::Error;
fn try_into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) -> Result<usize, Self::Error> {
let offset = &mut 0;
bytes.gwrite_with(self.dos_header, offset, ctx)?;
bytes.gwrite_with(self.dos_stub, offset, ctx)?;
bytes.gwrite_with(self.signature, offset, scroll::LE)?;
bytes.gwrite_with(self.coff_header, offset, ctx)?;
if let Some(opt_header) = self.optional_header {
bytes.gwrite_with(opt_header, offset, ctx)?;
}
Ok(*offset)
}
}
/// Convert machine to str representation
pub fn machine_to_str(machine: u16) -> &'static str {
match machine {

View File

@ -3,7 +3,12 @@
// TODO: panics with unwrap on None for apisetschema.dll, fhuxgraphics.dll and some others
use core::cmp::max;
use alloc::borrow::Cow;
use alloc::string::String;
use alloc::vec::Vec;
use log::warn;
pub mod authenticode;
pub mod certificate_table;
@ -23,8 +28,11 @@ pub mod utils;
use crate::container;
use crate::error;
use crate::pe::utils::pad;
use crate::strtab;
use scroll::{ctx, Pwrite};
use log::debug;
#[derive(Debug)]
@ -140,7 +148,7 @@ impl<'a> PE<'a> {
entry, image_base, is_64
);
let file_alignment = optional_header.windows_fields.file_alignment;
if let Some(export_table) = *optional_header.data_directories.get_export_table() {
if let Some(&export_table) = optional_header.data_directories.get_export_table() {
if let Ok(ed) = export::ExportData::parse_with_opts(
bytes,
export_table,
@ -162,7 +170,7 @@ impl<'a> PE<'a> {
}
}
debug!("exports: {:#?}", exports);
if let Some(import_table) = *optional_header.data_directories.get_import_table() {
if let Some(&import_table) = optional_header.data_directories.get_import_table() {
let id = if is_64 {
import::ImportData::parse_with_opts::<u64>(
bytes,
@ -196,7 +204,7 @@ impl<'a> PE<'a> {
import_data = Some(id);
}
debug!("imports: {:#?}", imports);
if let Some(debug_table) = *optional_header.data_directories.get_debug_table() {
if let Some(&debug_table) = optional_header.data_directories.get_debug_table() {
debug_data = Some(debug::DebugData::parse_with_opts(
bytes,
debug_table,
@ -209,8 +217,8 @@ impl<'a> PE<'a> {
if header.coff_header.machine == header::COFF_MACHINE_X86_64 {
// currently only x86_64 is supported
debug!("exception data: {:#?}", exception_data);
if let Some(exception_table) =
*optional_header.data_directories.get_exception_table()
if let Some(&exception_table) =
optional_header.data_directories.get_exception_table()
{
exception_data = Some(exception::ExceptionData::parse_with_opts(
bytes,
@ -222,26 +230,30 @@ impl<'a> PE<'a> {
}
}
let certtable = if let Some(certificate_table) =
*optional_header.data_directories.get_certificate_table()
{
certificates = certificate_table::enumerate_certificates(
bytes,
certificate_table.virtual_address,
certificate_table.size,
)?;
// Parse attribute certificates unless opted out of
let certificate_table_size = if opts.parse_attribute_certificates {
if let Some(&certificate_table) =
optional_header.data_directories.get_certificate_table()
{
certificates = certificate_table::enumerate_certificates(
bytes,
certificate_table.virtual_address,
certificate_table.size,
)?;
let start = certificate_table.virtual_address as usize;
let end = start + certificate_table.size as usize;
Some(start..end)
certificate_table.size as usize
} else {
0
}
} else {
None
0
};
authenticode_excluded_sections = Some(authenticode::ExcludedSections::new(
checksum,
datadir_entry_certtable,
certtable,
certificate_table_size,
optional_header.windows_fields.size_of_headers as usize,
));
}
Ok(PE {
@ -265,6 +277,192 @@ impl<'a> PE<'a> {
certificates,
})
}
pub fn write_sections(
&self,
bytes: &mut [u8],
offset: &mut usize,
file_alignment: Option<usize>,
ctx: scroll::Endian,
) -> Result<usize, error::Error> {
// sections table and data
debug_assert!(
self.sections
.iter()
.flat_map(|section_a| {
self.sections
.iter()
.map(move |section_b| (section_a, section_b))
})
// given sections = (s_1, …, s_n)
// for all (s_i, s_j), i != j, verify that s_i does not overlap with s_j and vice versa.
.all(|(section_i, section_j)| section_i == section_j
|| !section_i.overlaps_with(section_j)),
"Overlapping sections were found, this is not supported."
);
for section in &self.sections {
let section_data = section.data(&self.bytes)?.ok_or_else(|| {
error::Error::Malformed(format!(
"Section data `{}` is malformed",
section.name().unwrap_or("unknown name")
))
})?;
let file_section_offset =
usize::try_from(section.pointer_to_raw_data).map_err(|_| {
error::Error::Malformed(format!(
"Section `{}`'s pointer to raw data does not fit in platform `usize`",
section.name().unwrap_or("unknown name")
))
})?;
let vsize: usize = section.virtual_size.try_into()?;
let ondisk_size: usize = section.size_of_raw_data.try_into()?;
let section_name = String::from(section.name().unwrap_or("unknown name"));
let mut file_offset = file_section_offset;
// `file_section_offset` is a on-disk offset which can be anywhere in the file.
// Write section data first to avoid the final consumption.
match section_data {
Cow::Borrowed(borrowed) => bytes.gwrite(borrowed, &mut file_offset)?,
Cow::Owned(owned) => bytes.gwrite(owned.as_slice(), &mut file_offset)?,
};
// Section tables follows the header.
bytes.gwrite_with(section, offset, ctx)?;
// for size size_of_raw_data
// if < virtual_size, pad with 0
// Pad with zeros if necessary
if file_offset < vsize {
bytes.gwrite(vec![0u8; vsize - file_offset].as_slice(), &mut file_offset)?;
}
// Align on a boundary as per file alignement field.
if let Some(pad) = pad(file_offset - file_section_offset, file_alignment) {
debug!(
"aligning `{}` {:#x} -> {:#x} bytes'",
section_name,
file_offset - file_section_offset,
file_offset - file_section_offset + pad.len()
);
bytes.gwrite(pad.as_slice(), &mut file_offset)?;
}
let written_data_size = file_offset - file_section_offset;
if ondisk_size != written_data_size {
warn!("Original PE is inefficient or bug (on-disk data size in PE: {:#x}), we wrote {:#x} bytes",
ondisk_size,
written_data_size);
}
}
Ok(*offset)
}
pub fn write_certificates(
&self,
bytes: &mut [u8],
ctx: scroll::Endian,
) -> Result<usize, error::Error> {
let opt_header = self
.header
.optional_header
.ok_or(error::Error::Malformed(format!(
"This PE binary has no optional header; it is required to write certificates"
)))?;
let mut max_offset = 0;
if let Some(certificate_directory) = opt_header.data_directories.get_certificate_table() {
let mut certificate_start = certificate_directory.virtual_address.try_into()?;
for certificate in &self.certificates {
bytes.gwrite_with(certificate, &mut certificate_start, ctx)?;
max_offset = max(certificate_start, max_offset);
}
}
Ok(max_offset)
}
}
impl<'a> ctx::TryIntoCtx<scroll::Endian> for PE<'a> {
type Error = error::Error;
fn try_into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) -> Result<usize, Self::Error> {
let mut offset = 0;
// We need to maintain a `max_offset` because
// we could be writing sections in the wrong order (i.e. not an increasing order for the
// pointer on raw disk)
// and there could be holes between sections.
// If we don't re-layout sections, we cannot fix that ourselves.
// Same can be said about the certificate table, there could be a hole between sections
// and the certificate data.
// To avoid those troubles, we maintain the max over all offsets we see so far.
let mut max_offset = 0;
let file_alignment: Option<usize> = match self.header.optional_header {
Some(opt_header) => {
debug_assert!(
opt_header.windows_fields.file_alignment.count_ones() == 1,
"file alignment should be a power of 2"
);
Some(opt_header.windows_fields.file_alignment.try_into()?)
}
_ => None,
};
bytes.gwrite_with(self.header, &mut offset, ctx)?;
max_offset = max(offset, max_offset);
self.write_sections(bytes, &mut offset, file_alignment, ctx)?;
// We want the section offset for which we have the highest pointer on disk.
// The next offset is reserved for debug tables (outside of sections) and/or certificate
// tables.
max_offset = max(
self.sections
.iter()
.max_by_key(|section| section.pointer_to_raw_data as usize)
.map(|section| (section.pointer_to_raw_data + section.size_of_raw_data) as usize)
.unwrap_or(offset),
max_offset,
);
// COFF Symbol Table
// Auxiliary Symbol Records
// COFF String Table
assert!(
self.header.coff_header.pointer_to_symbol_table == 0,
"Symbol tables in PE are deprecated and not supported to write"
);
// The following data directories are
// taken care inside a section:
// - export table (.edata)
// - import table (.idata)
// - bound import table
// - import address table
// - delay import tables
// - resource table (.rsrc)
// - exception table (.pdata)
// - base relocation table (.reloc)
// - debug table (.debug) <- this one is special, it can be outside of a
// section.
// - load config table
// - tls table (.tls)
// - architecture (reserved, 0 for now)
// - global ptr is a "empty" data directory (header-only)
// - clr runtime header (.cormeta is object-only)
//
// Nonetheless, we need to write the attribute certificate table one.
max_offset = max(max_offset, self.write_certificates(bytes, ctx)?);
// TODO: we would like to support debug table outside of a section.
// i.e. debug tables that are never mapped in memory
// See https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#debug-directory-image-only
// > The debug directory can be in a discardable .debug section (if one exists), or it can be included in any other section in the image file, or not be in a section at all.
// In case it's not in a section at all, we need to find a way
// to rewrite it again.
// and we need to respect the ordering between attribute certificates
// and debug table.
Ok(max_offset)
}
}
/// An analyzed COFF object
@ -274,10 +472,12 @@ pub struct Coff<'a> {
pub header: header::CoffHeader,
/// A list of the sections in this COFF binary
pub sections: Vec<section_table::SectionTable>,
/// The COFF symbol table.
pub symbols: symbol::SymbolTable<'a>,
/// The string table.
pub strings: strtab::Strtab<'a>,
/// The COFF symbol table, they are not guaranteed to exist.
/// For an image, this is expected to be None as COFF debugging information
/// has been deprecated.
pub symbols: Option<symbol::SymbolTable<'a>>,
/// The string table, they don't exist if COFF symbol table does not exist.
pub strings: Option<strtab::Strtab<'a>>,
}
impl<'a> Coff<'a> {
@ -414,7 +614,7 @@ mod tests {
#[test]
fn string_table_excludes_length() {
let coff = Coff::parse(&&COFF_FILE_SINGLE_STRING_IN_STRING_TABLE[..]).unwrap();
let string_table = coff.strings.to_vec().unwrap();
let string_table = coff.strings.unwrap().to_vec().unwrap();
assert!(string_table == vec!["ExitProcess"]);
}
@ -422,9 +622,10 @@ mod tests {
#[test]
fn symbol_name_excludes_length() {
let coff = Coff::parse(&COFF_FILE_SINGLE_STRING_IN_STRING_TABLE).unwrap();
let strings = coff.strings;
let strings = coff.strings.unwrap();
let symbols = coff
.symbols
.unwrap()
.iter()
.filter(|(_, name, _)| name.is_none())
.map(|(_, _, sym)| sym.name(&strings).unwrap().to_owned())

View File

@ -71,6 +71,22 @@ impl From<StandardFields32> for StandardFields {
}
}
impl From<StandardFields> for StandardFields32 {
fn from(fields: StandardFields) -> Self {
StandardFields32 {
magic: fields.magic,
major_linker_version: fields.major_linker_version,
minor_linker_version: fields.minor_linker_version,
size_of_code: fields.size_of_code as u32,
size_of_initialized_data: fields.size_of_initialized_data as u32,
size_of_uninitialized_data: fields.size_of_uninitialized_data as u32,
address_of_entry_point: fields.address_of_entry_point as u32,
base_of_code: fields.base_of_code as u32,
base_of_data: fields.base_of_data,
}
}
}
impl From<StandardFields64> for StandardFields {
fn from(fields: StandardFields64) -> Self {
StandardFields {
@ -87,6 +103,21 @@ impl From<StandardFields64> for StandardFields {
}
}
impl From<StandardFields> for StandardFields64 {
fn from(fields: StandardFields) -> Self {
StandardFields64 {
magic: fields.magic,
major_linker_version: fields.major_linker_version,
minor_linker_version: fields.minor_linker_version,
size_of_code: fields.size_of_code as u32,
size_of_initialized_data: fields.size_of_initialized_data as u32,
size_of_uninitialized_data: fields.size_of_uninitialized_data as u32,
address_of_entry_point: fields.address_of_entry_point as u32,
base_of_code: fields.base_of_code as u32,
}
}
}
/// Standard fields magic number for 32-bit binary
pub const MAGIC_32: u16 = 0x10b;
/// Standard fields magic number for 64-bit binary
@ -208,6 +239,36 @@ impl From<WindowsFields32> for WindowsFields {
}
}
impl TryFrom<WindowsFields64> for WindowsFields32 {
type Error = crate::error::Error;
fn try_from(value: WindowsFields64) -> Result<Self, Self::Error> {
Ok(WindowsFields32 {
image_base: value.image_base.try_into()?,
section_alignment: value.section_alignment,
file_alignment: value.file_alignment,
major_operating_system_version: value.major_operating_system_version,
minor_operating_system_version: value.minor_operating_system_version,
major_image_version: value.major_image_version,
minor_image_version: value.minor_image_version,
major_subsystem_version: value.major_subsystem_version,
minor_subsystem_version: value.minor_subsystem_version,
win32_version_value: value.win32_version_value,
size_of_image: value.size_of_image,
size_of_headers: value.size_of_headers,
check_sum: value.check_sum,
subsystem: value.subsystem,
dll_characteristics: value.dll_characteristics,
size_of_stack_reserve: value.size_of_stack_reserve.try_into()?,
size_of_stack_commit: value.size_of_stack_commit.try_into()?,
size_of_heap_reserve: value.size_of_heap_reserve.try_into()?,
size_of_heap_commit: value.size_of_heap_commit.try_into()?,
loader_flags: value.loader_flags,
number_of_rva_and_sizes: value.number_of_rva_and_sizes,
})
}
}
// impl From<WindowsFields32> for WindowsFields {
// fn from(windows: WindowsFields32) -> Self {
// WindowsFields {
@ -289,6 +350,28 @@ impl<'a> ctx::TryFromCtx<'a, Endian> for OptionalHeader {
}
}
impl ctx::TryIntoCtx<scroll::Endian> for OptionalHeader {
type Error = error::Error;
fn try_into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) -> Result<usize, Self::Error> {
let offset = &mut 0;
match self.standard_fields.magic {
MAGIC_32 => {
bytes.gwrite_with::<StandardFields32>(self.standard_fields.into(), offset, ctx)?;
bytes.gwrite_with(WindowsFields32::try_from(self.windows_fields)?, offset, ctx)?;
bytes.gwrite_with(self.data_directories, offset, ctx)?;
}
MAGIC_64 => {
bytes.gwrite_with::<StandardFields64>(self.standard_fields.into(), offset, ctx)?;
bytes.gwrite_with(self.windows_fields, offset, ctx)?;
bytes.gwrite_with(self.data_directories, offset, ctx)?;
}
_ => panic!(),
}
Ok(*offset)
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -3,11 +3,19 @@
pub struct ParseOptions {
/// Wether the parser should resolve rvas or not. Default: true
pub resolve_rva: bool,
/// Whether or not to parse attribute certificates.
/// Set to false for in-memory representation, as the [loader does not map this info into
/// memory](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#other-contents-of-the-file).
/// For on-disk representations, leave as true. Default: true
pub parse_attribute_certificates: bool,
}
impl ParseOptions {
/// Returns a parse options structure with default values
pub fn default() -> Self {
ParseOptions { resolve_rva: true }
ParseOptions {
resolve_rva: true,
parse_attribute_certificates: true,
}
}
}

View File

@ -1,6 +1,8 @@
use crate::error::{self, Error};
use crate::pe::relocation;
use alloc::borrow::Cow;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use scroll::{ctx, Pread, Pwrite};
#[repr(C)]
@ -79,6 +81,32 @@ impl SectionTable {
Ok(table)
}
pub fn data<'a, 'b: 'a>(&'a self, pe_bytes: &'b [u8]) -> error::Result<Option<Cow<[u8]>>> {
let section_start: usize = self.pointer_to_raw_data.try_into().map_err(|_| {
Error::Malformed(format!("Virtual address cannot fit in platform `usize`"))
})?;
// assert!(self.virtual_size <= self.size_of_raw_data);
// if vsize > size_of_raw_data, the section is zero padded.
let section_end: usize = section_start
+ usize::try_from(self.size_of_raw_data).map_err(|_| {
Error::Malformed(format!("Virtual size cannot fit in platform `usize`"))
})?;
let original_bytes = pe_bytes.get(section_start..section_end).map(Cow::Borrowed);
if original_bytes.is_some() && self.virtual_size > self.size_of_raw_data {
let mut bytes: Vec<u8> = Vec::new();
bytes.resize(self.size_of_raw_data.try_into()?, 0);
bytes.copy_from_slice(&original_bytes.unwrap());
bytes.resize(self.virtual_size.try_into()?, 0);
Ok(Some(Cow::Owned(bytes)))
} else {
Ok(original_bytes)
}
}
pub fn name_offset(&self) -> error::Result<Option<usize>> {
// Based on https://github.com/llvm-mirror/llvm/blob/af7b1832a03ab6486c42a40d21695b2c03b2d8a3/lib/Object/COFFObjectFile.cpp#L1054
if self.name[0] == b'/' {
@ -163,6 +191,15 @@ impl SectionTable {
let number = self.number_of_relocations as usize;
relocation::Relocations::parse(bytes, offset, number)
}
/// Tests if `another_section` on-disk ranges will collide.
pub fn overlaps_with(&self, another_section: &SectionTable) -> bool {
let self_end = self.pointer_to_raw_data + self.size_of_raw_data;
let another_end = another_section.pointer_to_raw_data + another_section.size_of_raw_data;
!((self_end <= another_section.pointer_to_raw_data)
|| (another_end <= self.pointer_to_raw_data))
}
}
impl ctx::SizeWith<scroll::Endian> for SectionTable {
@ -171,7 +208,7 @@ impl ctx::SizeWith<scroll::Endian> for SectionTable {
}
}
impl ctx::TryIntoCtx<scroll::Endian> for SectionTable {
impl ctx::TryIntoCtx<scroll::Endian> for &SectionTable {
type Error = error::Error;
fn try_into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) -> Result<usize, Self::Error> {
let offset = &mut 0;
@ -189,7 +226,7 @@ impl ctx::TryIntoCtx<scroll::Endian> for SectionTable {
}
}
impl ctx::IntoCtx<scroll::Endian> for SectionTable {
impl ctx::IntoCtx<scroll::Endian> for &SectionTable {
fn into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) {
bytes.pwrite_with(self, 0, ctx).unwrap();
}

View File

@ -412,6 +412,7 @@ pub struct AuxSectionDefinition {
}
/// A COFF symbol table.
// TODO: #[derive(Pwrite)] produce unparseable tokens
pub struct SymbolTable<'a> {
symbols: &'a [u8],
}
@ -483,6 +484,14 @@ impl<'a> SymbolTable<'a> {
}
}
impl<'a> ctx::TryIntoCtx<scroll::Endian> for SymbolTable<'a> {
type Error = error::Error;
fn try_into_ctx(self, bytes: &mut [u8], _ctx: scroll::Endian) -> Result<usize, Self::Error> {
bytes.pwrite(self.symbols, 0).map_err(|err| err.into())
}
}
impl<'a> Debug for SymbolTable<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("SymbolTable")

View File

@ -1,5 +1,6 @@
use crate::error;
use alloc::string::ToString;
use alloc::vec::Vec;
use scroll::Pread;
use super::options;
@ -178,3 +179,18 @@ where
let result: T = bytes.pread_with(offset, scroll::LE)?;
Ok(result)
}
pub(crate) fn pad(length: usize, alignment: Option<usize>) -> Option<Vec<u8>> {
match alignment {
Some(alignment) => {
let overhang = length % alignment;
if overhang != 0 {
let repeat = alignment - overhang;
Some(vec![0u8; repeat])
} else {
None
}
}
None => None,
}
}

View File

@ -34,6 +34,11 @@ impl<'a> Strtab<'a> {
Self::from_slice_unparsed(bytes, 0, bytes.len(), delim)
}
/// Returns the length of this `Strtab` in bytes
pub fn len(&self) -> usize {
self.bytes.len()
}
/// Creates a `Strtab` directly without bounds check and without parsing it.
///
/// This is potentially unsafe and should only be used if `feature = "alloc"` is disabled.

View File

@ -1 +1 @@
{"files":{"CHANGELOG.md":"e1165d97c283b915d87e22f209494be39933723a0b544e725f69cfa5cef3876c","Cargo.lock":"7625529900ca1e3626b90e74ef268b31e06da85e8334a885711fdfd80821ddda","Cargo.toml":"81dde8ad3180c7b97325a6a67bfbefb145590606de9008d881c4e04808865f0a","README.md":"811ea1c958d5a65583d0223b7ab09bb282e7a51ed60f9a2cb90ef6d555325a68","benches/benches.rs":"67dcc916d0b7e28e396c28dac0499726366e1cb10e9991948d1c881a5abf5faa","check_mem_leaks.sh":"c1ab6ef27997c7f971352ab1c86a184004843c499bc24925da953aefcf1c624c","examples/recv_before_send.rs":"9a3cabcc2878990b61787d0048061b382555a8cd1a08b1ddec63a6e8a4a31e56","examples/recv_before_send_then_drop_sender.rs":"14706c6b4308a690662ceaa47f1699588bd833b3ec020eb9f42f220f3ffc7ae7","examples/recv_ref_before_send.rs":"43699f4720c46b5f138c260b866eb708ddf616e2b442ffa74a97373f4f48d4d0","examples/recv_ref_before_send_then_drop_sender.rs":"a190ed220cb4288d4965485365c9afaed30535cbfad5f8cb7389071b82d67cac","examples/recv_timeout_before_send.rs":"2262aa6531afce7816d43182ad9cbec2c04f3dc129064e11e89452278ce8b163","examples/recv_timeout_before_send_then_drop_sender.rs":"4cc8eade4c211f52f5b9be0f72a5906689b894490f4cb5255525e44106e7a4a8","examples/recv_with_dropped_sender.rs":"7906685053ce1c53ff6c26ce11d3221d4bf5ca3429d1d4d2c28de9237cb151c6","examples/send_before_recv.rs":"5555bd61ad52273b663007794128d8f012fc54272bd3225259b5546221bcd591","examples/send_then_drop_receiver.rs":"c3612de207309098404b057468687a2d2311d07f354b7e046398e35e93c4cdcf","examples/send_with_dropped_receiver.rs":"f5a7762b231a24a0db4397c5139437cba155d09b9dbb59872d662c7923080706","src/errors.rs":"df6a1db663fdb1c54d6941d737f6591bfe0dc6f01bd627ba0a94d67ed50b27a9","src/lib.rs":"86893f56e8e762b41ee079b42f4248608e9efb68bd76aa9550fce61e7466bbb0","src/loombox.rs":"fc85d1c2d3fda432be60f0c4d1d528e5998ec2b738a5b395a242285051b94d65","tests/assert_mem.rs":"b1e5190af01af22e55c7c1cd1ff2711807591f788e4eb8b6c6d89123e146105e","tests/async.rs":"6fd2826e589b94677d4eeed1080deda8bcc429aa05a20d843d1442a3a48ea757","tests/future.rs":"0e71f0293cd5a8c44210e8882aca20cfbf1e3771ecd4e4f6b59b924c0d01dd97","tests/helpers/mod.rs":"19161ed33e0ba8862746f04678d0606dee90205896083f85d8c1dcd4d211ccb0","tests/helpers/waker.rs":"77494d49f62d0d320df3830643c306e06e6e20751d210cf6fa58b238bd96c3f9","tests/loom.rs":"ea350fa424a95581e1871bc0037badecc5a090f28fd10532917abbaf561218ab","tests/sync.rs":"1186fa6cdb5a180944fa7d793ccb8be412c4a4e88bb504daa70bc097ee081b06"},"package":"9ae4988774e7a7e6a0783d119bdc683ea8c1d01a24d4fff9b4bdc280e07bd99e"}
{"files":{"CHANGELOG.md":"4ad03d95d5532e8f2551e3e53877e6347c04c32f479c4edf517244ecd5921ac7","Cargo.lock":"5d85bcfda2ee559d243099fb26f3724ae239777d891e780a924804e30f6733ad","Cargo.toml":"07a73ff74274df3a7439fccc8acfe306fae0f51ad79a80edbc54b51a730314c0","README.md":"811ea1c958d5a65583d0223b7ab09bb282e7a51ed60f9a2cb90ef6d555325a68","benches/benches.rs":"67dcc916d0b7e28e396c28dac0499726366e1cb10e9991948d1c881a5abf5faa","check_mem_leaks.sh":"c1ab6ef27997c7f971352ab1c86a184004843c499bc24925da953aefcf1c624c","examples/recv_before_send.rs":"9a3cabcc2878990b61787d0048061b382555a8cd1a08b1ddec63a6e8a4a31e56","examples/recv_before_send_then_drop_sender.rs":"14706c6b4308a690662ceaa47f1699588bd833b3ec020eb9f42f220f3ffc7ae7","examples/recv_ref_before_send.rs":"43699f4720c46b5f138c260b866eb708ddf616e2b442ffa74a97373f4f48d4d0","examples/recv_ref_before_send_then_drop_sender.rs":"a190ed220cb4288d4965485365c9afaed30535cbfad5f8cb7389071b82d67cac","examples/recv_timeout_before_send.rs":"2262aa6531afce7816d43182ad9cbec2c04f3dc129064e11e89452278ce8b163","examples/recv_timeout_before_send_then_drop_sender.rs":"4cc8eade4c211f52f5b9be0f72a5906689b894490f4cb5255525e44106e7a4a8","examples/recv_with_dropped_sender.rs":"7906685053ce1c53ff6c26ce11d3221d4bf5ca3429d1d4d2c28de9237cb151c6","examples/send_before_recv.rs":"5555bd61ad52273b663007794128d8f012fc54272bd3225259b5546221bcd591","examples/send_then_drop_receiver.rs":"c3612de207309098404b057468687a2d2311d07f354b7e046398e35e93c4cdcf","examples/send_with_dropped_receiver.rs":"f5a7762b231a24a0db4397c5139437cba155d09b9dbb59872d662c7923080706","src/errors.rs":"a5aa56bc497dccdbdbe15b9070360f50835c762f11be4ee96e0d25b150168ac9","src/lib.rs":"4bef3602ff4f5d2b42ce963d722a48c9ff07275e75ef6bed7b523e8f45e459fe","src/loombox.rs":"fc85d1c2d3fda432be60f0c4d1d528e5998ec2b738a5b395a242285051b94d65","tests/assert_mem.rs":"b1e5190af01af22e55c7c1cd1ff2711807591f788e4eb8b6c6d89123e146105e","tests/async.rs":"6fd2826e589b94677d4eeed1080deda8bcc429aa05a20d843d1442a3a48ea757","tests/future.rs":"0e71f0293cd5a8c44210e8882aca20cfbf1e3771ecd4e4f6b59b924c0d01dd97","tests/helpers/mod.rs":"19161ed33e0ba8862746f04678d0606dee90205896083f85d8c1dcd4d211ccb0","tests/helpers/waker.rs":"77494d49f62d0d320df3830643c306e06e6e20751d210cf6fa58b238bd96c3f9","tests/loom.rs":"ea350fa424a95581e1871bc0037badecc5a090f28fd10532917abbaf561218ab","tests/raw.rs":"5564615fea811b0061d8ad801356e60e0018ec4e3fb99cc739287ed5b96cb7cf","tests/sync.rs":"1186fa6cdb5a180944fa7d793ccb8be412c4a4e88bb504daa70bc097ee081b06"},"package":"6c548d5c78976f6955d72d0ced18c48ca07030f7a1d4024529fedd7c1c01b29c"}

View File

@ -16,6 +16,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
## [0.1.6] - 2023-09-14
### Added
* Add `into_raw` and `from_raw` methods on both `Sender` and `Receiver`. Allows passing `oneshot`
channels over FFI without an extra layer of heap allocation.
## [0.1.5] - 2022-09-01
### Fixed
- Handle the UNPARKING state correctly in all recv methods. `try_recv` will now not panic

View File

@ -601,7 +601,7 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "oneshot-uniffi"
version = "0.1.5"
version = "0.1.6"
dependencies = [
"async-std",
"criterion",

View File

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.60.0"
name = "oneshot-uniffi"
version = "0.1.5"
version = "0.1.6"
authors = ["Linus Färnstrand <faern@faern.net>"]
description = """
Patched version of oneshot specifically for the UniFFI project.

View File

@ -4,7 +4,8 @@ use core::mem;
use core::ptr::NonNull;
/// An error returned when trying to send on a closed channel. Returned from
/// [`Sender::send`] if the corresponding [`Receiver`] has already been dropped.
/// [`Sender::send`](crate::Sender::send) if the corresponding [`Receiver`](crate::Receiver)
/// has already been dropped.
///
/// The message that could not be sent can be retreived again with [`SendError::into_inner`].
pub struct SendError<T> {
@ -79,10 +80,10 @@ impl<T> fmt::Debug for SendError<T> {
#[cfg(feature = "std")]
impl<T> std::error::Error for SendError<T> {}
/// An error returned from the indefinitely blocking recv functions on a [`Receiver`].
/// An error returned from the blocking [`Receiver::recv`](crate::Receiver::recv) method.
///
/// The recv operation can only fail if the corresponding [`Sender`] was dropped before sending
/// any message. Or if a message has already been sent and received on the channel.
/// The receive operation can only fail if the corresponding [`Sender`](crate::Sender) was dropped
/// before sending any message, or if a message has already been sent and received on the channel.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct RecvError;
@ -95,7 +96,8 @@ impl fmt::Display for RecvError {
#[cfg(feature = "std")]
impl std::error::Error for RecvError {}
/// An error returned when trying a non blocking receive on a [`Receiver`].
/// An error returned when failing to receive a message in the non-blocking
/// [`Receiver::try_recv`](crate::Receiver::try_recv).
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum TryRecvError {
/// The channel is still open, but there was no message present in it.
@ -119,7 +121,8 @@ impl fmt::Display for TryRecvError {
#[cfg(feature = "std")]
impl std::error::Error for TryRecvError {}
/// An error returned when trying a time limited blocking receive on a [`Receiver`].
/// An error returned when failing to receive a message in
/// [`Receiver::recv_timeout`](crate::Receiver::recv_timeout).
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum RecvTimeoutError {
/// No message arrived on the channel before the timeout was reached. The channel is still open.

View File

@ -314,6 +314,31 @@ impl<T> Sender<T> {
_ => unreachable!(),
}
}
/// Consumes the Sender, returning a raw pointer to the channel on the heap.
///
/// This is intended to simplify using oneshot channels with some FFI code. The only safe thing
/// to do with the returned pointer is to later reconstruct the Sender with [Sender::from_raw].
/// Memory will leak if the Sender is never reconstructed.
pub fn into_raw(self) -> *mut () {
let raw = self.channel_ptr.as_ptr() as *mut ();
mem::forget(self);
raw
}
/// Consumes a raw pointer from [Sender::into_raw], recreating the Sender.
///
/// # Safety
///
/// This pointer must have come from [`Sender<T>::into_raw`] with the same message type, `T`.
/// At most one Sender must exist for a channel at any point in time.
/// Constructing multiple Senders from the same raw pointer leads to undefined behavior.
pub unsafe fn from_raw(raw: *mut ()) -> Self {
Self {
channel_ptr: NonNull::new_unchecked(raw as *mut Channel<T>),
_invariant: PhantomData,
}
}
}
impl<T> Drop for Sender<T> {
@ -816,6 +841,30 @@ impl<T> Receiver<T> {
_ => unreachable!(),
}
}
/// Consumes the Receiver, returning a raw pointer to the channel on the heap.
///
/// This is intended to simplify using oneshot channels with some FFI code. The only safe thing
/// to do with the returned pointer is to later reconstruct the Receiver with
/// [Receiver::from_raw]. Memory will leak if the Receiver is never reconstructed.
pub fn into_raw(self) -> *mut () {
let raw = self.channel_ptr.as_ptr() as *mut ();
mem::forget(self);
raw
}
/// Consumes a raw pointer from [Receiver::into_raw], recreating the Receiver.
///
/// # Safety
///
/// This pointer must have come from [`Receiver<T>::into_raw`] with the same message type, `T`.
/// At most one Receiver must exist for a channel at any point in time.
/// Constructing multiple Receivers from the same raw pointer leads to undefined behavior.
pub unsafe fn from_raw(raw: *mut ()) -> Self {
Self {
channel_ptr: NonNull::new_unchecked(raw as *mut Channel<T>),
}
}
}
#[cfg(feature = "async")]
@ -1178,7 +1227,7 @@ fn receiver_waker_size() {
(false, false) => 0,
(false, true) => 16,
(true, false) => 8,
(true, true) => 24,
(true, true) => 16,
};
assert_eq!(mem::size_of::<ReceiverWaker>(), expected);
}

View File

@ -0,0 +1,46 @@
#![cfg(not(loom))]
use oneshot::{channel, Receiver, Sender};
#[test]
fn test_raw_sender() {
let (sender, receiver) = channel::<u32>();
let raw = sender.into_raw();
let recreated = unsafe { Sender::<u32>::from_raw(raw) };
recreated
.send(100)
.unwrap_or_else(|e| panic!("error sending after into_raw/from_raw roundtrip: {e}"));
assert_eq!(receiver.try_recv(), Ok(100))
}
#[test]
fn test_raw_receiver() {
let (sender, receiver) = channel::<u32>();
let raw = receiver.into_raw();
sender.send(100).unwrap();
let recreated = unsafe { Receiver::<u32>::from_raw(raw) };
assert_eq!(
recreated
.try_recv()
.unwrap_or_else(|e| panic!("error receiving after into_raw/from_raw roundtrip: {e}")),
100
)
}
#[test]
fn test_raw_sender_and_receiver() {
let (sender, receiver) = channel::<u32>();
let raw_receiver = receiver.into_raw();
let raw_sender = sender.into_raw();
let recreated_sender = unsafe { Sender::<u32>::from_raw(raw_sender) };
recreated_sender.send(100).unwrap();
let recreated_receiver = unsafe { Receiver::<u32>::from_raw(raw_receiver) };
assert_eq!(
recreated_receiver
.try_recv()
.unwrap_or_else(|e| panic!("error receiving after into_raw/from_raw roundtrip: {e}")),
100
)
}

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"9cd293889d14141968761c609b8e472c332fc1c0656fff58602fd2993a537f98","build.rs":"a562bfe527d21c4e8a1a44b892defa83cdff141ec5dd51ed6f3862330e50ddd7","src/bin/generate-test-data.rs":"7f1c9dc445418c7627f89d1f2aa8e550d0f85b3d1f05edb7c378ab9441714f1f","src/db.rs":"0b45180f3031759213a0421231b6f109ed4f5c88aca556df159ce2717416cfec","src/error.rs":"6831fc329044174a8451b8b008c0b96c47404c591eb42e880562e65da0adfd0f","src/interest.rs":"ce6298ef8f69fcb57c8e5797467cbe1c0212a0d94daf828b12845740ac14a166","src/lib.rs":"7a0f0ad0a43f371035d9c0b73d143cf1b387d4b8cfad0d0db79314b5b91fd43c","src/populate_interests.rs":"b8905b52f9fc80719c175253b758413f606b27660e660635094421eec8b24c8f","src/relevancy.udl":"a3fae5097f9e8b39bb6c74ed6789906748c46f22d377e3dcb73b08731908f5bc","src/schema.rs":"f782c712f10c4f1af2f9e1424d6b52f59a2bacfcc452a8feb763f36478f5dd5d","src/url_hash.rs":"5619a249d471e7b642d889bad09e93212559c8b947010d49492c1423da2b310e","test-data":"392fc950363c9953ea6ab144b81d84021c4af1e1177cc0adac4eda5688c8bc33"},"package":null}
{"files":{"Cargo.toml":"76d64a839128f51662d1c10728ceddbb6a9ebdfce803915874cd654117d1b14e","build.rs":"a562bfe527d21c4e8a1a44b892defa83cdff141ec5dd51ed6f3862330e50ddd7","src/bin/generate-test-data.rs":"7f1c9dc445418c7627f89d1f2aa8e550d0f85b3d1f05edb7c378ab9441714f1f","src/db.rs":"0b45180f3031759213a0421231b6f109ed4f5c88aca556df159ce2717416cfec","src/error.rs":"6831fc329044174a8451b8b008c0b96c47404c591eb42e880562e65da0adfd0f","src/interest.rs":"ce6298ef8f69fcb57c8e5797467cbe1c0212a0d94daf828b12845740ac14a166","src/lib.rs":"7a0f0ad0a43f371035d9c0b73d143cf1b387d4b8cfad0d0db79314b5b91fd43c","src/populate_interests.rs":"b8905b52f9fc80719c175253b758413f606b27660e660635094421eec8b24c8f","src/relevancy.udl":"a3fae5097f9e8b39bb6c74ed6789906748c46f22d377e3dcb73b08731908f5bc","src/schema.rs":"f782c712f10c4f1af2f9e1424d6b52f59a2bacfcc452a8feb763f36478f5dd5d","src/url_hash.rs":"5619a249d471e7b642d889bad09e93212559c8b947010d49492c1423da2b310e","test-data":"392fc950363c9953ea6ab144b81d84021c4af1e1177cc0adac4eda5688c8bc33"},"package":null}

View File

@ -29,7 +29,7 @@ log = "0.4"
md-5 = "0.10"
parking_lot = ">=0.11,<=0.12"
thiserror = "1.0"
uniffi = "0.25.2"
uniffi = "0.27.1"
url = "2.5"
[dependencies.error-support]
@ -43,5 +43,5 @@ features = ["bundled"]
path = "../support/sql"
[build-dependencies.uniffi]
version = "0.25.2"
version = "0.27.1"
features = ["build"]

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"4fa89b0606fe8ec8ac8c479b8b9adf33d0c936b09fa5af108ded74139ace37fb","build.rs":"4326f03729cf8f1673e4228e6dc111de1ea4d8bcc06351f7ae563efb2613f866","src/client.rs":"fb3f2cd47460e5ae07a5e8d61b358d588d14075bd9dd6b6e818e1af74abd5dba","src/config.rs":"7bb678addfae3b4ed5f2892d32263e5b33cc05e5a12a250f664150e78211f94a","src/error.rs":"192ca42af7c6b882f3129378c23b45dab8a0d2b179e23a8813a335ffd56b21dc","src/lib.rs":"416e99894e152f6cea7418ad2fabfd94bc3d907efd9f33fbd2a83fb99452b2df","src/remote_settings.udl":"2e71491ad3894d17e5bde0663d9490bfea6294d99cdbe9d67a36137faeedc593","uniffi.toml":"f8ec8dc593e0d501c2e9e40368ec93ec33b1edd8608e29495e0a54b63144e880"},"package":null}
{"files":{"Cargo.toml":"1029f571c66d33c4dfc5e9fc55287a780329ce183f5d2b672de79737155c4227","build.rs":"4326f03729cf8f1673e4228e6dc111de1ea4d8bcc06351f7ae563efb2613f866","src/client.rs":"7510ae0d5bcb9fbaa2c43c4773aa0fd518edc78fe0f396c0e1d6dd442446f429","src/config.rs":"7bb678addfae3b4ed5f2892d32263e5b33cc05e5a12a250f664150e78211f94a","src/error.rs":"192ca42af7c6b882f3129378c23b45dab8a0d2b179e23a8813a335ffd56b21dc","src/lib.rs":"416e99894e152f6cea7418ad2fabfd94bc3d907efd9f33fbd2a83fb99452b2df","src/remote_settings.udl":"2e71491ad3894d17e5bde0663d9490bfea6294d99cdbe9d67a36137faeedc593","uniffi.toml":"f8ec8dc593e0d501c2e9e40368ec93ec33b1edd8608e29495e0a54b63144e880"},"package":null}

View File

@ -28,7 +28,7 @@ license = "MPL-2.0"
parking_lot = "0.12"
serde_json = "1"
thiserror = "1.0"
uniffi = "0.25.2"
uniffi = "0.27.1"
url = "2.1"
[dependencies.serde]
@ -46,5 +46,5 @@ mockito = "0.31"
path = "../support/viaduct-reqwest"
[build-dependencies.uniffi]
version = "0.25.2"
version = "0.27.1"
features = ["build"]

View File

@ -64,7 +64,7 @@ impl Client {
/// collection defined by the [ClientConfig] used to generate this [Client].
pub fn get_records_since(&self, timestamp: u64) -> Result<RemoteSettingsResponse> {
self.get_records_with_options(
GetItemsOptions::new().gt("last_modified", timestamp.to_string()),
GetItemsOptions::new().filter_gt("last_modified", timestamp.to_string()),
)
}
@ -307,7 +307,7 @@ struct AttachmentsCapability {
}
/// Options for requests to endpoints that return multiple items.
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct GetItemsOptions {
filters: Vec<Filter>,
sort: Vec<Sort>,
@ -328,14 +328,14 @@ impl GetItemsOptions {
/// `author.name`. `value` can be a bare number or string (like
/// `2` or `Ben`), or a stringified JSON value (`"2.0"`, `[1, 2]`,
/// `{"checked": true}`).
pub fn eq(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
pub fn filter_eq(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
self.filters.push(Filter::Eq(field.into(), value.into()));
self
}
/// Sets an option to only return items whose `field` is not equal to the
/// given `value`.
pub fn not(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
pub fn filter_not(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
self.filters.push(Filter::Not(field.into(), value.into()));
self
}
@ -343,7 +343,11 @@ impl GetItemsOptions {
/// Sets an option to only return items whose `field` is an array that
/// contains the given `value`. If `value` is a stringified JSON array, the
/// field must contain all its elements.
pub fn contains(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
pub fn filter_contains(
&mut self,
field: impl Into<String>,
value: impl Into<String>,
) -> &mut Self {
self.filters
.push(Filter::Contains(field.into(), value.into()));
self
@ -351,47 +355,47 @@ impl GetItemsOptions {
/// Sets an option to only return items whose `field` is strictly less
/// than the given `value`.
pub fn lt(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
pub fn filter_lt(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
self.filters.push(Filter::Lt(field.into(), value.into()));
self
}
/// Sets an option to only return items whose `field` is strictly greater
/// than the given `value`.
pub fn gt(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
pub fn filter_gt(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
self.filters.push(Filter::Gt(field.into(), value.into()));
self
}
/// Sets an option to only return items whose `field` is less than or equal
/// to the given `value`.
pub fn max(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
pub fn filter_max(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
self.filters.push(Filter::Max(field.into(), value.into()));
self
}
/// Sets an option to only return items whose `field` is greater than or
/// equal to the given `value`.
pub fn min(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
pub fn filter_min(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
self.filters.push(Filter::Min(field.into(), value.into()));
self
}
/// Sets an option to only return items whose `field` is a string that
/// contains the substring `value`. `value` can contain `*` wildcards.
pub fn like(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
pub fn filter_like(&mut self, field: impl Into<String>, value: impl Into<String>) -> &mut Self {
self.filters.push(Filter::Like(field.into(), value.into()));
self
}
/// Sets an option to only return items that have the given `field`.
pub fn has(&mut self, field: impl Into<String>) -> &mut Self {
pub fn filter_has(&mut self, field: impl Into<String>) -> &mut Self {
self.filters.push(Filter::Has(field.into()));
self
}
/// Sets an option to only return items that do not have the given `field`.
pub fn has_not(&mut self, field: impl Into<String>) -> &mut Self {
pub fn filter_has_not(&mut self, field: impl Into<String>) -> &mut Self {
self.filters.push(Filter::HasNot(field.into()));
self
}
@ -454,7 +458,7 @@ impl GetItemsOptions {
}
/// The order in which to return items.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub enum SortOrder {
/// Smaller values first.
Ascending,
@ -462,7 +466,7 @@ pub enum SortOrder {
Descending,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
enum Filter {
Eq(String, String),
Not(String, String),
@ -495,7 +499,7 @@ impl Filter {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
struct Sort(String, SortOrder);
impl Sort {
@ -692,16 +696,16 @@ mod test {
.field("a")
.field("c")
.field("b")
.eq("a", "b")
.lt("c.d", "5")
.gt("e", "15")
.max("f", "20")
.min("g", "10")
.not("h", "i")
.like("j", "*k*")
.has("l")
.has_not("m")
.contains("n", "o")
.filter_eq("a", "b")
.filter_lt("c.d", "5")
.filter_gt("e", "15")
.filter_max("f", "20")
.filter_min("g", "10")
.filter_not("h", "i")
.filter_like("j", "*k*")
.filter_has("l")
.filter_has_not("m")
.filter_contains("n", "o")
.sort("b", SortOrder::Descending)
.sort("a", SortOrder::Ascending)
.limit(3);

View File

@ -1 +1 @@
{"files":{"CHANGELOG.md":"de2bbf4669561405d402322f4cc2604218d4986b73b75b41708b9505aebcb02c","Cargo.lock":"d6a215b7466d37e08551c56949e77be4ee488f989bdef3e507713c729bbda0e6","Cargo.toml":"c240c5768d23ea9611ef57308f08b8ee4372ede6c04f0783dc9fd1710e664c19","LICENSE":"6e24b7455f0b9afefdf4f3efd59a56ce76a3020c2dc4371937e281fc5e587fd7","README.md":"e4fe9aabcd87d85a5ec93241eeefc0d69aa0d98fbd67da2fe1849e4cbddac3ce","benches/bench.rs":"12ae02c383c91f1b0e11e9201eb8a9d44dadfb2b5987e7e71b0ef7c6589af1ca","examples/data_ctx.rs":"79684fc44d499d0b13a173184793837fbaba70d2f74f075e796eb37a1803ce3d","src/ctx.rs":"8f58672c5f3bc09b8f09c76f1d423431cbff786af75f5b39a0cef23b820d48c6","src/endian.rs":"5b717eb5ed0dc2b536779316b020df4e6489c05b13b4fd9b5f5e683aca1b2c28","src/error.rs":"a6a0ec9a6237d23febd608637c0e3926d147511e7983195366bc5a11f12d9093","src/greater.rs":"29d9736f9d35a0f92ca054c7a36878ade0a77b4e8ee27441c34cd81c6bdb68e6","src/leb128.rs":"e343f4e104ca6d8660a3dded30934b83bad4c04d8888ce2cbebfa562f5ac115d","src/lesser.rs":"d3028781977e60d67003512e45666935deab9a03c76a3ba9316a5dbdddf432eb","src/lib.rs":"49d02fa761bb2a771d1857ffd150aa4b6f55b4f03aee1a7a23d8181c76a55fd6","src/pread.rs":"64afdcf2c2785f1f23d065ec5e565d78569086dfd9ece0a3d2553b05aee5df9b","src/pwrite.rs":"05e3129ec666790a61f5b5f894ad863103e213eb798243cfe5f2cbb54d042ba1","tests/api.rs":"1bef345e020a6a4e590350ea4f6069c5836941656379e252bfbdaee6edbbc0de"},"package":"04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da"}
{"files":{"Cargo.toml":"c9242ab52e0b3ba02d9557c3ef2070bc173dfbef05870c3c4831937233de38c0","LICENSE":"6e24b7455f0b9afefdf4f3efd59a56ce76a3020c2dc4371937e281fc5e587fd7","README.md":"7a7f6695853fbc174e3b016d72a8ef0113e313c897269779c7c368f102ed0c23","src/ctx.rs":"9bd92f1038962a8034450b64818cc7b5eaebacde2a229eec5b9cda3ec99c5ae4","src/endian.rs":"e3e0fcb99d0f71f739b6f0ea466a5d3479ed9c90f29269adb1aa2d725ac12af4","src/error.rs":"d91d332a87bde35738cc5915279fc0fde65301fe86ef98ec36126e1de9fd0474","src/greater.rs":"29d9736f9d35a0f92ca054c7a36878ade0a77b4e8ee27441c34cd81c6bdb68e6","src/leb128.rs":"eb71761d708f78c785e6dbe8d385fd90317d08369d1c3ac57d142ca7c0e09e9e","src/lesser.rs":"16fa2c3a737c126b7ac40117c960bc025fb418abc99559c244e8a5ae4348c730","src/lib.rs":"e9a1b9b0ee06ba39de6925f4bc23cb847c8ec3831ca37280c3660dc6d1b28826","src/pread.rs":"80eb931ad7340bba7e1a03a7cbef62c93537bdf4703e467210957d07b82f6489","src/pwrite.rs":"5384d97a57a245e057bca70bd3a386c2942c89f6f7555bcad498b348ee555543"},"package":"6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6"}

View File

@ -1,17 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
Before 1.0, this project does not adhere to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [0.10.0] - unreleased
### Added
- scroll is now 2018 compliant, thanks @lzutao: https://github.com/m4b/scroll/pull/49
- scroll_derive now lives in scroll repo itself
### Removed
- BREAKING: removed units/size generics in SizeWith, thanks @willglynn: https://github.com/m4b/scroll/pull/45
## [0.9.1] - 2018-9-22
### Added
- pread primitive references: https://github.com/m4b/scroll/pull/35
- u128/i128 support: https://github.com/m4b/scroll/pull/32
- CStr support: https://github.com/m4b/scroll/pull/30

205
third_party/rust/scroll/Cargo.lock generated vendored
View File

@ -1,205 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "byteorder"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "const_fn"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
[[package]]
name = "crossbeam-channel"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
dependencies = [
"cfg-if",
"const_fn",
"crossbeam-utils",
"lazy_static",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
dependencies = [
"autocfg",
"cfg-if",
"lazy_static",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "hermit-abi"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
dependencies = [
"libc",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
[[package]]
name = "memoffset"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
dependencies = [
"autocfg",
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"lazy_static",
"num_cpus",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "scroll"
version = "0.11.0"
dependencies = [
"byteorder",
"rayon",
"scroll_derive",
]
[[package]]
name = "scroll_derive"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdbda6ac5cd1321e724fa9cee216f3a61885889b896f073b8f82322789c5250e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"

View File

@ -11,26 +11,37 @@
[package]
edition = "2021"
rust-version = "1.63"
name = "scroll"
version = "0.11.0"
authors = ["m4b <m4b.github.io@gmail.com>", "Ted Mielczarek <ted@mielczarek.org>"]
version = "0.12.0"
authors = [
"m4b <m4b.github.io@gmail.com>",
"Ted Mielczarek <ted@mielczarek.org>",
]
include = [
"src/**/*",
"Cargo.toml",
"LICENSE",
"README.md",
]
description = "A suite of powerful, extensible, generic, endian-aware Read/Write traits for byte buffers"
documentation = "https://docs.rs/scroll"
readme = "README.md"
keywords = ["bytes", "endian", "immutable", "pread", "pwrite"]
keywords = [
"bytes",
"endian",
"immutable",
"pread",
"pwrite",
]
license = "MIT"
repository = "https://github.com/m4b/scroll"
resolver = "2"
[dependencies.scroll_derive]
version = "0.11"
optional = true
[dev-dependencies.byteorder]
version = "1"
[dev-dependencies.rayon]
version = "1"
[dependencies.scroll_derive]
version = "0.12"
optional = true
[features]
default = ["std"]
derive = ["scroll_derive"]
derive = ["dep:scroll_derive"]
std = []

View File

@ -1,4 +1,13 @@
[![Build Status](https://travis-ci.org/m4b/scroll.svg?branch=master)](https://travis-ci.org/m4b/scroll)
[![Actions][actions-badge]][actions-url]
[![crates.io version][crates-scroll-badge]][crates-scroll]
<!-- Badges' links -->
[actions-badge]: https://github.com/m4b/scroll/workflows/CI/badge.svg?branch=master
[actions-url]: https://github.com/m4b/scroll/actions
[crates-scroll-badge]: https://img.shields.io/crates/v/scroll.svg
[crates-scroll]: https://crates.io/crates/scroll
## Scroll - cast some magic
```text
@ -23,7 +32,7 @@ Add to your `Cargo.toml`
```toml, no_test
[dependencies]
scroll = "0.10"
scroll = "0.11"
```
### Overview

View File

@ -1,157 +0,0 @@
#![feature(test)]
extern crate test;
use scroll::{Cread, Pread, LE};
use test::black_box;
#[bench]
fn bench_parallel_cread_with(b: &mut test::Bencher) {
use rayon::prelude::*;
let vec = vec![0u8; 1_000_000];
let nums = vec![0usize; 500_000];
b.iter(|| {
let data = black_box(&vec[..]);
nums.par_iter().for_each(|offset| {
let _: u16 = black_box(data.cread_with(*offset, LE));
});
});
b.bytes = vec.len() as u64;
}
#[bench]
fn bench_cread_vec(b: &mut test::Bencher) {
let vec = vec![0u8; 1_000_000];
b.iter(|| {
let data = black_box(&vec[..]);
for val in data.chunks(2) {
let _: u16 = black_box(val.cread_with(0, LE));
}
});
b.bytes = vec.len() as u64;
}
#[bench]
fn bench_cread(b: &mut test::Bencher) {
const NITER: i32 = 100_000;
b.iter(|| {
for _ in 1..NITER {
let data = black_box([1, 2]);
let _: u16 = black_box(data.cread(0));
}
});
b.bytes = 2 * NITER as u64;
}
#[bench]
fn bench_pread_ctx_vec(b: &mut test::Bencher) {
let vec = vec![0u8; 1_000_000];
b.iter(|| {
let data = black_box(&vec[..]);
for val in data.chunks(2) {
let _: Result<u16, _> = black_box(val.pread(0));
}
});
b.bytes = vec.len() as u64;
}
#[bench]
fn bench_pread_with_unwrap(b: &mut test::Bencher) {
const NITER: i32 = 100_000;
b.iter(|| {
for _ in 1..NITER {
let data: &[u8] = &black_box([1, 2]);
let _: u16 = black_box(data.pread_with(0, LE).unwrap());
}
});
b.bytes = 2 * NITER as u64;
}
#[bench]
fn bench_pread_vec(b: &mut test::Bencher) {
let vec = vec![0u8; 1_000_000];
b.iter(|| {
let data = black_box(&vec[..]);
for val in data.chunks(2) {
let _: Result<u16, _> = black_box(val.pread_with(0, LE));
}
});
b.bytes = vec.len() as u64;
}
#[bench]
fn bench_pread_unwrap(b: &mut test::Bencher) {
const NITER: i32 = 100_000;
b.iter(|| {
for _ in 1..NITER {
let data = black_box([1, 2]);
let _: u16 = black_box(data.pread(0)).unwrap();
}
});
b.bytes = 2 * NITER as u64;
}
#[bench]
fn bench_gread_vec(b: &mut test::Bencher) {
let vec = vec![0u8; 1_000_000];
b.iter(|| {
let data = black_box(&vec[..]);
for val in data.chunks(2) {
let mut offset = 0;
let _: Result<u16, _> = black_box(val.gread(&mut offset));
}
});
b.bytes = vec.len() as u64;
}
#[bench]
fn bench_gread_unwrap(b: &mut test::Bencher) {
const NITER: i32 = 100_000;
b.iter(|| {
for _ in 1..NITER {
let data = black_box([1, 2]);
let mut offset = 0;
let _: u16 = black_box(data.gread_with(&mut offset, LE).unwrap());
}
});
b.bytes = 2 * NITER as u64;
}
#[bench]
fn bench_parallel_pread_with(b: &mut test::Bencher) {
use rayon::prelude::*;
let vec = vec![0u8; 1_000_000];
let nums = vec![0usize; 500_000];
b.iter(|| {
let data = black_box(&vec[..]);
nums.par_iter().for_each(|offset| {
let _: Result<u16, _> = black_box(data.pread_with(*offset, LE));
});
});
b.bytes = vec.len() as u64;
}
#[bench]
fn bench_byteorder_vec(b: &mut test::Bencher) {
use byteorder::ReadBytesExt;
let vec = vec![0u8; 1_000_000];
b.iter(|| {
let data = black_box(&vec[..]);
for mut val in data.chunks(2) {
let _: Result<u16, _> = black_box(val.read_u16::<byteorder::LittleEndian>());
}
});
b.bytes = vec.len() as u64;
}
#[bench]
fn bench_byteorder(b: &mut test::Bencher) {
use byteorder::ByteOrder;
const NITER: i32 = 100_000;
b.iter(|| {
for _ in 1..NITER {
let data = black_box([1, 2]);
let _: u16 = black_box(byteorder::LittleEndian::read_u16(&data));
}
});
b.bytes = 2 * NITER as u64;
}

View File

@ -1,24 +0,0 @@
use scroll::{ctx, Endian, Pread, BE};
#[derive(Debug)]
struct Data<'a> {
name: &'a str,
id: u32,
}
impl<'a> ctx::TryFromCtx<'a, Endian> for Data<'a> {
type Error = scroll::Error;
fn try_from_ctx(src: &'a [u8], endian: Endian) -> Result<(Self, usize), Self::Error> {
let name = src.pread::<&'a str>(0)?;
let id = src.pread_with(name.len() + 1, endian)?;
Ok((Data { name: name, id: id }, name.len() + 4))
}
}
fn main() {
let bytes = b"UserName\x00\x01\x02\x03\x04";
let data = bytes.pread_with::<Data>(0, BE).unwrap();
assert_eq!(data.id, 0x01020304);
assert_eq!(data.name.to_string(), "UserName".to_string());
println!("Data: {:?}", &data);
}

View File

@ -180,17 +180,14 @@
//! }
//! ```
use core::mem::size_of;
use core::mem::transmute;
use core::mem::{size_of, MaybeUninit};
use core::ptr::copy_nonoverlapping;
use core::result;
use core::str;
use core::{result, str};
#[cfg(feature = "std")]
use std::ffi::{CStr, CString};
use crate::endian::Endian;
use crate::error;
use crate::{error, Pread, Pwrite};
/// A trait for measuring how large something is; for a byte sequence, it will be its length.
pub trait MeasureWith<Ctx> {
@ -240,18 +237,14 @@ impl Default for StrCtx {
impl StrCtx {
pub fn len(&self) -> usize {
match *self {
match self {
StrCtx::Delimiter(_) | StrCtx::DelimiterUntil(_, _) => 1,
StrCtx::Length(_) => 0,
}
}
pub fn is_empty(&self) -> bool {
if let StrCtx::Length(_) = *self {
true
} else {
false
}
matches!(self, StrCtx::Length(_))
}
}
@ -267,6 +260,7 @@ pub trait FromCtx<Ctx: Copy = (), This: ?Sized = [u8]> {
/// `[u8]`), then you need to implement this trait
///
/// ```rust
/// ##[cfg(feature = "std")] {
/// use scroll::{self, ctx, Pread};
/// #[derive(Debug, PartialEq, Eq)]
/// pub struct Foo(u16);
@ -286,6 +280,7 @@ pub trait FromCtx<Ctx: Copy = (), This: ?Sized = [u8]> {
///
/// let foo2 = bytes.pread_with::<Foo>(0, scroll::BE).unwrap();
/// assert_eq!(Foo(0xdeadu16), foo2);
/// # }
/// ```
///
/// # Advanced: Using Your Own Error in `TryFromCtx`
@ -350,6 +345,7 @@ pub trait IntoCtx<Ctx: Copy = (), This: ?Sized = [u8]>: Sized {
/// To implement writing into an arbitrary byte buffer, implement `TryIntoCtx`
/// # Example
/// ```rust
/// ##[cfg(feature = "std")] {
/// use scroll::{self, ctx, LE, Endian, Pwrite};
/// #[derive(Debug, PartialEq, Eq)]
/// pub struct Foo(u16);
@ -369,6 +365,7 @@ pub trait IntoCtx<Ctx: Copy = (), This: ?Sized = [u8]>: Sized {
///
/// let mut bytes: [u8; 4] = [0, 0, 0, 0];
/// bytes.pwrite_with(Foo(0x7f), 1, LE).unwrap();
/// # }
/// ```
pub trait TryIntoCtx<Ctx: Copy = (), This: ?Sized = [u8]>: Sized {
type Error;
@ -403,13 +400,14 @@ macro_rules! signed_to_unsigned {
macro_rules! write_into {
($typ:ty, $size:expr, $n:expr, $dst:expr, $endian:expr) => {{
assert!($dst.len() >= $size);
let bytes = if $endian.is_little() {
$n.to_le()
} else {
$n.to_be()
}
.to_ne_bytes();
unsafe {
assert!($dst.len() >= $size);
let bytes = transmute::<$typ, [u8; $size]>(if $endian.is_little() {
$n.to_le()
} else {
$n.to_be()
});
copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size);
}
}};
@ -570,12 +568,12 @@ macro_rules! from_ctx_float_impl {
&mut data as *mut signed_to_unsigned!($typ) as *mut u8,
$size,
);
transmute(if le.is_little() {
data.to_le()
} else {
data.to_be()
})
}
$typ::from_bits(if le.is_little() {
data.to_le()
} else {
data.to_be()
})
}
}
impl<'a> TryFromCtx<'a, Endian> for $typ
@ -621,13 +619,7 @@ macro_rules! into_ctx_float_impl {
#[inline]
fn into_ctx(self, dst: &mut [u8], le: Endian) {
assert!(dst.len() >= $size);
write_into!(
signed_to_unsigned!($typ),
$size,
transmute::<$typ, signed_to_unsigned!($typ)>(self),
dst,
le
);
write_into!(signed_to_unsigned!($typ), $size, self.to_bits(), dst, le);
}
}
impl<'a> IntoCtx<Endian> for &'a $typ {
@ -725,7 +717,7 @@ impl<'a> TryIntoCtx for &'a [u8] {
let src_len = self.len() as isize;
let dst_len = dst.len() as isize;
// if src_len < 0 || dst_len < 0 || offset < 0 {
// return Err(error::Error::BadOffset(format!("requested operation has negative casts: src len: {} dst len: {} offset: {}", src_len, dst_len, offset)).into())
// return Err(error::Error::BadOffset(format!("requested operation has negative casts: src len: {src_len} dst len: {dst_len} offset: {offset}")).into())
// }
if src_len > dst_len {
Err(error::Error::TooBig {
@ -789,6 +781,56 @@ impl<'a> TryFromCtx<'a, usize> for &'a [u8] {
}
}
impl<'a, Ctx: Copy, T: TryFromCtx<'a, Ctx, Error = error::Error>, const N: usize>
TryFromCtx<'a, Ctx> for [T; N]
{
type Error = error::Error;
fn try_from_ctx(src: &'a [u8], ctx: Ctx) -> Result<(Self, usize), Self::Error> {
let mut offset = 0;
let mut buf: [MaybeUninit<T>; N] = core::array::from_fn(|_| MaybeUninit::uninit());
let mut error_ctx = None;
for (idx, element) in buf.iter_mut().enumerate() {
match src.gread_with::<T>(&mut offset, ctx) {
Ok(val) => {
*element = MaybeUninit::new(val);
}
Err(e) => {
error_ctx = Some((e, idx));
break;
}
}
}
if let Some((e, idx)) = error_ctx {
for element in &mut buf[0..idx].iter_mut() {
// SAFETY: Any element upto idx must have already been initialized, since
// we iterate until we encounter an error.
unsafe {
element.assume_init_drop();
}
}
Err(e)
} else {
// SAFETY: we initialized each element above by preading them out, correctness
// of the initialized element is guaranted by pread itself
Ok((buf.map(|element| unsafe { element.assume_init() }), offset))
}
}
}
impl<Ctx: Copy, T: TryIntoCtx<Ctx, Error = error::Error>, const N: usize> TryIntoCtx<Ctx>
for [T; N]
{
type Error = error::Error;
fn try_into_ctx(self, buf: &mut [u8], ctx: Ctx) -> Result<usize, Self::Error> {
let mut offset = 0;
for element in self {
buf.gwrite_with(element, &mut offset, ctx)?;
}
Ok(offset)
}
}
#[cfg(feature = "std")]
impl<'a> TryFromCtx<'a> for &'a CStr {
type Error = error::Error;
@ -863,11 +905,11 @@ impl TryIntoCtx for CString {
// }
#[cfg(test)]
#[cfg(feature = "std")]
mod tests {
use super::*;
#[test]
#[cfg(feature = "std")]
fn parse_a_cstr() {
let src = CString::new("Hello World").unwrap();
let as_bytes = src.as_bytes_with_nul();
@ -879,7 +921,6 @@ mod tests {
}
#[test]
#[cfg(feature = "std")]
fn round_trip_a_c_str() {
let src = CString::new("Hello World").unwrap();
let src = src.as_c_str();

View File

@ -43,9 +43,6 @@ impl Endian {
}
#[inline]
pub fn is_little(&self) -> bool {
match *self {
LE => true,
_ => false,
}
*self == LE
}
}

View File

@ -1,10 +1,7 @@
use core::fmt::{self, Display};
use core::result;
#[cfg(feature = "std")]
use std::error;
#[cfg(feature = "std")]
use std::io;
use std::{error, io};
#[derive(Debug)]
/// A custom Scroll error
@ -20,18 +17,19 @@ pub enum Error {
size: usize,
msg: &'static str,
},
/// A custom Scroll error for reporting messages to clients.
/// For no-std, use [`Error::BadInput`] with a static string.
#[cfg(feature = "std")]
/// A custom Scroll error for reporting messages to clients
Custom(String),
#[cfg(feature = "std")]
/// Returned when IO based errors are encountered
#[cfg(feature = "std")]
IO(io::Error),
}
#[cfg(feature = "std")]
impl error::Error for Error {
fn description(&self) -> &str {
match *self {
match self {
Error::TooBig { .. } => "TooBig",
Error::BadOffset(_) => "BadOffset",
Error::BadInput { .. } => "BadInput",
@ -40,7 +38,7 @@ impl error::Error for Error {
}
}
fn cause(&self) -> Option<&dyn error::Error> {
match *self {
match self {
Error::TooBig { .. } => None,
Error::BadOffset(_) => None,
Error::BadInput { .. } => None,
@ -59,23 +57,23 @@ impl From<io::Error> for Error {
impl Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
match self {
Error::TooBig { ref size, ref len } => {
write!(fmt, "type is too big ({}) for {}", size, len)
write!(fmt, "type is too big ({size}) for {len}")
}
Error::BadOffset(ref offset) => {
write!(fmt, "bad offset {}", offset)
write!(fmt, "bad offset {offset}")
}
Error::BadInput { ref msg, ref size } => {
write!(fmt, "bad input {} ({})", msg, size)
write!(fmt, "bad input {msg} ({size})")
}
#[cfg(feature = "std")]
Error::Custom(ref msg) => {
write!(fmt, "{}", msg)
write!(fmt, "{msg}")
}
#[cfg(feature = "std")]
Error::IO(ref err) => {
write!(fmt, "{}", err)
write!(fmt, "{err}")
}
}
}

View File

@ -1,9 +1,8 @@
use crate::ctx::TryFromCtx;
use crate::error;
use crate::Pread;
use core::convert::{AsRef, From};
use core::result;
use core::u8;
use core::{result, u8};
use crate::ctx::TryFromCtx;
use crate::{error, Pread};
#[derive(Debug, PartialEq, Copy, Clone)]
/// An unsigned leb128 integer
@ -184,21 +183,24 @@ mod tests {
let buf = [2u8 | CONTINUATION_BIT, 1];
let bytes = &buf[..];
let num = bytes.pread::<Uleb128>(0).unwrap();
println!("num: {:?}", &num);
#[cfg(feature = "std")]
println!("num: {num:?}");
assert_eq!(130u64, num.into());
assert_eq!(num.size(), 2);
let buf = [0x00, 0x01];
let bytes = &buf[..];
let num = bytes.pread::<Uleb128>(0).unwrap();
println!("num: {:?}", &num);
#[cfg(feature = "std")]
println!("num: {num:?}");
assert_eq!(0u64, num.into());
assert_eq!(num.size(), 1);
let buf = [0x21];
let bytes = &buf[..];
let num = bytes.pread::<Uleb128>(0).unwrap();
println!("num: {:?}", &num);
#[cfg(feature = "std")]
println!("num: {num:?}");
assert_eq!(0x21u64, num.into());
assert_eq!(num.size(), 1);
}

View File

@ -1,6 +1,7 @@
use crate::ctx::{FromCtx, IntoCtx, SizeWith};
use std::io::{Read, Result, Write};
use crate::ctx::{FromCtx, IntoCtx, SizeWith};
/// An extension trait to `std::io::Read` streams; mainly targeted at reading primitive types with
/// a known size.
///
@ -104,8 +105,8 @@ pub trait IOread<Ctx: Copy>: Read {
fn ioread_with<N: FromCtx<Ctx> + SizeWith<Ctx>>(&mut self, ctx: Ctx) -> Result<N> {
let mut scratch = [0u8; 256];
let size = N::size_with(&ctx);
let mut buf = &mut scratch[0..size];
self.read_exact(&mut buf)?;
let buf = &mut scratch[0..size];
self.read_exact(buf)?;
Ok(N::from_ctx(buf, ctx))
}
}

View File

@ -119,6 +119,7 @@
//! [FromCtx](ctx/trait.FromCtx.html) and [SizeWith](ctx/trait.SizeWith.html).
//!
//! ```rust
//! ##[cfg(feature = "std")] {
//! use std::io::Cursor;
//! use scroll::{IOread, ctx, Endian};
//! let bytes = [0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xef,0xbe,0x00,0x00,];
@ -139,12 +140,14 @@
//! // read/written, e.g. switching between ELF32 or ELF64 at runtime.
//! let size = <u64 as ctx::SizeWith<Endian>>::size_with(&Endian::Little) as u64;
//! assert_eq!(prev + size, after);
//! # }
//! ```
//!
//! In the same vein as IOread we can use IOwrite to write a type to anything implementing
//! `std::io::Write`:
//!
//! ```rust
//! ##[cfg(feature = "std")] {
//! use std::io::Cursor;
//! use scroll::{IOwrite};
//!
@ -155,6 +158,7 @@
//! cursor.iowrite_with(0xdeadbeef as u32, scroll::BE).unwrap();
//!
//! assert_eq!(cursor.into_inner(), [0xde, 0xad, 0xbe, 0xef, 0x0]);
//! # }
//! ```
//!
//! ## Complex use cases
@ -249,8 +253,7 @@ pub use crate::pwrite::*;
#[doc(hidden)]
pub mod export {
pub use ::core::mem;
pub use ::core::result;
pub use ::core::{mem, result};
}
#[allow(unused)]
@ -267,7 +270,6 @@ doc_comment!(include_str!("../README.md"));
#[cfg(test)]
mod tests {
#[allow(overflowing_literals)]
use super::LE;
#[test]
@ -355,36 +357,48 @@ mod tests {
let bytes: [u8; 2] = [0x2e, 0x0];
let b = &bytes[..];
let s: &str = b.pread(0).unwrap();
println!("str: {}", s);
#[cfg(feature = "std")]
println!("str: {s}");
assert_eq!(s.len(), bytes[..].len() - 1);
let bytes: &[u8] = b"hello, world!\0some_other_things";
let hello_world: &str = bytes.pread_with(0, StrCtx::Delimiter(NULL)).unwrap();
println!("{:?}", &hello_world);
#[cfg(feature = "std")]
println!("{hello_world:?}");
assert_eq!(hello_world.len(), 13);
let hello: &str = bytes.pread_with(0, StrCtx::Delimiter(SPACE)).unwrap();
println!("{:?}", &hello);
#[cfg(feature = "std")]
println!("{hello:?}");
assert_eq!(hello.len(), 6);
// this could result in underflow so we just try it
let _error = bytes.pread_with::<&str>(6, StrCtx::Delimiter(SPACE));
let error = bytes.pread_with::<&str>(7, StrCtx::Delimiter(SPACE));
println!("{:?}", &error);
#[cfg(feature = "std")]
println!("{error:?}");
assert!(error.is_ok());
}
/// In this test, we are testing preading
/// at length boundaries.
/// In the past, this test was supposed to test failures for `hello_world`.
/// Since PR#94, this test is unwrapping as we exploit
/// the fact that if you do &x[x.len()..] you get an empty slice.
#[test]
fn pread_str_weird() {
use super::ctx::*;
use super::Pread;
let bytes: &[u8] = b"";
let hello_world = bytes.pread_with::<&str>(0, StrCtx::Delimiter(NULL));
println!("1 {:?}", &hello_world);
assert_eq!(hello_world.is_err(), true);
#[cfg(feature = "std")]
println!("1 {hello_world:?}");
assert!(hello_world.unwrap().is_empty());
let error = bytes.pread_with::<&str>(7, StrCtx::Delimiter(SPACE));
println!("2 {:?}", &error);
#[cfg(feature = "std")]
println!("2 {error:?}");
assert!(error.is_err());
let bytes: &[u8] = b"\0";
let null = bytes.pread::<&str>(0).unwrap();
println!("3 {:?}", &null);
#[cfg(feature = "std")]
println!("3 {null:?}");
assert_eq!(null.len(), 0);
}
@ -413,8 +427,7 @@ mod tests {
assert_eq!(bytes, "bytes");
}
use std::error;
use std::fmt::{self, Display};
use core::fmt::{self, Display};
#[derive(Debug)]
pub struct ExternalError {}
@ -425,11 +438,12 @@ mod tests {
}
}
impl error::Error for ExternalError {
#[cfg(feature = "std")]
impl std::error::Error for ExternalError {
fn description(&self) -> &str {
"ExternalError"
}
fn cause(&self) -> Option<&dyn error::Error> {
fn cause(&self) -> Option<&dyn std::error::Error> {
None
}
}
@ -451,7 +465,7 @@ mod tests {
fn try_into_ctx(self, this: &mut [u8], le: super::Endian) -> Result<usize, Self::Error> {
use super::Pwrite;
if this.len() < 2 {
return Err((ExternalError {}).into());
return Err(ExternalError {});
}
this.pwrite_with(self.0, 0, le)?;
Ok(2)
@ -463,7 +477,7 @@ mod tests {
fn try_from_ctx(this: &'a [u8], le: super::Endian) -> Result<(Self, usize), Self::Error> {
use super::Pread;
if this.len() > 2 {
return Err((ExternalError {}).into());
return Err(ExternalError {});
}
let n = this.pread_with(0, le)?;
Ok((Foo(n), 2))
@ -499,7 +513,7 @@ mod tests {
let mut offset = 0;
let deadbeef: $typ = bytes.gread_with(&mut offset, LE).unwrap();
assert_eq!(deadbeef, $deadbeef as $typ);
assert_eq!(offset, ::std::mem::size_of::<$typ>());
assert_eq!(offset, ::core::mem::size_of::<$typ>());
}
};
}
@ -518,7 +532,7 @@ mod tests {
let mut offset = 0;
let deadbeef: $typ = bytes.gread_with(&mut offset, LE).unwrap();
assert_eq!(deadbeef, $deadbeef as $typ);
assert_eq!(offset, ::std::mem::size_of::<$typ>());
assert_eq!(offset, ::core::mem::size_of::<$typ>());
}
};
}
@ -537,8 +551,8 @@ mod tests {
let o2 = &mut 0;
let val: $typ = buffer.gread_with(o2, LE).unwrap();
assert_eq!(val, $val);
assert_eq!(*offset, ::std::mem::size_of::<$typ>());
assert_eq!(*o2, ::std::mem::size_of::<$typ>());
assert_eq!(*offset, ::core::mem::size_of::<$typ>());
assert_eq!(*o2, ::core::mem::size_of::<$typ>());
assert_eq!(*o2, *offset);
buffer.gwrite_with($val.clone(), offset, BE).unwrap();
let val: $typ = buffer.gread_with(o2, BE).unwrap();
@ -612,16 +626,17 @@ mod tests {
let res = b.gread_with::<&str>(offset, StrCtx::Length(3));
assert!(res.is_err());
*offset = 0;
let astring: [u8; 3] = [0x45, 042, 0x44];
let astring: [u8; 3] = [0x45, 0x42, 0x44];
let string = astring.gread_with::<&str>(offset, StrCtx::Length(2));
match &string {
&Ok(_) => {}
&Err(ref err) => {
println!("{}", &err);
Ok(_) => {}
Err(_err) => {
#[cfg(feature = "std")]
println!("{_err}");
panic!();
}
}
assert_eq!(string.unwrap(), "E*");
assert_eq!(string.unwrap(), "EB");
*offset = 0;
let bytes2: &[u8] = b.gread_with(offset, 2).unwrap();
assert_eq!(*offset, 2);

View File

@ -20,6 +20,11 @@ use crate::error;
/// over chunks of memory or any other indexable type — but scroll does come with a set of powerful
/// blanket implementations for data being a continous block of byte-addressable memory.
///
/// Note that in the particular case of the implementation of `Pread` for `[u8]`,
/// reading it at the length boundary of that slice will cause to read from an empty slice.
/// i.e. we make use of the fact that `&bytes[bytes.len()..]` will return an empty slice, rather
/// than returning an error. In the past, scroll returned an offset error.
///
/// Pread provides two main groups of functions: pread and gread.
///
/// `pread` is the basic function that simply extracts a given type from a given data store - either
@ -167,7 +172,7 @@ impl<Ctx: Copy, E: From<error::Error>> Pread<Ctx, E> for [u8] {
ctx: Ctx,
) -> result::Result<N, E> {
let start = *offset;
if start >= self.len() {
if start > self.len() {
return Err(error::Error::BadOffset(start).into());
}
N::try_from_ctx(&self[start..], ctx).map(|(n, size)| {

View File

@ -19,6 +19,13 @@ use crate::error;
/// with 'read' switched for 'write' and 'From' switched with 'Into' so if you haven't yet you
/// should read the documentation of `Pread` first.
///
/// As with `Pread`, note that in the particular case of the implementation of `Pwrite` for `[u8]`,
/// writing it at the length boundary of that slice will cause to write in an empty slice.
/// i.e. we make use of the fact that `&bytes[bytes.len()..]` will return an empty slice, rather
/// than returning an error. In the past, scroll returned an offset error.
/// In this case, this is relevant if you are writing an empty slice inside an empty slice and
/// expected this to work.
///
/// Unless you need to implement your own data store — that is either can't convert to `&[u8]` or
/// have a data that does not expose a `&mut [u8]` — you will probably want to implement
/// [TryIntoCtx](ctx/trait.TryIntoCtx.html) on your Rust types to be written.
@ -87,7 +94,7 @@ impl<Ctx: Copy, E: From<error::Error>> Pwrite<Ctx, E> for [u8] {
offset: usize,
ctx: Ctx,
) -> result::Result<usize, E> {
if offset >= self.len() {
if offset > self.len() {
return Err(error::Error::BadOffset(offset).into());
}
let dst = &mut self[offset..];

View File

@ -1,292 +0,0 @@
// this exists primarily to test various API usages of scroll; e.g., must compile
// guard against potential undefined behaviour when borrowing from
// packed structs. See https://github.com/rust-lang/rust/issues/46043
#![deny(unaligned_references)]
// #[macro_use] extern crate scroll_derive;
use scroll::ctx::SizeWith;
use scroll::{ctx, Cread, Pread, Result};
use std::ops::{Deref, DerefMut};
#[derive(Default)]
pub struct Section<'a> {
pub sectname: [u8; 16],
pub segname: [u8; 16],
pub addr: u64,
pub size: u64,
pub offset: u32,
pub align: u32,
pub reloff: u32,
pub nreloc: u32,
pub flags: u32,
pub data: &'a [u8],
}
impl<'a> Section<'a> {
pub fn name(&self) -> Result<&str> {
self.sectname.pread::<&str>(0)
}
pub fn segname(&self) -> Result<&str> {
self.segname.pread::<&str>(0)
}
}
impl<'a> ctx::SizeWith for Section<'a> {
fn size_with(_ctx: &()) -> usize {
4
}
}
#[repr(C)]
// renable when scroll_derive Pread/Pwrite matches
//#[derive(Debug, Clone, Copy, Pread, Pwrite)]
#[derive(Debug, Clone, Copy)]
pub struct Section32 {
pub sectname: [u8; 16],
pub segname: [u8; 16],
pub addr: u32,
pub size: u32,
pub offset: u32,
pub align: u32,
pub reloff: u32,
pub nreloc: u32,
pub flags: u32,
pub reserved1: u32,
pub reserved2: u32,
}
impl<'a> ctx::TryFromCtx<'a, ()> for Section<'a> {
type Error = scroll::Error;
fn try_from_ctx(
_bytes: &'a [u8],
_ctx: (),
) -> ::std::result::Result<(Self, usize), Self::Error> {
let section = Section::default();
Ok((section, ::std::mem::size_of::<Section>()))
}
}
pub struct Segment<'a> {
pub cmd: u32,
pub cmdsize: u32,
pub segname: [u8; 16],
pub vmaddr: u64,
pub vmsize: u64,
pub fileoff: u64,
pub filesize: u64,
pub maxprot: u32,
pub initprot: u32,
pub nsects: u32,
pub flags: u32,
pub data: &'a [u8],
offset: usize,
raw_data: &'a [u8],
}
impl<'a> Segment<'a> {
pub fn name(&self) -> Result<&str> {
Ok(self.segname.pread::<&str>(0)?)
}
pub fn sections(&self) -> Result<Vec<Section<'a>>> {
let nsects = self.nsects as usize;
let mut sections = Vec::with_capacity(nsects);
let offset = &mut (self.offset + Self::size_with(&()));
let _size = Section::size_with(&());
let raw_data: &'a [u8] = self.raw_data;
for _ in 0..nsects {
let section = raw_data.gread_with::<Section<'a>>(offset, ())?;
sections.push(section);
//offset += size;
}
Ok(sections)
}
}
impl<'a> ctx::SizeWith for Segment<'a> {
fn size_with(_ctx: &()) -> usize {
4
}
}
pub struct Segments<'a> {
pub segments: Vec<Segment<'a>>,
}
impl<'a> Deref for Segments<'a> {
type Target = Vec<Segment<'a>>;
fn deref(&self) -> &Self::Target {
&self.segments
}
}
impl<'a> DerefMut for Segments<'a> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.segments
}
}
impl<'a> Segments<'a> {
pub fn new() -> Self {
Segments {
segments: Vec::new(),
}
}
pub fn sections(&self) -> Result<Vec<Vec<Section<'a>>>> {
let mut sections = Vec::new();
for segment in &self.segments {
sections.push(segment.sections()?);
}
Ok(sections)
}
}
fn lifetime_passthrough_<'a>(segments: &Segments<'a>, section_name: &str) -> Option<&'a [u8]> {
let segment_name = "__TEXT";
for segment in &segments.segments {
if let Ok(name) = segment.name() {
println!("segment.name: {}", name);
if name == segment_name {
if let Ok(sections) = segment.sections() {
for section in sections {
let sname = section.name().unwrap();
println!("section.name: {}", sname);
if section_name == sname {
return Some(section.data);
}
}
}
}
}
}
None
}
#[test]
fn lifetime_passthrough() {
let segments = Segments::new();
let _res = lifetime_passthrough_(&segments, "__text");
assert!(true)
}
#[derive(Default)]
#[repr(packed)]
struct Foo {
foo: i64,
bar: u32,
}
impl scroll::ctx::FromCtx<scroll::Endian> for Foo {
fn from_ctx(bytes: &[u8], ctx: scroll::Endian) -> Self {
Foo {
foo: bytes.cread_with::<i64>(0, ctx),
bar: bytes.cread_with::<u32>(8, ctx),
}
}
}
impl scroll::ctx::SizeWith<scroll::Endian> for Foo {
fn size_with(_: &scroll::Endian) -> usize {
::std::mem::size_of::<Foo>()
}
}
#[test]
fn ioread_api() {
use scroll::{IOread, LE};
use std::io::Cursor;
let bytes_ = [
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xbe, 0x00, 0x00,
];
let mut bytes = Cursor::new(bytes_);
let foo = bytes.ioread_with::<i64>(LE).unwrap();
let bar = bytes.ioread_with::<u32>(LE).unwrap();
assert_eq!(foo, 1);
assert_eq!(bar, 0xbeef);
let error = bytes.ioread_with::<f64>(LE);
assert!(error.is_err());
let mut bytes = Cursor::new(bytes_);
let foo_ = bytes.ioread_with::<Foo>(LE).unwrap();
assert_eq!({ foo_.foo }, foo);
assert_eq!({ foo_.bar }, bar);
}
#[repr(packed)]
struct Bar {
foo: i32,
bar: u32,
}
impl scroll::ctx::FromCtx<scroll::Endian> for Bar {
fn from_ctx(bytes: &[u8], ctx: scroll::Endian) -> Self {
Bar {
foo: bytes.cread_with(0, ctx),
bar: bytes.cread_with(4, ctx),
}
}
}
#[test]
fn cread_api() {
use scroll::{Cread, LE};
let bytes = [
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xbe, 0x00, 0x00,
];
let foo = bytes.cread_with::<u64>(0, LE);
let bar = bytes.cread_with::<u32>(8, LE);
assert_eq!(foo, 1);
assert_eq!(bar, 0xbeef);
}
#[test]
fn cread_api_customtype() {
use scroll::{Cread, LE};
let bytes = [0xff, 0xff, 0xff, 0xff, 0xef, 0xbe, 0xad, 0xde];
let bar = &bytes[..].cread_with::<Bar>(0, LE);
assert_eq!({ bar.foo }, -1);
assert_eq!({ bar.bar }, 0xdeadbeef);
}
#[test]
#[should_panic]
fn cread_api_badindex() {
use scroll::Cread;
let bytes = [
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xbe, 0xad, 0xde,
];
let _foo = bytes.cread::<i64>(1_000_000);
}
#[test]
fn cwrite_api() {
use scroll::Cread;
use scroll::Cwrite;
let mut bytes = [0x0; 16];
bytes.cwrite::<u64>(42, 0);
bytes.cwrite::<u32>(0xdeadbeef, 8);
assert_eq!(bytes.cread::<u64>(0), 42);
assert_eq!(bytes.cread::<u32>(8), 0xdeadbeef);
}
impl scroll::ctx::IntoCtx<scroll::Endian> for Bar {
fn into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) {
use scroll::Cwrite;
bytes.cwrite_with(self.foo, 0, ctx);
bytes.cwrite_with(self.bar, 4, ctx);
}
}
#[test]
fn cwrite_api_customtype() {
use scroll::{Cread, Cwrite};
let bar = Bar {
foo: -1,
bar: 0xdeadbeef,
};
let mut bytes = [0x0; 16];
let _ = &bytes[..].cwrite::<Bar>(bar, 0);
let bar = bytes.cread::<Bar>(0);
assert_eq!({ bar.foo }, -1);
assert_eq!({ bar.bar }, 0xdeadbeef);
}

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"9fbb5068c3ffbf2c357f4068f854f439bae4999e04527e2dedc6758fa37a9807","LICENSE":"afb11426e09da40a1ae4f8fa17ddcc6b6a52d14df04c29bc5bcd06eb8730624d","README.md":"f89c7768454b0d2b9db816afe05db3a4cea1125bef87f08ed3eefd65e9e2b180","src/lib.rs":"a9cabe3c0b373f352357745b817f188ab841e9445056014dee9cc83c4d167483"},"package":"1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae"}
{"files":{"Cargo.toml":"57ee02784903ef6f506e87164230e0bf543cf9f9bcd1546e123158c7ab98b648","LICENSE":"afb11426e09da40a1ae4f8fa17ddcc6b6a52d14df04c29bc5bcd06eb8730624d","README.md":"0ed9b8c8ec7dd75f14aab9b7e54769f81b86e68960658356e260e5ec8ccac206","src/lib.rs":"a9cabe3c0b373f352357745b817f188ab841e9445056014dee9cc83c4d167483"},"package":"7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932"}

View File

@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "scroll_derive"
version = "0.11.1"
version = "0.12.0"
authors = [
"m4b <m4b.github.io@gmail.com>",
"Ted Mielczarek <ted@mielczarek.org>",

View File

@ -21,7 +21,7 @@ use scroll::{Pread, Pwrite, Cread, LE};
fn main (){
let bytes = [0xefu8, 0xbe, 0xad, 0xde, 0, 0, 0, 0, 0, 0, 224, 63, 0xad, 0xde, 0xef, 0xbe];
let data: Data = bytes.pread_with(0, LE).unwrap();
println!("data: {:?}", &data);
println!("data: {data:?}");
assert_eq!(data.id, 0xdeadbeefu32);
let mut bytes2 = vec![0; ::std::mem::size_of::<Data>()];
bytes2.pwrite_with(data, 0, LE).unwrap();

View File

@ -0,0 +1 @@
{"files":{"Cargo.toml":"4581638d3c628d22826bde37114048c825ffb354f17f21645d8d49f9ebd64689","LICENSE":"0173035e025d60b1d19197840a93a887f6da8b075c01dd10601fcb6414a0043b","README.md":"c27297df61be8dd14e47dc30a80ae1d443f5acea82932139637543bc6d860631","dprint.json":"aacd5ec32db8741fbdea4ac916e61f0011485a51e8ec7a660f849be60cc7b512","rustfmt.toml":"6819baea67831b8a8b2a7ad33af1128dd2774a900c804635c912bb6545a4e922","src/brute_force.rs":"02edda18441ea5d6cc89d2fdfb9ab32a361e2598de74a71fb930fb630288ce35","src/lib.rs":"b312e4855945cfe27f4b1e9949b1c6ffea8f248ad80ac8fc49e72f0cc38df219","src/monge.rs":"f6c475f4d094b70b5e45d0c8a94112d42eaafa0ab41b2d3d96d06a38f1bac32d","src/recursive.rs":"e585286fe6c885dcac8001d0f484718aa8f73f3f85a452f8b4c1cb36d4fbfcf6","tests/agreement.rs":"764406a5d8c9a322bab8787764d780832cfc3962722ed01efda99684a619d543","tests/complexity.rs":"e2e850d38529f171eb6005807c2a86a3f95a907052253eaa8e24a834200cda0b","tests/monge.rs":"fe418373f89904cd40e2ed1d539bccd2d9be50c1f3f9ab2d93806ff3bce6b7ea","tests/random_monge/mod.rs":"83cf1dd0c7b0b511ad754c19857a5d830ed54e8fef3c31235cd70b709687534b","tests/version-numbers.rs":"73301b7bfe500eada5ede66f0dce89bd3e354af50a8e7a123b02931cd5eb8e16"},"package":"b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"}

53
third_party/rust/smawk/Cargo.toml vendored Normal file
View File

@ -0,0 +1,53 @@
# 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 are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2021"
name = "smawk"
version = "0.3.2"
authors = ["Martin Geisler <martin@geisler.net>"]
exclude = [
".github/",
".gitignore",
"benches/",
"examples/",
]
description = "Functions for finding row-minima in a totally monotone matrix."
readme = "README.md"
keywords = [
"smawk",
"matrix",
"optimization",
"dynamic-programming",
]
categories = [
"algorithms",
"mathematics",
"science",
]
license = "MIT"
repository = "https://github.com/mgeisler/smawk"
[dependencies.ndarray]
version = "0.15.4"
optional = true
[dev-dependencies.num-traits]
version = "0.2.14"
[dev-dependencies.rand]
version = "0.8.4"
[dev-dependencies.rand_chacha]
version = "0.3.1"
[dev-dependencies.version-sync]
version = "0.9.4"

21
third_party/rust/smawk/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Martin Geisler
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.

151
third_party/rust/smawk/README.md vendored Normal file
View File

@ -0,0 +1,151 @@
# SMAWK Algorithm in Rust
[![](https://github.com/mgeisler/smawk/workflows/build/badge.svg)][build-status]
[![](https://codecov.io/gh/mgeisler/smawk/branch/master/graph/badge.svg)][codecov]
[![](https://img.shields.io/crates/v/smawk.svg)][crates-io]
[![](https://docs.rs/smawk/badge.svg)][api-docs]
This crate contains an implementation of the [SMAWK algorithm][smawk] for
finding the smallest element per row in a totally monotone matrix.
The SMAWK algorithm allows you to lower the running time of some algorithms from
O(_n_²) to just O(_n_). In other words, you can turn a quadratic time complexity
(which is often too expensive) into linear time complexity.
Finding optimal line breaks in a paragraph of text is an example of an algorithm
which would normally take O(_n_²) time for _n_ words. With this crate, the
running time becomes linear. Please see the [textwrap crate][textwrap] for an
example of this.
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
smawk = "0.3"
```
You can now efficiently find row and column minima. Here is an example where we
find the column minima:
```rust
use smawk::Matrix;
let matrix = vec![
vec![3, 2, 4, 5, 6],
vec![2, 1, 3, 3, 4],
vec![2, 1, 3, 3, 4],
vec![3, 2, 4, 3, 4],
vec![4, 3, 2, 1, 1],
];
let minima = vec![1, 1, 4, 4, 4];
assert_eq!(smawk::column_minima(&matrix), minima);
```
The `minima` vector gives the index of the minimum value per column, so
`minima[0] == 1` since the minimum value in the first column is 2 (row 1). Note
that the smallest row index is returned.
### Cargo Features
This crate has an optional dependency on the
[`ndarray` crate](https://docs.rs/ndarray/), which provides an efficient matrix
implementation. Enable the `ndarray` Cargo feature to use it.
## Documentation
**[API documentation][api-docs]**
## Changelog
### Version 0.3.2 (2023-09-17)
This release adds more documentation and renames the top-level SMAWK functions.
The old names have been kept for now to ensure backwards compatibility, but they
will be removed in a future release.
- [#65](https://github.com/mgeisler/smawk/pull/65): Forbid the use of unsafe
code.
- [#69](https://github.com/mgeisler/smawk/pull/69): Migrate to the Rust 2021
edition.
- [#73](https://github.com/mgeisler/smawk/pull/73): Add examples to all
functions.
- [#74](https://github.com/mgeisler/smawk/pull/74): Add “mathematics” as a crate
category.
- [#75](https://github.com/mgeisler/smawk/pull/75): Remove `smawk_` prefix from
optimized functions.
### Version 0.3.1 (2021-01-30)
This release relaxes the bounds on the `smawk_row_minima`,
`smawk_column_minima`, and `online_column_minima` functions so that they work on
matrices containing floating point numbers.
- [#55](https://github.com/mgeisler/smawk/pull/55): Relax bounds to `PartialOrd`
instead of `Ord`.
- [#56](https://github.com/mgeisler/smawk/pull/56): Update dependencies to their
latest versions.
- [#59](https://github.com/mgeisler/smawk/pull/59): Give an example of what
SMAWK does in the README.
### Version 0.3.0 (2020-09-02)
This release slims down the crate significantly by making `ndarray` an optional
dependency.
- [#45](https://github.com/mgeisler/smawk/pull/45): Move non-SMAWK code and unit
tests out of lib and into separate modules.
- [#46](https://github.com/mgeisler/smawk/pull/46): Switch `smawk_row_minima`
and `smawk_column_minima` functions to a new `Matrix` trait.
- [#47](https://github.com/mgeisler/smawk/pull/47): Make the dependency on the
`ndarray` crate optional.
- [#48](https://github.com/mgeisler/smawk/pull/48): Let `is_monge` take a
`Matrix` argument instead of `ndarray::Array2`.
- [#50](https://github.com/mgeisler/smawk/pull/50): Remove mandatory
dependencies on `rand` and `num-traits` crates.
### Version 0.2.0 (2020-07-29)
This release updates the code to Rust 2018.
- [#18](https://github.com/mgeisler/smawk/pull/18): Make `online_column_minima`
generic in matrix type.
- [#23](https://github.com/mgeisler/smawk/pull/23): Switch to the
[Rust 2018][rust-2018] edition. We test against the latest stable and nightly
version of Rust.
- [#29](https://github.com/mgeisler/smawk/pull/29): Drop strict Rust 2018
compatibility by not testing with Rust 1.31.0.
- [#32](https://github.com/mgeisler/smawk/pull/32): Fix crash on overflow in
`is_monge`.
- [#33](https://github.com/mgeisler/smawk/pull/33): Update `rand` dependency to
latest version and get rid of `rand_derive`.
- [#34](https://github.com/mgeisler/smawk/pull/34): Bump `num-traits` and
`version-sync` dependencies to latest versions.
- [#35](https://github.com/mgeisler/smawk/pull/35): Drop unnecessary Windows
tests. The assumption is that the numeric computations we do are
cross-platform.
- [#36](https://github.com/mgeisler/smawk/pull/36): Update `ndarray` dependency
to the latest version.
- [#37](https://github.com/mgeisler/smawk/pull/37): Automate publishing new
releases to crates.io.
### Version 0.1.0 — August 7th, 2018
First release with the classical offline SMAWK algorithm as well as a newer
online version where the matrix entries can depend on previously computed column
minima.
## License
SMAWK can be distributed according to the [MIT license][mit]. Contributions will
be accepted under the same license.
[build-status]: https://github.com/mgeisler/smawk/actions?query=branch%3Amaster+workflow%3Abuild
[crates-io]: https://crates.io/crates/smawk
[codecov]: https://codecov.io/gh/mgeisler/smawk
[textwrap]: https://crates.io/crates/textwrap
[smawk]: https://en.wikipedia.org/wiki/SMAWK_algorithm
[api-docs]: https://docs.rs/smawk/
[rust-2018]: https://doc.rust-lang.org/edition-guide/rust-2018/
[mit]: LICENSE

19
third_party/rust/smawk/dprint.json vendored Normal file
View File

@ -0,0 +1,19 @@
{
"markdown": {
"textWrap": "always"
},
"exec": {
"commands": [{
"command": "rustfmt",
"exts": ["rs"]
}]
},
"excludes": ["target/"],
"plugins": [
"https://plugins.dprint.dev/json-0.17.4.wasm",
"https://plugins.dprint.dev/markdown-0.16.1.wasm",
"https://plugins.dprint.dev/toml-0.5.4.wasm",
"https://plugins.dprint.dev/exec-0.4.3.json@42343548b8022c99b1d750be6b894fe6b6c7ee25f72ae9f9082226dd2e515072",
"https://plugins.dprint.dev/prettier-0.27.0.json@3557a62b4507c55a47d8cde0683195b14d13c41dda66d0f0b0e111aed107e2fe"
]
}

2
third_party/rust/smawk/rustfmt.toml vendored Normal file
View File

@ -0,0 +1,2 @@
# Use rustfmt from the nightly channel for this:
imports_granularity = "Module"

Some files were not shown because too many files have changed in this diff Show More