mirror of https://github.com/boa-dev/boa.git
Browse Source
This Pull Request offers a fuzzer which is capable of detecting faults in the parser and interner. It does so by ensuring that the parsed AST remains the same between a parsed source and the result of parsing the `to_interned_string` result of the first parsed source. It changes the following: - Adds a fuzzer for the parser and interner. Any issues I raise in association with this fuzzer will link back to this fuzzer. You may run the fuzzer using the following commands: ```bash $ cd boa_engine $ cargo +nightly fuzz run -s none parser-idempotency ``` Co-authored-by: Addison Crump <addison.crump@cispa.de>pull/2414/head
Addison Crump
2 years ago
61 changed files with 1182 additions and 2 deletions
@ -0,0 +1,831 @@
|
||||
# This file is automatically @generated by Cargo. |
||||
# It is not intended for manual editing. |
||||
version = 3 |
||||
|
||||
[[package]] |
||||
name = "android_system_properties" |
||||
version = "0.1.5" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" |
||||
dependencies = [ |
||||
"libc", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "arbitrary" |
||||
version = "1.2.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "29d47fbf90d5149a107494b15a7dc8d69b351be2db3bb9691740e88ec17fd880" |
||||
dependencies = [ |
||||
"derive_arbitrary", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "autocfg" |
||||
version = "1.1.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" |
||||
|
||||
[[package]] |
||||
name = "bitflags" |
||||
version = "1.3.2" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" |
||||
|
||||
[[package]] |
||||
name = "boa_ast" |
||||
version = "0.16.0" |
||||
dependencies = [ |
||||
"arbitrary", |
||||
"bitflags", |
||||
"boa_interner", |
||||
"boa_macros", |
||||
"num-bigint", |
||||
"rustc-hash", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "boa_engine" |
||||
version = "0.16.0" |
||||
dependencies = [ |
||||
"bitflags", |
||||
"boa_ast", |
||||
"boa_gc", |
||||
"boa_interner", |
||||
"boa_macros", |
||||
"boa_parser", |
||||
"boa_profiler", |
||||
"boa_unicode", |
||||
"chrono", |
||||
"dyn-clone", |
||||
"fast-float", |
||||
"gc", |
||||
"indexmap", |
||||
"num-bigint", |
||||
"num-integer", |
||||
"num-traits", |
||||
"once_cell", |
||||
"rand", |
||||
"regress", |
||||
"rustc-hash", |
||||
"ryu-js", |
||||
"serde", |
||||
"serde_json", |
||||
"sptr", |
||||
"static_assertions", |
||||
"tap", |
||||
"thiserror", |
||||
"unicode-normalization", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "boa_fuzz" |
||||
version = "0.0.0" |
||||
dependencies = [ |
||||
"boa_ast", |
||||
"boa_engine", |
||||
"boa_interner", |
||||
"boa_parser", |
||||
"libfuzzer-sys", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "boa_gc" |
||||
version = "0.16.0" |
||||
dependencies = [ |
||||
"gc", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "boa_interner" |
||||
version = "0.16.0" |
||||
dependencies = [ |
||||
"arbitrary", |
||||
"boa_macros", |
||||
"indexmap", |
||||
"once_cell", |
||||
"phf", |
||||
"rustc-hash", |
||||
"static_assertions", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "boa_macros" |
||||
version = "0.16.0" |
||||
dependencies = [ |
||||
"quote", |
||||
"syn", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "boa_parser" |
||||
version = "0.16.0" |
||||
dependencies = [ |
||||
"bitflags", |
||||
"boa_ast", |
||||
"boa_interner", |
||||
"boa_macros", |
||||
"boa_profiler", |
||||
"boa_unicode", |
||||
"fast-float", |
||||
"num-bigint", |
||||
"num-traits", |
||||
"rustc-hash", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "boa_profiler" |
||||
version = "0.16.0" |
||||
|
||||
[[package]] |
||||
name = "boa_unicode" |
||||
version = "0.16.0" |
||||
dependencies = [ |
||||
"unicode-general-category", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "bumpalo" |
||||
version = "3.11.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" |
||||
|
||||
[[package]] |
||||
name = "cc" |
||||
version = "1.0.74" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "581f5dba903aac52ea3feb5ec4810848460ee833876f1f9b0fdeab1f19091574" |
||||
dependencies = [ |
||||
"jobserver", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "cfg-if" |
||||
version = "1.0.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" |
||||
|
||||
[[package]] |
||||
name = "chrono" |
||||
version = "0.4.22" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" |
||||
dependencies = [ |
||||
"iana-time-zone", |
||||
"js-sys", |
||||
"num-integer", |
||||
"num-traits", |
||||
"time", |
||||
"wasm-bindgen", |
||||
"winapi", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "codespan-reporting" |
||||
version = "0.11.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" |
||||
dependencies = [ |
||||
"termcolor", |
||||
"unicode-width", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "core-foundation-sys" |
||||
version = "0.8.3" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" |
||||
|
||||
[[package]] |
||||
name = "cxx" |
||||
version = "1.0.80" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "6b7d4e43b25d3c994662706a1d4fcfc32aaa6afd287502c111b237093bb23f3a" |
||||
dependencies = [ |
||||
"cc", |
||||
"cxxbridge-flags", |
||||
"cxxbridge-macro", |
||||
"link-cplusplus", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "cxx-build" |
||||
version = "1.0.80" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "84f8829ddc213e2c1368e51a2564c552b65a8cb6a28f31e576270ac81d5e5827" |
||||
dependencies = [ |
||||
"cc", |
||||
"codespan-reporting", |
||||
"once_cell", |
||||
"proc-macro2", |
||||
"quote", |
||||
"scratch", |
||||
"syn", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "cxxbridge-flags" |
||||
version = "1.0.80" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "e72537424b474af1460806647c41d4b6d35d09ef7fe031c5c2fa5766047cc56a" |
||||
|
||||
[[package]] |
||||
name = "cxxbridge-macro" |
||||
version = "1.0.80" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "derive_arbitrary" |
||||
version = "1.2.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "4903dff04948f22033ca30232ab8eca2c3fc4c913a8b6a34ee5199699814817f" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "dyn-clone" |
||||
version = "1.0.9" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" |
||||
|
||||
[[package]] |
||||
name = "fast-float" |
||||
version = "0.2.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" |
||||
|
||||
[[package]] |
||||
name = "gc" |
||||
version = "0.4.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "3edaac0f5832202ebc99520cb77c932248010c4645d20be1dc62d6579f5b3752" |
||||
dependencies = [ |
||||
"gc_derive", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "gc_derive" |
||||
version = "0.4.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "60df8444f094ff7885631d80e78eb7d88c3c2361a98daaabb06256e4500db941" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
"synstructure", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "getrandom" |
||||
version = "0.2.8" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" |
||||
dependencies = [ |
||||
"cfg-if", |
||||
"libc", |
||||
"wasi 0.11.0+wasi-snapshot-preview1", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "hashbrown" |
||||
version = "0.12.3" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" |
||||
|
||||
[[package]] |
||||
name = "iana-time-zone" |
||||
version = "0.1.53" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" |
||||
dependencies = [ |
||||
"android_system_properties", |
||||
"core-foundation-sys", |
||||
"iana-time-zone-haiku", |
||||
"js-sys", |
||||
"wasm-bindgen", |
||||
"winapi", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "iana-time-zone-haiku" |
||||
version = "0.1.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" |
||||
dependencies = [ |
||||
"cxx", |
||||
"cxx-build", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "indexmap" |
||||
version = "1.9.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" |
||||
dependencies = [ |
||||
"autocfg", |
||||
"hashbrown", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "itoa" |
||||
version = "1.0.4" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" |
||||
|
||||
[[package]] |
||||
name = "jobserver" |
||||
version = "0.1.25" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" |
||||
dependencies = [ |
||||
"libc", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "js-sys" |
||||
version = "0.3.60" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" |
||||
dependencies = [ |
||||
"wasm-bindgen", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "libc" |
||||
version = "0.2.137" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" |
||||
|
||||
[[package]] |
||||
name = "libfuzzer-sys" |
||||
version = "0.4.5" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "c8fff891139ee62800da71b7fd5b508d570b9ad95e614a53c6f453ca08366038" |
||||
dependencies = [ |
||||
"arbitrary", |
||||
"cc", |
||||
"once_cell", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "link-cplusplus" |
||||
version = "1.0.7" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" |
||||
dependencies = [ |
||||
"cc", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "log" |
||||
version = "0.4.17" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" |
||||
dependencies = [ |
||||
"cfg-if", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "memchr" |
||||
version = "2.5.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" |
||||
|
||||
[[package]] |
||||
name = "num-bigint" |
||||
version = "0.4.3" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" |
||||
dependencies = [ |
||||
"arbitrary", |
||||
"autocfg", |
||||
"num-integer", |
||||
"num-traits", |
||||
"serde", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "num-integer" |
||||
version = "0.1.45" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" |
||||
dependencies = [ |
||||
"autocfg", |
||||
"num-traits", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "num-traits" |
||||
version = "0.2.15" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" |
||||
dependencies = [ |
||||
"autocfg", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "once_cell" |
||||
version = "1.16.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" |
||||
|
||||
[[package]] |
||||
name = "phf" |
||||
version = "0.11.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" |
||||
dependencies = [ |
||||
"phf_macros", |
||||
"phf_shared", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "phf_generator" |
||||
version = "0.11.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" |
||||
dependencies = [ |
||||
"phf_shared", |
||||
"rand", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "phf_macros" |
||||
version = "0.11.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" |
||||
dependencies = [ |
||||
"phf_generator", |
||||
"phf_shared", |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "phf_shared" |
||||
version = "0.11.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" |
||||
dependencies = [ |
||||
"siphasher", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "ppv-lite86" |
||||
version = "0.2.17" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" |
||||
|
||||
[[package]] |
||||
name = "proc-macro2" |
||||
version = "1.0.47" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" |
||||
dependencies = [ |
||||
"unicode-ident", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "quote" |
||||
version = "1.0.21" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "rand" |
||||
version = "0.8.5" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" |
||||
dependencies = [ |
||||
"libc", |
||||
"rand_chacha", |
||||
"rand_core", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "rand_chacha" |
||||
version = "0.3.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" |
||||
dependencies = [ |
||||
"ppv-lite86", |
||||
"rand_core", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "rand_core" |
||||
version = "0.6.4" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" |
||||
dependencies = [ |
||||
"getrandom", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "regress" |
||||
version = "0.4.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "0a92ff21fe8026ce3f2627faaf43606f0b67b014dbc9ccf027181a804f75d92e" |
||||
dependencies = [ |
||||
"memchr", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "rustc-hash" |
||||
version = "1.1.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" |
||||
|
||||
[[package]] |
||||
name = "ryu" |
||||
version = "1.0.11" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" |
||||
|
||||
[[package]] |
||||
name = "ryu-js" |
||||
version = "0.2.2" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "6518fc26bced4d53678a22d6e423e9d8716377def84545fe328236e3af070e7f" |
||||
|
||||
[[package]] |
||||
name = "scratch" |
||||
version = "1.0.2" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" |
||||
|
||||
[[package]] |
||||
name = "serde" |
||||
version = "1.0.147" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" |
||||
dependencies = [ |
||||
"serde_derive", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "serde_derive" |
||||
version = "1.0.147" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "serde_json" |
||||
version = "1.0.87" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" |
||||
dependencies = [ |
||||
"itoa", |
||||
"ryu", |
||||
"serde", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "siphasher" |
||||
version = "0.3.10" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" |
||||
|
||||
[[package]] |
||||
name = "sptr" |
||||
version = "0.3.2" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" |
||||
|
||||
[[package]] |
||||
name = "static_assertions" |
||||
version = "1.1.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" |
||||
|
||||
[[package]] |
||||
name = "syn" |
||||
version = "1.0.103" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"unicode-ident", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "synstructure" |
||||
version = "0.12.6" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
"unicode-xid", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "tap" |
||||
version = "1.0.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" |
||||
|
||||
[[package]] |
||||
name = "termcolor" |
||||
version = "1.1.3" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" |
||||
dependencies = [ |
||||
"winapi-util", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "thiserror" |
||||
version = "1.0.37" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" |
||||
dependencies = [ |
||||
"thiserror-impl", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "thiserror-impl" |
||||
version = "1.0.37" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "time" |
||||
version = "0.1.44" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" |
||||
dependencies = [ |
||||
"libc", |
||||
"wasi 0.10.0+wasi-snapshot-preview1", |
||||
"winapi", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "tinyvec" |
||||
version = "1.6.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" |
||||
dependencies = [ |
||||
"tinyvec_macros", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "tinyvec_macros" |
||||
version = "0.1.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" |
||||
|
||||
[[package]] |
||||
name = "unicode-general-category" |
||||
version = "0.6.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7" |
||||
|
||||
[[package]] |
||||
name = "unicode-ident" |
||||
version = "1.0.5" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" |
||||
|
||||
[[package]] |
||||
name = "unicode-normalization" |
||||
version = "0.1.22" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" |
||||
dependencies = [ |
||||
"tinyvec", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "unicode-width" |
||||
version = "0.1.10" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" |
||||
|
||||
[[package]] |
||||
name = "unicode-xid" |
||||
version = "0.2.4" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" |
||||
|
||||
[[package]] |
||||
name = "wasi" |
||||
version = "0.10.0+wasi-snapshot-preview1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" |
||||
|
||||
[[package]] |
||||
name = "wasi" |
||||
version = "0.11.0+wasi-snapshot-preview1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" |
||||
|
||||
[[package]] |
||||
name = "wasm-bindgen" |
||||
version = "0.2.83" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" |
||||
dependencies = [ |
||||
"cfg-if", |
||||
"wasm-bindgen-macro", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "wasm-bindgen-backend" |
||||
version = "0.2.83" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" |
||||
dependencies = [ |
||||
"bumpalo", |
||||
"log", |
||||
"once_cell", |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
"wasm-bindgen-shared", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "wasm-bindgen-macro" |
||||
version = "0.2.83" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" |
||||
dependencies = [ |
||||
"quote", |
||||
"wasm-bindgen-macro-support", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "wasm-bindgen-macro-support" |
||||
version = "0.2.83" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
"wasm-bindgen-backend", |
||||
"wasm-bindgen-shared", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "wasm-bindgen-shared" |
||||
version = "0.2.83" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" |
||||
|
||||
[[package]] |
||||
name = "winapi" |
||||
version = "0.3.9" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" |
||||
dependencies = [ |
||||
"winapi-i686-pc-windows-gnu", |
||||
"winapi-x86_64-pc-windows-gnu", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "winapi-i686-pc-windows-gnu" |
||||
version = "0.4.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" |
||||
|
||||
[[package]] |
||||
name = "winapi-util" |
||||
version = "0.1.5" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" |
||||
dependencies = [ |
||||
"winapi", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "winapi-x86_64-pc-windows-gnu" |
||||
version = "0.4.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" |
@ -0,0 +1,29 @@
|
||||
[package] |
||||
name = "boa_fuzz" |
||||
version = "0.0.0" |
||||
publish = false |
||||
edition = "2021" |
||||
|
||||
[package.metadata] |
||||
cargo-fuzz = true |
||||
|
||||
[dependencies] |
||||
libfuzzer-sys = "0.4" |
||||
|
||||
boa_ast = { path = "../boa_ast", features = ["fuzz"] } |
||||
boa_engine = { path = "../boa_engine", features = ["fuzz"] } |
||||
boa_interner = { path = "../boa_interner", features = ["fuzz"] } |
||||
boa_parser = { path = "../boa_parser" } |
||||
|
||||
# Prevent this from interfering with workspaces |
||||
[workspace] |
||||
members = ["."] |
||||
|
||||
[profile.release] |
||||
debug = 1 |
||||
|
||||
[[bin]] |
||||
name = "parser-idempotency" |
||||
path = "fuzz_targets/parser-idempotency.rs" |
||||
test = false |
||||
doc = false |
@ -0,0 +1,37 @@
|
||||
# boa_engine-fuzz |
||||
|
||||
This directory contains fuzzers which can be used to automatically identify faults present in Boa. All the fuzzers in |
||||
this directory are [grammar-aware](https://www.fuzzingbook.org/html/Grammars.html) (based on |
||||
[Arbitrary](https://docs.rs/arbitrary/latest/arbitrary/)) and coverage-guided. See [common.rs](fuzz/fuzz_targets/common.rs) |
||||
for implementation specifics. |
||||
|
||||
You can run any fuzzer you wish with the following command (replacing `your-fuzzer` with a fuzzer availble in |
||||
fuzz_targets, e.g. `parser-idempotency`): |
||||
|
||||
```bash |
||||
cargo fuzz run -s none your-fuzzer |
||||
``` |
||||
|
||||
Note that you may wish to use a different sanitizer option (`-s`) according to what kind of issue you're looking for. |
||||
Refer to the [cargo-fuzz book](https://rust-fuzz.github.io/book/cargo-fuzz.html) for details on how to select a |
||||
sanitizer and other flags. |
||||
|
||||
## Parser Fuzzer |
||||
|
||||
The parser fuzzer, located in [parser-idempotency.rs](fuzz/fuzz_targets/parser-idempotency.rs), identifies |
||||
correctness issues in both the parser and the AST-to-source conversion process (e.g., via `to_interned_string`) by |
||||
searching for inputs which are not idempotent over parsing and conversion back to source. It does this by doing the |
||||
following: |
||||
|
||||
1. Generate an arbitrary AST |
||||
2. Convert that AST to source code with `to_interned_string`; we'll call this the "original source" |
||||
3. Parse the original source into an AST; we'll call this the "first AST" |
||||
- Arbitrary ASTs aren't guaranteed to be parseable; to avoid errors caused by this, we discard errors here. |
||||
4. Convert the first AST to source code with `to_interned_string`; we'll call this the "first source" |
||||
5. Parse the first source into an AST; we'll call this the "second AST" |
||||
- Since the original source was parseable, the first source must be parseable; emit any errors parsing produces. |
||||
6. Compare the first AST and the second AST. If they are not equal, emit an error. |
||||
- An error here indicates that either the parser or the AST-to-source conversion lost information or added incorrect |
||||
information, as the inputs parsed between the two should be the same. |
||||
|
||||
In this way, this fuzzer can identify correctness issues present in the parser. |
@ -0,0 +1,74 @@
|
||||
use boa_ast::{ |
||||
visitor::{VisitWith, VisitorMut}, |
||||
Expression, StatementList, |
||||
}; |
||||
use boa_interner::{Interner, Sym}; |
||||
use libfuzzer_sys::arbitrary; |
||||
use libfuzzer_sys::arbitrary::{Arbitrary, Unstructured}; |
||||
use std::fmt::{Debug, Formatter}; |
||||
use std::ops::ControlFlow; |
||||
|
||||
/// Context for performing fuzzing. This structure contains both the generated AST as well as the
|
||||
/// context used to resolve the symbols therein.
|
||||
pub struct FuzzData { |
||||
pub interner: Interner, |
||||
pub ast: StatementList, |
||||
} |
||||
|
||||
impl<'a> Arbitrary<'a> for FuzzData { |
||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> { |
||||
let mut interner = Interner::with_capacity(8); |
||||
let mut syms_available = Vec::with_capacity(8); |
||||
for c in 'a'..='h' { |
||||
syms_available.push(interner.get_or_intern(&*String::from(c))); |
||||
} |
||||
|
||||
let mut ast = StatementList::arbitrary(u)?; |
||||
|
||||
struct FuzzReplacer<'a, 's, 'u> { |
||||
syms: &'s [Sym], |
||||
u: &'u mut Unstructured<'a>, |
||||
} |
||||
impl<'a, 's, 'u, 'ast> VisitorMut<'ast> for FuzzReplacer<'a, 's, 'u> { |
||||
type BreakTy = arbitrary::Error; |
||||
|
||||
// TODO arbitrary strings literals?
|
||||
|
||||
fn visit_expression_mut( |
||||
&mut self, |
||||
node: &'ast mut Expression, |
||||
) -> ControlFlow<Self::BreakTy> { |
||||
if matches!(node, Expression::FormalParameterList(_)) { |
||||
match self.u.arbitrary() { |
||||
Ok(id) => *node = Expression::Identifier(id), |
||||
Err(e) => return ControlFlow::Break(e), |
||||
} |
||||
} |
||||
node.visit_with_mut(self) |
||||
} |
||||
|
||||
fn visit_sym_mut(&mut self, node: &'ast mut Sym) -> ControlFlow<Self::BreakTy> { |
||||
*node = self.syms[node.get() % self.syms.len()]; |
||||
ControlFlow::Continue(()) |
||||
} |
||||
} |
||||
|
||||
let mut replacer = FuzzReplacer { |
||||
syms: &syms_available, |
||||
u, |
||||
}; |
||||
if let ControlFlow::Break(e) = replacer.visit_statement_list_mut(&mut ast) { |
||||
Err(e) |
||||
} else { |
||||
Ok(Self { interner, ast }) |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl Debug for FuzzData { |
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
||||
f.debug_struct("FuzzData") |
||||
.field("ast", &self.ast) |
||||
.finish_non_exhaustive() |
||||
} |
||||
} |
@ -0,0 +1,74 @@
|
||||
#![no_main] |
||||
|
||||
mod common; |
||||
|
||||
use crate::common::FuzzData; |
||||
use boa_interner::ToInternedString; |
||||
use boa_parser::Parser; |
||||
use libfuzzer_sys::fuzz_target; |
||||
use libfuzzer_sys::Corpus; |
||||
use std::error::Error; |
||||
use std::io::Cursor; |
||||
|
||||
/// Fuzzer test harness. This function accepts the arbitrary AST and performs the fuzzing operation.
|
||||
///
|
||||
/// See [README.md](../README.md) for details on the design of this fuzzer.
|
||||
fn do_fuzz(mut data: FuzzData) -> Result<(), Box<dyn Error>> { |
||||
let original = data.ast.to_interned_string(&data.interner); |
||||
|
||||
let mut parser = Parser::new(Cursor::new(&original)); |
||||
|
||||
let before = data.interner.len(); |
||||
// For a variety of reasons, we may not actually produce valid code here (e.g., nameless function).
|
||||
// Fail fast and only make the next checks if we were valid.
|
||||
if let Ok(first) = parser.parse_all(&mut data.interner) { |
||||
let after_first = data.interner.len(); |
||||
let first_interned = first.to_interned_string(&data.interner); |
||||
|
||||
assert_eq!( |
||||
before, |
||||
after_first, |
||||
"The number of interned symbols changed; a new string was read.\nBefore:\n{}\nAfter:\n{}\nBefore (AST):\n{:#?}\nAfter (AST):\n{:#?}", |
||||
original, |
||||
first_interned, |
||||
data.ast, |
||||
first |
||||
); |
||||
let mut parser = Parser::new(Cursor::new(&first_interned)); |
||||
|
||||
// Now, we most assuredly should produce valid code. It has already gone through a first pass.
|
||||
let second = parser |
||||
.parse_all(&mut data.interner) |
||||
.expect("Could not parse the first-pass interned copy."); |
||||
let second_interned = second.to_interned_string(&data.interner); |
||||
let after_second = data.interner.len(); |
||||
assert_eq!( |
||||
after_first, |
||||
after_second, |
||||
"The number of interned symbols changed; a new string was read.\nBefore:\n{}\nAfter:\n{}\nBefore (AST):\n{:#?}\nAfter (AST):\n{:#?}", |
||||
first_interned, |
||||
second_interned, |
||||
first, |
||||
second |
||||
); |
||||
assert_eq!( |
||||
first, |
||||
second, |
||||
"Expected the same AST after two intern passes, but found dissimilar.\nOriginal:\n{}\nFirst:\n{}\nSecond:\n{}", |
||||
original, |
||||
first_interned, |
||||
second_interned, |
||||
); |
||||
} |
||||
Ok(()) |
||||
} |
||||
|
||||
// Fuzz harness wrapper to expose it to libfuzzer (and thus cargo-fuzz)
|
||||
// See: https://rust-fuzz.github.io/book/cargo-fuzz.html
|
||||
fuzz_target!(|data: FuzzData| -> Corpus { |
||||
if do_fuzz(data).is_ok() { |
||||
Corpus::Keep |
||||
} else { |
||||
Corpus::Reject |
||||
} |
||||
}); |
Loading…
Reference in new issue