| { | ||
| "git": { | ||
| "sha1": "c9fac4e625ccb2c6a7aa35079fff9709db4385ac" | ||
| "sha1": "a14f2dad852be26bad277ae704abf27a15cbfed1" | ||
| }, | ||
| "path_in_vcs": "utils/zerovec" | ||
| } |
+114
-177
@@ -7,5 +7,5 @@ # This file is automatically @generated by Cargo. | ||
| name = "aho-corasick" | ||
| version = "1.1.4" | ||
| version = "1.1.5" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" | ||
| checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" | ||
| dependencies = [ | ||
@@ -29,5 +29,5 @@ "memchr", | ||
| name = "autocfg" | ||
| version = "1.5.0" | ||
| version = "1.5.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" | ||
| checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" | ||
@@ -45,11 +45,11 @@ [[package]] | ||
| name = "bitflags" | ||
| version = "2.11.0" | ||
| version = "2.13.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" | ||
| checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" | ||
| [[package]] | ||
| name = "bumpalo" | ||
| version = "3.20.2" | ||
| version = "3.20.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" | ||
| checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" | ||
@@ -137,10 +137,9 @@ [[package]] | ||
| name = "console" | ||
| version = "0.15.11" | ||
| version = "0.16.4" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" | ||
| checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" | ||
| dependencies = [ | ||
| "encode_unicode", | ||
| "libc", | ||
| "once_cell", | ||
| "windows-sys 0.59.0", | ||
| "windows-sys", | ||
| ] | ||
@@ -186,5 +185,5 @@ | ||
| name = "crossbeam-deque" | ||
| version = "0.8.6" | ||
| version = "0.8.7" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" | ||
| checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" | ||
| dependencies = [ | ||
@@ -197,5 +196,5 @@ "crossbeam-epoch", | ||
| name = "crossbeam-epoch" | ||
| version = "0.9.18" | ||
| version = "0.9.20" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" | ||
| checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" | ||
| dependencies = [ | ||
@@ -207,5 +206,5 @@ "crossbeam-utils", | ||
| name = "crossbeam-utils" | ||
| version = "0.8.21" | ||
| version = "0.8.22" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" | ||
| checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" | ||
@@ -237,3 +236,3 @@ [[package]] | ||
| "quote", | ||
| "syn", | ||
| "syn 2.0.119", | ||
| "synstructure", | ||
@@ -250,5 +249,5 @@ ] | ||
| name = "either" | ||
| version = "1.15.0" | ||
| version = "1.17.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" | ||
| checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" | ||
@@ -280,3 +279,3 @@ [[package]] | ||
| "libc", | ||
| "windows-sys 0.61.2", | ||
| "windows-sys", | ||
| ] | ||
@@ -286,5 +285,5 @@ | ||
| name = "fastrand" | ||
| version = "2.3.0" | ||
| version = "2.5.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" | ||
| checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" | ||
@@ -329,5 +328,5 @@ [[package]] | ||
| name = "insta" | ||
| version = "1.46.3" | ||
| version = "1.48.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "e82db8c87c7f1ccecb34ce0c24399b8a73081427f3c7c50a5d597925356115e4" | ||
| checksum = "86f0f8fee8c926415c58d6ae43a08523a26faccb2323f5e6b644fe7dd4ef6b82" | ||
| dependencies = [ | ||
@@ -349,3 +348,3 @@ "console", | ||
| "libc", | ||
| "windows-sys 0.61.2", | ||
| "windows-sys", | ||
| ] | ||
@@ -370,5 +369,5 @@ | ||
| name = "js-sys" | ||
| version = "0.3.91" | ||
| version = "0.3.94" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" | ||
| checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" | ||
| dependencies = [ | ||
@@ -381,5 +380,5 @@ "once_cell", | ||
| name = "libc" | ||
| version = "0.2.183" | ||
| version = "0.2.189" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" | ||
| checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" | ||
@@ -400,5 +399,5 @@ [[package]] | ||
| name = "memchr" | ||
| version = "2.8.0" | ||
| version = "2.8.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" | ||
| checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" | ||
@@ -484,5 +483,5 @@ [[package]] | ||
| name = "proc-macro2" | ||
| version = "1.0.106" | ||
| version = "1.0.107" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" | ||
| checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" | ||
| dependencies = [ | ||
@@ -494,5 +493,5 @@ "unicode-ident", | ||
| name = "quote" | ||
| version = "1.0.45" | ||
| version = "1.0.47" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" | ||
| checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" | ||
| dependencies = [ | ||
@@ -510,5 +509,5 @@ "proc-macro2", | ||
| name = "rand" | ||
| version = "0.9.2" | ||
| version = "0.9.5" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" | ||
| checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" | ||
| dependencies = [ | ||
@@ -579,5 +578,5 @@ "rand_chacha", | ||
| name = "ref-cast" | ||
| version = "1.0.25" | ||
| version = "1.0.26" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" | ||
| checksum = "216e8f773d7923bcba9ceb86a86c93cabb3903a11872fc3f138c49630e50b96d" | ||
| dependencies = [ | ||
@@ -589,9 +588,9 @@ "ref-cast-impl", | ||
| name = "ref-cast-impl" | ||
| version = "1.0.25" | ||
| version = "1.0.26" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" | ||
| checksum = "2c9283685feec7d69af75fb0e858d5e7378f33fe4fc699383b2916ab9273e03c" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| "syn 3.0.3", | ||
| ] | ||
@@ -601,5 +600,5 @@ | ||
| name = "regex" | ||
| version = "1.12.3" | ||
| version = "1.13.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" | ||
| checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" | ||
| dependencies = [ | ||
@@ -614,5 +613,5 @@ "aho-corasick", | ||
| name = "regex-automata" | ||
| version = "0.4.14" | ||
| version = "0.4.18" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" | ||
| checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" | ||
| dependencies = [ | ||
@@ -626,5 +625,5 @@ "aho-corasick", | ||
| name = "regex-syntax" | ||
| version = "0.8.10" | ||
| version = "0.8.11" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" | ||
| checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" | ||
@@ -663,3 +662,3 @@ [[package]] | ||
| "linux-raw-sys", | ||
| "windows-sys 0.61.2", | ||
| "windows-sys", | ||
| ] | ||
@@ -669,5 +668,5 @@ | ||
| name = "rustversion" | ||
| version = "1.0.22" | ||
| version = "1.0.23" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" | ||
| checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" | ||
@@ -685,5 +684,5 @@ [[package]] | ||
| name = "schemars" | ||
| version = "1.2.1" | ||
| version = "1.2.2" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" | ||
| checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" | ||
| dependencies = [ | ||
@@ -698,5 +697,5 @@ "dyn-clone", | ||
| name = "serde" | ||
| version = "1.0.228" | ||
| version = "1.0.229" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" | ||
| checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" | ||
| dependencies = [ | ||
@@ -709,5 +708,5 @@ "serde_core", | ||
| name = "serde_core" | ||
| version = "1.0.228" | ||
| version = "1.0.229" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" | ||
| checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" | ||
| dependencies = [ | ||
@@ -719,9 +718,9 @@ "serde_derive", | ||
| name = "serde_derive" | ||
| version = "1.0.228" | ||
| version = "1.0.229" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" | ||
| checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| "syn 3.0.3", | ||
| ] | ||
@@ -731,5 +730,5 @@ | ||
| name = "serde_json" | ||
| version = "1.0.149" | ||
| version = "1.0.151" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" | ||
| checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" | ||
| dependencies = [ | ||
@@ -757,5 +756,5 @@ "itoa", | ||
| name = "syn" | ||
| version = "2.0.117" | ||
| version = "2.0.119" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" | ||
| checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" | ||
| dependencies = [ | ||
@@ -768,2 +767,13 @@ "proc-macro2", | ||
| [[package]] | ||
| name = "syn" | ||
| version = "3.0.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "unicode-ident", | ||
| ] | ||
| [[package]] | ||
| name = "synstructure" | ||
@@ -776,3 +786,3 @@ version = "0.13.2" | ||
| "quote", | ||
| "syn", | ||
| "syn 2.0.119", | ||
| ] | ||
@@ -790,3 +800,3 @@ | ||
| "rustix", | ||
| "windows-sys 0.61.2", | ||
| "windows-sys", | ||
| ] | ||
@@ -796,5 +806,5 @@ | ||
| name = "thiserror" | ||
| version = "2.0.18" | ||
| version = "2.0.20" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" | ||
| checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" | ||
| dependencies = [ | ||
@@ -806,9 +816,9 @@ "thiserror-impl", | ||
| name = "thiserror-impl" | ||
| version = "2.0.18" | ||
| version = "2.0.20" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" | ||
| checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| "syn 3.0.3", | ||
| ] | ||
@@ -828,5 +838,5 @@ | ||
| name = "twox-hash" | ||
| version = "2.1.2" | ||
| version = "2.1.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" | ||
| checksum = "8464ec13c3691491391d9fce00f6416c9a48e46972f72d7865688be2080192c9" | ||
@@ -860,5 +870,5 @@ [[package]] | ||
| name = "wasm-bindgen" | ||
| version = "0.2.114" | ||
| version = "0.2.117" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" | ||
| checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" | ||
| dependencies = [ | ||
@@ -874,5 +884,5 @@ "cfg-if", | ||
| name = "wasm-bindgen-macro" | ||
| version = "0.2.114" | ||
| version = "0.2.117" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" | ||
| checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" | ||
| dependencies = [ | ||
@@ -885,5 +895,5 @@ "quote", | ||
| name = "wasm-bindgen-macro-support" | ||
| version = "0.2.114" | ||
| version = "0.2.117" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" | ||
| checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" | ||
| dependencies = [ | ||
@@ -893,3 +903,3 @@ "bumpalo", | ||
| "quote", | ||
| "syn", | ||
| "syn 2.0.119", | ||
| "wasm-bindgen-shared", | ||
@@ -900,5 +910,5 @@ ] | ||
| name = "wasm-bindgen-shared" | ||
| version = "0.2.114" | ||
| version = "0.2.117" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" | ||
| checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" | ||
| dependencies = [ | ||
@@ -910,5 +920,5 @@ "unicode-ident", | ||
| name = "web-sys" | ||
| version = "0.3.91" | ||
| version = "0.3.94" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" | ||
| checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" | ||
| dependencies = [ | ||
@@ -925,3 +935,3 @@ "js-sys", | ||
| dependencies = [ | ||
| "windows-sys 0.61.2", | ||
| "windows-sys", | ||
| ] | ||
@@ -937,11 +947,2 @@ | ||
| name = "windows-sys" | ||
| version = "0.59.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" | ||
| dependencies = [ | ||
| "windows-targets", | ||
| ] | ||
| [[package]] | ||
| name = "windows-sys" | ||
| version = "0.61.2" | ||
@@ -955,66 +956,2 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| [[package]] | ||
| name = "windows-targets" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" | ||
| dependencies = [ | ||
| "windows_aarch64_gnullvm", | ||
| "windows_aarch64_msvc", | ||
| "windows_i686_gnu", | ||
| "windows_i686_gnullvm", | ||
| "windows_i686_msvc", | ||
| "windows_x86_64_gnu", | ||
| "windows_x86_64_gnullvm", | ||
| "windows_x86_64_msvc", | ||
| ] | ||
| [[package]] | ||
| name = "windows_aarch64_gnullvm" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" | ||
| [[package]] | ||
| name = "windows_aarch64_msvc" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" | ||
| [[package]] | ||
| name = "windows_i686_gnu" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" | ||
| [[package]] | ||
| name = "windows_i686_gnullvm" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" | ||
| [[package]] | ||
| name = "windows_i686_msvc" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" | ||
| [[package]] | ||
| name = "windows_x86_64_gnu" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" | ||
| [[package]] | ||
| name = "windows_x86_64_gnullvm" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" | ||
| [[package]] | ||
| name = "windows_x86_64_msvc" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" | ||
| [[package]] | ||
| name = "wit-bindgen" | ||
@@ -1027,5 +964,5 @@ version = "0.46.0" | ||
| name = "yoke" | ||
| version = "0.8.2" | ||
| version = "0.8.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" | ||
| checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" | ||
| dependencies = [ | ||
@@ -1045,3 +982,3 @@ "stable_deref_trait", | ||
| "quote", | ||
| "syn", | ||
| "syn 2.0.119", | ||
| "synstructure", | ||
@@ -1052,5 +989,5 @@ ] | ||
| name = "zerocopy" | ||
| version = "0.8.47" | ||
| version = "0.8.56" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" | ||
| checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" | ||
| dependencies = [ | ||
@@ -1062,9 +999,9 @@ "zerocopy-derive", | ||
| name = "zerocopy-derive" | ||
| version = "0.8.47" | ||
| version = "0.8.56" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" | ||
| checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| "syn 2.0.119", | ||
| ] | ||
@@ -1074,5 +1011,5 @@ | ||
| name = "zerofrom" | ||
| version = "0.1.7" | ||
| version = "0.1.8" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" | ||
| checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" | ||
| dependencies = [ | ||
@@ -1090,3 +1027,3 @@ "zerofrom-derive", | ||
| "quote", | ||
| "syn", | ||
| "syn 2.0.119", | ||
| "synstructure", | ||
@@ -1097,3 +1034,3 @@ ] | ||
| name = "zerovec" | ||
| version = "0.11.6" | ||
| version = "0.11.7" | ||
| dependencies = [ | ||
@@ -1122,9 +1059,9 @@ "bincode", | ||
| name = "zerovec-derive" | ||
| version = "0.11.3" | ||
| version = "0.11.4" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" | ||
| checksum = "47402523226a02bfe5230160dc3ccc089aa6f6f19e7fcbb4e6f824bbb1b4aa62" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| "syn 3.0.3", | ||
| ] | ||
@@ -1134,4 +1071,4 @@ | ||
| name = "zmij" | ||
| version = "1.0.21" | ||
| version = "1.0.23" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" | ||
| checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" |
+10
-8
@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| name = "zerovec" | ||
| version = "0.11.6" | ||
| version = "0.11.7" | ||
| authors = ["The ICU4X Project Developers"] | ||
@@ -144,3 +144,3 @@ build = false | ||
| [dependencies.yoke] | ||
| version = "0.8.2" | ||
| version = "0.8.3" | ||
| optional = true | ||
@@ -154,3 +154,3 @@ default-features = false | ||
| [dependencies.zerovec-derive] | ||
| version = "0.11.3" | ||
| version = "0.11.4" | ||
| optional = true | ||
@@ -199,3 +199,3 @@ default-features = false | ||
| [dev-dependencies.yoke] | ||
| version = "0.8.2" | ||
| version = "0.8.3" | ||
| features = ["derive"] | ||
@@ -208,4 +208,5 @@ default-features = false | ||
| [lints.clippy] | ||
| alloc-instead-of-core = "warn" | ||
| branches-sharing-code = "warn" | ||
| alloc_instead_of_core = "warn" | ||
| bool_assert_comparison = "allow" | ||
| branches_sharing_code = "warn" | ||
| collection_is_never_read = "warn" | ||
@@ -225,3 +226,3 @@ crosspointer_transmute = "warn" | ||
| negative_feature_names = "warn" | ||
| or-fun-call = "warn" | ||
| or_fun_call = "warn" | ||
| same_functions_in_if_condition = "warn" | ||
@@ -237,3 +238,3 @@ todo = "warn" | ||
| trivially_copy_pass_by_ref = "deny" | ||
| unnecessary-wraps = "warn" | ||
| unnecessary_wraps = "warn" | ||
| useless_transmute = "warn" | ||
@@ -255,4 +256,5 @@ wildcard_dependencies = "warn" | ||
| "cfg(needs_alloc_error_handler)", | ||
| "cfg(icu4x_nightly_tests)", | ||
| "cfg(icu4x_run_size_tests)", | ||
| "cfg(icu4x_unstable_fast_trie_only)", | ||
| ] |
+12
-2
@@ -194,4 +194,14 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| pub fn new_owned(val: Box<V>) -> Self { | ||
| let val = ManuallyDrop::new(val); | ||
| let buf: NonNull<[u8]> = val.as_bytes().into(); | ||
| let raw_box: *mut V = Box::into_raw(val); | ||
| // SAFETY: raw_box is a valid pointer to V as it comes from Box::into_raw. | ||
| let raw_ref: &V = unsafe { &*raw_box }; | ||
| let slice_ref: &[u8] = raw_ref.as_bytes(); | ||
| // SAFETY: We construct the NonNull pointer directly from raw_box (which has unique owning | ||
| // provenance) cast to u8, using the length from slice_ref. This avoids losing unique provenance. | ||
| let buf = unsafe { | ||
| NonNull::new_unchecked(core::ptr::slice_from_raw_parts_mut( | ||
| raw_box.cast::<u8>(), | ||
| slice_ref.len(), | ||
| )) | ||
| }; | ||
| let raw = RawVarZeroCow { | ||
@@ -198,0 +208,0 @@ // Invariants upheld: |
@@ -65,3 +65,12 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| /// * `key_hashes` - [`ExactSizeIterator`] over the hashed key values | ||
| #[expect(clippy::indexing_slicing, clippy::unwrap_used)] | ||
| /// | ||
| /// # Panics | ||
| /// | ||
| /// Panics if the `key_hashes` iterator claims to have more elements than can fit in a u32. | ||
| #[expect( | ||
| clippy::indexing_slicing, | ||
| clippy::unwrap_used, | ||
| clippy::expect_used, | ||
| reason = "Documented panic" | ||
| )] | ||
| pub fn compute_displacements( | ||
@@ -71,2 +80,3 @@ key_hashes: impl ExactSizeIterator<Item = u64>, | ||
| let len = key_hashes.len(); | ||
| let len_u32 = u32::try_from(len).expect("Hashmap too large for u32"); | ||
@@ -127,4 +137,4 @@ // A vector to track the size of buckets for sorting. | ||
| 'd0: for d0 in 0..len as u32 { | ||
| 'd1: for d1 in 0..len as u32 { | ||
| 'd0: for d0 in 0..len_u32 { | ||
| 'd1: for d1 in 0..len_u32 { | ||
| if (d0, d1) == (0, 0) { | ||
@@ -137,3 +147,3 @@ continue; | ||
| for ((_, f0, f1), _) in buckets { | ||
| let displacement_idx = compute_index((*f0, *f1), (d0, d1), len as u32).unwrap(); | ||
| let displacement_idx = compute_index((*f0, *f1), (d0, d1), len_u32).unwrap(); | ||
@@ -140,0 +150,0 @@ // displacement_idx is always within bounds |
+20
-0
@@ -239,2 +239,22 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| } | ||
| #[test] | ||
| #[should_panic(expected = "Hashmap too large for u32")] | ||
| #[cfg(target_pointer_width = "64")] | ||
| fn test_hashmap_too_large() { | ||
| struct HugeIter; | ||
| impl Iterator for HugeIter { | ||
| type Item = u64; | ||
| fn next(&mut self) -> Option<Self::Item> { | ||
| None | ||
| } | ||
| } | ||
| impl ExactSizeIterator for HugeIter { | ||
| fn len(&self) -> usize { | ||
| // Return something that is > u32::MAX on 64-bit systems | ||
| (u32::MAX as usize) + 1 | ||
| } | ||
| } | ||
| let _ = compute_displacements(HugeIter); | ||
| } | ||
| } |
+19
-0
@@ -575,2 +575,21 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| } | ||
| #[test] | ||
| fn test_miri_repro_eyepatch_hack_truncate() { | ||
| let slice: &[u16] = &[1, 2, 3, 4]; | ||
| let zv: ZeroVec<u16> = ZeroVec::try_from_slice(slice).unwrap(); | ||
| let _truncated = zv.truncated(2); | ||
| } | ||
| #[test] | ||
| fn test_miri_repro_encode_varule_to_box() { | ||
| let str_slice: &str = "hello world"; | ||
| let _boxed: Box<str> = ule::encode_varule_to_box(str_slice); | ||
| } | ||
| #[test] | ||
| fn test_miri_repro_varzerocow_new_owned() { | ||
| let boxed_str: Box<str> = Box::from("hello world"); | ||
| let _cow: VarZeroCow<str> = VarZeroCow::new_owned(boxed_str); | ||
| } | ||
| } |
@@ -98,11 +98,6 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| x.encode_var_ule_write(&mut vec); | ||
| let boxed = core::mem::ManuallyDrop::new(vec.into_boxed_slice()); | ||
| unsafe { | ||
| // Safety: `ptr` is a box, and `T` is a VarULE which guarantees it has the same memory layout as `[u8]` | ||
| // and can be recouped via from_bytes_unchecked() | ||
| let ptr: *mut T = T::from_bytes_unchecked(&boxed) as *const T as *mut T; | ||
| // Safety: we can construct an owned version since we have mem::forgotten the older owner | ||
| Box::from_raw(ptr) | ||
| } | ||
| // SAFETY: | ||
| // - T::from_bytes_unchecked is safe because the bytes were written by x.encode_var_ule_write | ||
| // which guarantees a valid representation of T. | ||
| unsafe { cast_box(vec.into_boxed_slice()) } | ||
| } | ||
@@ -109,0 +104,0 @@ |
+51
-10
@@ -365,12 +365,6 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| use alloc::borrow::ToOwned; | ||
| use core::alloc::Layout; | ||
| let bytesvec = self.as_bytes().to_owned().into_boxed_slice(); | ||
| let bytesvec = core::mem::ManuallyDrop::new(bytesvec); | ||
| unsafe { | ||
| // Get the pointer representation | ||
| let ptr: *mut Self = Self::from_bytes_unchecked(&bytesvec) as *const Self as *mut Self; | ||
| assert_eq!(Layout::for_value(&*ptr), Layout::for_value(&**bytesvec)); | ||
| // Transmute the pointer to an owned pointer | ||
| Box::from_raw(ptr) | ||
| } | ||
| let bytes = self.as_bytes().to_owned().into_boxed_slice(); | ||
| // SAFETY: | ||
| // - Self::from_bytes_unchecked is safe because the bytes came from self.as_bytes() which is valid. | ||
| unsafe { cast_box(bytes) } | ||
| } | ||
@@ -454,1 +448,48 @@ } | ||
| impl core::error::Error for UleError {} | ||
| #[cfg(feature = "alloc")] | ||
| /// Reconstructs a `Box<T>` from a `Box<[u8]>` while preserving unique pointer provenance | ||
| /// and correctly resolving DST metadata. | ||
| /// | ||
| /// This is an internal helper used to safely convert a heap-allocated byte buffer | ||
| /// into an owned `Box<T>` where `T` is an unsized `VarULE` type. | ||
| /// | ||
| /// ### Why this is needed | ||
| /// | ||
| /// Reconstructing a `Box<T>` is tricky because: | ||
| /// 1. **Provenance**: If we derive the pointer from a temporary shared reference (e.g., `&[u8]`), | ||
| /// Miri/Stacked Borrows will tag the pointer as `SharedReadOnly`. Reclaiming unique ownership | ||
| /// and deallocating through a pointer with shared provenance is Undefined Behavior. To avoid this, | ||
| /// we must derive the final pointer directly from `Box::into_raw` (which carries `Unique` provenance). | ||
| /// 2. **DST Metadata**: Unsized types (like `VarTupleULE`) may have custom metadata that is *not* | ||
| /// simply the byte length of the allocation. We must use `T::from_bytes_unchecked` to construct | ||
| /// a reference with the correct metadata, and then combine that metadata with the unique thin | ||
| /// pointer from `Box::into_raw` without clobbering the provenance. | ||
| /// | ||
| /// ### Safety | ||
| /// | ||
| /// - `T::from_bytes_unchecked` must be safe to call on the slice behind bytes | ||
| pub(crate) unsafe fn cast_box<T: VarULE + ?Sized>(bytes: Box<[u8]>) -> Box<T> { | ||
| use core::alloc::Layout; | ||
| let raw = Box::into_raw(bytes); | ||
| // SAFETY: we just produced `raw`; it is valid | ||
| let slice: &[u8] = unsafe { &*raw }; | ||
| // SAFETY: caller guarantees `from_bytes_unchecked` is safe. | ||
| let ref_t: &T = unsafe { T::from_bytes_unchecked(slice) }; | ||
| // Extract metadata from ref_t. | ||
| debug_assert_eq!(size_of::<&T>(), size_of::<(*const u8, usize)>()); | ||
| let (_, metadata) = unsafe { core::mem::transmute_copy::<&T, (*const u8, usize)>(&ref_t) }; | ||
| // Construct *mut T from (raw_data_ptr, metadata). | ||
| debug_assert_eq!(size_of::<*mut T>(), size_of::<(*mut u8, usize)>()); | ||
| let ptr: *mut T = unsafe { | ||
| core::mem::transmute_copy::<(*mut u8, usize), *mut T>(&(raw.cast::<u8>(), metadata)) | ||
| }; | ||
| let expected_layout = Layout::for_value(slice); | ||
| // SAFETY: ptr was reconstructed with the correct metadata and the unique pointer from Box::into_raw. | ||
| let boxed = unsafe { Box::from_raw(ptr) }; | ||
| assert_eq!(Layout::for_value(&*boxed), expected_layout); | ||
| boxed | ||
| } |
+18
-0
@@ -200,2 +200,6 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self { | ||
| debug_assert!( | ||
| !bytes.is_empty(), | ||
| "Bytes must be nonempty by OptionVarULE validation invariants" | ||
| ); | ||
| let entire_struct_as_slice: *const [u8] = | ||
@@ -266,1 +270,15 @@ ::core::ptr::slice_from_raw_parts(bytes.as_ptr(), bytes.len() - 1); | ||
| } | ||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
| #[test] | ||
| #[cfg(debug_assertions)] | ||
| #[should_panic] | ||
| fn test_option_varule_underflow() { | ||
| unsafe { | ||
| let _ = OptionVarULE::<str>::from_bytes_unchecked(&[]); | ||
| } | ||
| } | ||
| } |
@@ -282,7 +282,15 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| // so we use len_minus_one | ||
| // | ||
| // We do the math in u32 space so that we can be sure that VZVs constructed | ||
| // on 64 bit computers can still be used on 32 bit ones. | ||
| let indices_len = u32::try_from(F::Index::SIZE) | ||
| .ok() | ||
| .and_then(|x| x.checked_mul(len_minus_one)) | ||
| .and_then(|x| usize::try_from(x).ok()) | ||
| .ok_or(VarZeroVecFormatError::Metadata)?; | ||
| let indices_bytes = slice | ||
| .get(..F::Index::SIZE * (len_minus_one as usize)) | ||
| .get(..indices_len) | ||
| .ok_or(VarZeroVecFormatError::Metadata)?; | ||
| let things = slice | ||
| .get(F::Index::SIZE * (len_minus_one as usize)..) | ||
| .get(indices_len..) | ||
| .ok_or(VarZeroVecFormatError::Metadata)?; | ||
@@ -326,2 +334,3 @@ | ||
| let len_u32 = len as u32; | ||
| debug_assert_eq!(len, len_u32 as usize); | ||
@@ -356,4 +365,6 @@ // Safety: This method requires the bytes to have passed through `parse_bytes()` | ||
| // so we use len_minus_one | ||
| let indices_bytes = slice.get_unchecked(..F::Index::SIZE * (len_minus_one as usize)); | ||
| let things = slice.get_unchecked(F::Index::SIZE * (len_minus_one as usize)..); | ||
| let indices_len = F::Index::SIZE.wrapping_mul(len_minus_one as usize); | ||
| debug_assert!(F::Index::SIZE.checked_mul(len_minus_one as usize).is_some()); | ||
| let indices_bytes = slice.get_unchecked(..indices_len); | ||
| let things = slice.get_unchecked(indices_len..); | ||
@@ -735,3 +746,10 @@ VarZeroVecComponents { | ||
| // first_dat_offset = offset from the start of the buffer of the first data block | ||
| let first_dat_offset: usize = idx_offset + (elements.len() - 1) * F::Index::SIZE; | ||
| #[expect( | ||
| clippy::expect_used, | ||
| reason = "Function contract allows panicky behavior" | ||
| )] | ||
| let indices_size = F::Index::SIZE | ||
| .checked_mul(elements.len() - 1) | ||
| .expect(F::Index::TOO_LARGE_ERROR); | ||
| let first_dat_offset: usize = idx_offset + indices_size; | ||
| // dat_offset = offset from the start of the buffer of the next data block | ||
@@ -759,3 +777,6 @@ let mut dat_offset: usize = first_dat_offset; | ||
| let dat_limit = dat_offset + element_len; | ||
| #[expect(clippy::indexing_slicing)] // Function contract allows panicky behavior | ||
| #[expect( | ||
| clippy::indexing_slicing, | ||
| reason = "Function contract allows panicky behavior" | ||
| )] | ||
| let dat_slice = &mut output[dat_offset..dat_limit]; | ||
@@ -767,3 +788,10 @@ element.encode_var_ule_write(dat_slice); | ||
| debug_assert_eq!(idx_offset, F::Index::SIZE * (elements.len() - 1)); | ||
| #[expect( | ||
| clippy::expect_used, | ||
| reason = "Function contract allows panicky behavior" | ||
| )] | ||
| let indices_size = F::Index::SIZE | ||
| .checked_mul(elements.len() - 1) | ||
| .expect(F::Index::TOO_LARGE_ERROR); | ||
| debug_assert_eq!(idx_offset, indices_size); | ||
| assert_eq!(dat_offset, output.len()); | ||
@@ -770,0 +798,0 @@ } |
+37
-12
@@ -137,4 +137,10 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| let len = self.len(); | ||
| if len == 0 { | ||
| return 0; | ||
| } | ||
| let out = if idx == len { | ||
| self.entire_slice.len() - F::Len::SIZE - (F::Index::SIZE * (len - 1)) | ||
| let indices_size = F::Index::SIZE | ||
| .checked_mul(len - 1) | ||
| .expect(F::Index::TOO_LARGE_ERROR); | ||
| self.entire_slice.len() - F::Len::SIZE - indices_size | ||
| } else if let Some(idx) = self.index_data(idx) { | ||
@@ -145,3 +151,6 @@ idx.iule_to_usize() | ||
| }; | ||
| debug_assert!(out + F::Len::SIZE + (len - 1) * F::Index::SIZE <= self.entire_slice.len()); | ||
| let indices_size = F::Index::SIZE | ||
| .checked_mul(len - 1) | ||
| .expect(F::Index::TOO_LARGE_ERROR); | ||
| debug_assert!(out + F::Len::SIZE + indices_size <= self.entire_slice.len()); | ||
| out | ||
@@ -178,3 +187,6 @@ } | ||
| let index_minus_one = index.checked_sub(1)?; | ||
| let pos = F::Len::SIZE + F::Index::SIZE * index_minus_one; | ||
| let pos = F::Len::SIZE | ||
| + F::Index::SIZE | ||
| .checked_mul(index_minus_one) | ||
| .expect(F::Index::TOO_LARGE_ERROR); | ||
| Some(pos..pos + F::Index::SIZE) | ||
@@ -221,4 +233,7 @@ } | ||
| let len = self.len(); | ||
| let indices_size = F::Index::SIZE | ||
| .checked_mul(len - 1) | ||
| .expect(F::Index::TOO_LARGE_ERROR); | ||
| let indices = F::Index::iule_from_bytes_unchecked_mut( | ||
| &mut self.entire_slice[F::Len::SIZE..F::Len::SIZE + F::Index::SIZE * (len - 1)], | ||
| &mut self.entire_slice[F::Len::SIZE..F::Len::SIZE + indices_size], | ||
| ); | ||
@@ -315,3 +330,6 @@ for idx in &mut indices[normalized_idx..] { | ||
| let old_slice_end = slice_range.start.add(slice_len); | ||
| let data_start = indices_start.add((len - 1) * F::Index::SIZE); | ||
| let indices_size = F::Index::SIZE | ||
| .checked_mul(len - 1) | ||
| .expect(F::Index::TOO_LARGE_ERROR); | ||
| let data_start = indices_start.add(indices_size); | ||
| let prev_element_p = | ||
@@ -326,3 +344,6 @@ data_start.add(prev_element.start)..data_start.add(prev_element.end); | ||
| let index_range = if let Some(index_minus_one) = index.checked_sub(1) { | ||
| let index_start = indices_start.add(F::Index::SIZE * index_minus_one); | ||
| let index_offset = F::Index::SIZE | ||
| .checked_mul(index_minus_one) | ||
| .expect(F::Index::TOO_LARGE_ERROR); | ||
| let index_start = indices_start.add(index_offset); | ||
| Some(index_start..index_start.add(F::Index::SIZE)) | ||
@@ -409,5 +430,6 @@ } else { | ||
| // Return a mut slice to the new element data. | ||
| let element_pos = F::Len::SIZE | ||
| + (self.len() - 1) * F::Index::SIZE | ||
| + self.element_position_unchecked(index); | ||
| let indices_size = F::Index::SIZE | ||
| .checked_mul(self.len() - 1) | ||
| .expect(F::Index::TOO_LARGE_ERROR); | ||
| let element_pos = F::Len::SIZE + indices_size + self.element_position_unchecked(index); | ||
| &mut self.entire_slice[element_pos..element_pos + new_size] | ||
@@ -439,6 +461,9 @@ } | ||
| } | ||
| if self.entire_slice.len() < F::Len::SIZE + (len - 1) * F::Index::SIZE { | ||
| let indices_size = F::Index::SIZE | ||
| .checked_mul(len - 1) | ||
| .expect(F::Index::TOO_LARGE_ERROR); | ||
| if self.entire_slice.len() < F::Len::SIZE + indices_size { | ||
| panic!("VarZeroVecOwned integrity: Not enough room for the indices"); | ||
| } | ||
| let data_len = self.entire_slice.len() - F::Len::SIZE - (len - 1) * F::Index::SIZE; | ||
| let data_len = self.entire_slice.len() - F::Len::SIZE - indices_size; | ||
| if data_len > F::Index::MAX_VALUE as usize { | ||
@@ -451,3 +476,3 @@ panic!("VarZeroVecOwned integrity: Data segment is too long"); | ||
| F::Index::slice_from_bytes_unchecked( | ||
| &self.entire_slice[F::Len::SIZE..F::Len::SIZE + (len - 1) * F::Index::SIZE], | ||
| &self.entire_slice[F::Len::SIZE..F::Len::SIZE + indices_size], | ||
| ) | ||
@@ -454,0 +479,0 @@ }; |
@@ -520,1 +520,22 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| } | ||
| #[test] | ||
| fn test_overflow_parse_bytes_with_length() { | ||
| use super::components::{Index32, VarZeroVecComponents}; | ||
| // Tests that you can't try to construct a VZV that is too big to store its length | ||
| // as a u32. | ||
| // We want to distinguish between "failed because of slice bounds" and "failed because of u32 overflow". | ||
| // On 64-bit, 4 * 0x4000_0000 = 4GB. | ||
| // If we had the u32 check, it would return Metadata error regardless of slice size. | ||
| // If we didn't, it would only return Metadata error if slice size < 4GB. | ||
| // We don't use a fully valid VZV here because we just want to ensure the first few lines of code | ||
| // return the metadata error without panicking. Actually allocating and instantiating | ||
| // a 4GB VZV candidate is very slow. | ||
| let mut bytes = vec![0u8; 4]; | ||
| bytes.copy_from_slice(&0x4000_0001u32.to_le_bytes()); | ||
| let result = VarZeroVecComponents::<str, Index32>::parse_bytes(&bytes); | ||
| assert!(matches!(result, Err(VarZeroVecFormatError::Metadata))); | ||
| } |
+27
-8
@@ -170,2 +170,5 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| fn truncate(&mut self, max: usize) { | ||
| // We must take care not to materialize an `&mut` here, otherwise we will | ||
| // have overlapping references | ||
| let buf_ptr: *mut [U] = self.buf.as_ptr(); | ||
| // SAFETY: | ||
@@ -179,3 +182,4 @@ // - The elements in buf are `ULE`, so they don't need to be dropped even if we own them. | ||
| NonNull::new_unchecked(core::ptr::slice_from_raw_parts_mut( | ||
| self.buf.as_mut().as_mut_ptr(), | ||
| // Remove the DST | ||
| buf_ptr.cast::<U>(), | ||
| core::cmp::min(max, self.buf.as_ref().len()), | ||
@@ -246,11 +250,20 @@ )) | ||
| where | ||
| T: AsULE + PartialEq, | ||
| T: AsULE, | ||
| { | ||
| #[inline] | ||
| fn eq(&self, other: &ZeroVec<'b, T>) -> bool { | ||
| // Note: T implements PartialEq but not T::ULE | ||
| self.iter().eq(other.iter()) | ||
| self.as_slice().eq(other) | ||
| } | ||
| } | ||
| impl<T> PartialEq<[T]> for ZeroVec<'_, T> | ||
| where | ||
| T: AsULE + PartialEq, | ||
| { | ||
| #[inline] | ||
| fn eq(&self, other: &[T]) -> bool { | ||
| self.as_slice().eq(other) | ||
| } | ||
| } | ||
| impl<T> PartialEq<&[T]> for ZeroVec<'_, T> | ||
@@ -262,3 +275,3 @@ where | ||
| fn eq(&self, other: &&[T]) -> bool { | ||
| self.iter().eq(other.iter().copied()) | ||
| self.as_slice().eq(other) | ||
| } | ||
@@ -273,3 +286,3 @@ } | ||
| fn eq(&self, other: &[T; N]) -> bool { | ||
| self.iter().eq(other.iter().copied()) | ||
| self.as_slice().eq(other) | ||
| } | ||
@@ -287,3 +300,3 @@ } | ||
| fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | ||
| self.iter().partial_cmp(other.iter()) | ||
| self.as_slice().partial_cmp(other) | ||
| } | ||
@@ -294,6 +307,12 @@ } | ||
| fn cmp(&self, other: &Self) -> Ordering { | ||
| self.iter().cmp(other.iter()) | ||
| self.as_slice().cmp(other) | ||
| } | ||
| } | ||
| impl<'a, T: AsULE> core::hash::Hash for ZeroVec<'a, T> { | ||
| fn hash<H: core::hash::Hasher>(&self, state: &mut H) { | ||
| self.as_slice().hash(state); | ||
| } | ||
| } | ||
| impl<'a, T: AsULE> AsRef<[T::ULE]> for ZeroVec<'a, T> { | ||
@@ -300,0 +319,0 @@ fn as_ref(&self) -> &[T::ULE] { |
+34
-6
@@ -519,7 +519,8 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| where | ||
| T: AsULE + PartialEq, | ||
| T: AsULE, | ||
| { | ||
| #[inline] | ||
| fn eq(&self, other: &ZeroSlice<T>) -> bool { | ||
| self.as_zerovec().eq(&other.as_zerovec()) | ||
| // All Zero-to-Zero PartialEq impls call this one | ||
| self.as_bytes().eq(other.as_bytes()) | ||
| } | ||
@@ -534,2 +535,3 @@ } | ||
| fn eq(&self, other: &[T]) -> bool { | ||
| // All Slice-to-Zero PartialEq impls call this one | ||
| self.iter().eq(other.iter().copied()) | ||
@@ -539,3 +541,3 @@ } | ||
| impl<'a, T> PartialEq<ZeroVec<'a, T>> for ZeroSlice<T> | ||
| impl<T> PartialEq<&[T]> for ZeroSlice<T> | ||
| where | ||
@@ -545,4 +547,24 @@ T: AsULE + PartialEq, | ||
| #[inline] | ||
| fn eq(&self, other: &&[T]) -> bool { | ||
| ZeroSlice::eq(self, *other) | ||
| } | ||
| } | ||
| impl<T, const N: usize> PartialEq<[T; N]> for ZeroSlice<T> | ||
| where | ||
| T: AsULE + PartialEq, | ||
| { | ||
| #[inline] | ||
| fn eq(&self, other: &[T; N]) -> bool { | ||
| ZeroSlice::eq(self, &other[..]) | ||
| } | ||
| } | ||
| impl<'a, T> PartialEq<ZeroVec<'a, T>> for ZeroSlice<T> | ||
| where | ||
| T: AsULE, | ||
| { | ||
| #[inline] | ||
| fn eq(&self, other: &ZeroVec<'a, T>) -> bool { | ||
| self.as_zerovec().eq(other) | ||
| ZeroSlice::eq(self, other.as_slice()) | ||
| } | ||
@@ -553,7 +575,7 @@ } | ||
| where | ||
| T: AsULE + PartialEq, | ||
| T: AsULE, | ||
| { | ||
| #[inline] | ||
| fn eq(&self, other: &ZeroSlice<T>) -> bool { | ||
| self.eq(&other.as_zerovec()) | ||
| ZeroSlice::eq(self.as_slice(), other) | ||
| } | ||
@@ -583,2 +605,8 @@ } | ||
| impl<T: AsULE> core::hash::Hash for ZeroSlice<T> { | ||
| fn hash<H: core::hash::Hasher>(&self, state: &mut H) { | ||
| state.write(self.as_bytes()); | ||
| } | ||
| } | ||
| #[cfg(feature = "alloc")] | ||
@@ -585,0 +613,0 @@ impl<T: AsULE> AsRef<ZeroSlice<T>> for Vec<T::ULE> { |
Sorry, the diff of this file is not supported yet