зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
2bb9af8156
Коммит
b9d37221b3
|
@ -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"]
|
||||
|
|
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}
|
|
@ -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"]
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -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
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
//! A simple histogram implementation for exponential histograms.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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).**
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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())),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"}
|
|
@ -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"
|
||||
|
|
|
@ -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(),
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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"}
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) |
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.")))
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 section’s 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 image’s 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,
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"}
|
|
@ -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
|
||||
|
|
|
@ -601,7 +601,7 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
|||
|
||||
[[package]]
|
||||
name = "oneshot-uniffi"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"criterion",
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
|
@ -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}
|
|
@ -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"]
|
||||
|
|
|
@ -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}
|
|
@ -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"]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"}
|
|
@ -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
|
|
@ -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"
|
|
@ -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 = []
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -43,9 +43,6 @@ impl Endian {
|
|||
}
|
||||
#[inline]
|
||||
pub fn is_little(&self) -> bool {
|
||||
match *self {
|
||||
LE => true,
|
||||
_ => false,
|
||||
}
|
||||
*self == LE
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)| {
|
||||
|
|
|
@ -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..];
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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"}
|
|
@ -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>",
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"}
|
|
@ -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"
|
|
@ -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.
|
|
@ -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
|
|
@ -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"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
# Use rustfmt from the nightly channel for this:
|
||||
imports_granularity = "Module"
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче