fix: prevent panic from out of bound slice access

This commit is contained in:
2026-04-03 08:10:18 +02:00
parent a49e7c7e4b
commit 83a6efc205
4 changed files with 347 additions and 119 deletions

301
Cargo.lock generated
View File

@@ -24,9 +24,9 @@ dependencies = [
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
@@ -34,6 +34,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
[[package]] [[package]]
name = "bstr" name = "bstr"
version = "0.2.17" version = "0.2.17"
@@ -45,15 +51,19 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.78" version = "1.2.58"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]] [[package]]
name = "clap" name = "clap"
@@ -63,7 +73,7 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [ dependencies = [
"ansi_term", "ansi_term",
"atty", "atty",
"bitflags", "bitflags 1.3.2",
"strsim", "strsim",
"textwrap", "textwrap",
"unicode-width", "unicode-width",
@@ -71,10 +81,32 @@ dependencies = [
] ]
[[package]] [[package]]
name = "getrandom" name = "either"
version = "0.2.8" version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.61.2",
]
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "getrandom"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@@ -90,6 +122,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "home"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
dependencies = [
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@@ -98,15 +139,21 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.139" version = "0.2.184"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]] [[package]]
name = "lua-src" name = "lua-src"
version = "544.0.1" version = "546.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "708ba3c844d5e9d38def4a09dd871c17c370f519b3c4b7261fbabe4a613a814c" checksum = "2da0daa7eee611a4c30c8f5ee31af55266e26e573971ba9336d2993e2da129b2"
dependencies = [ dependencies = [
"cc", "cc",
] ]
@@ -129,18 +176,19 @@ dependencies = [
[[package]] [[package]]
name = "luajit-src" name = "luajit-src"
version = "210.4.5+resty2cf5186" version = "210.4.8+resty107baaf"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27b7992a40e602786272d84c6f2beca44a588ededcfd57b48ec6f82008a7cb97" checksum = "e05167e8b2a2185758d83ed23541e5bd8bce37072e4204e0ef2c9b322bc87c4e"
dependencies = [ dependencies = [
"cc", "cc",
"which",
] ]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.5.0" version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]] [[package]]
name = "memoffset" name = "memoffset"
@@ -153,9 +201,9 @@ dependencies = [
[[package]] [[package]]
name = "mlua" name = "mlua"
version = "0.8.7" version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ee2ad7a9aa69056b148d9d590344bc155d3ce0d2200e3b2838f7034f6ba33c1" checksum = "0bb37b0ba91f017aa7ca2b98ef99496827770cd635b4a932a6047c5b4bbe678e"
dependencies = [ dependencies = [
"bstr", "bstr",
"cc", "cc",
@@ -169,32 +217,31 @@ dependencies = [
[[package]] [[package]]
name = "nix" name = "nix"
version = "0.26.1" version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46a58d1d356c6597d08cde02c2f09d785b09e28711837b1ed667dc652c08a694" checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.3.2",
"cfg-if", "cfg-if",
"libc", "libc",
"memoffset", "memoffset",
"pin-utils", "pin-utils",
"static_assertions",
] ]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.15" version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.17.0" version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]] [[package]]
name = "pin-utils" name = "pin-utils"
@@ -204,30 +251,33 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.26" version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.17" version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.49" version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.23" version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@@ -269,19 +319,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "serde" name = "rustix"
version = "1.0.152" version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags 2.11.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.152" version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -289,10 +362,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "static_assertions" name = "shlex"
version = "1.1.0" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]] [[package]]
name = "strsim" name = "strsim"
@@ -302,9 +375,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.107" version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -322,9 +395,9 @@ dependencies = [
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.5.10" version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@@ -347,15 +420,15 @@ checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.6" version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.10" version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]] [[package]]
name = "vec_map" name = "vec_map"
@@ -365,9 +438,21 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
@@ -390,3 +475,111 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[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 = "zerocopy"
version = "0.8.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@@ -1,3 +1,4 @@
use crate::OOB;
use crate::{ use crate::{
lua_new_bytes, lua_new_bytes_from_string, lua_new_from_slice, vec_from_variadic, LuabyteArray, lua_new_bytes, lua_new_bytes_from_string, lua_new_from_slice, vec_from_variadic, LuabyteArray,
BITV, DEBUG, ERR, ERROR, INFO, WARN, BITV, DEBUG, ERR, ERROR, INFO, WARN,
@@ -5,6 +6,7 @@ use crate::{
use mlua::prelude::*; use mlua::prelude::*;
use mlua::Variadic; use mlua::Variadic;
use rand::Rng; use rand::Rng;
use std::cmp;
use std::collections::HashMap; use std::collections::HashMap;
use std::io::{BufRead, BufReader, Cursor, Read, Write}; use std::io::{BufRead, BufReader, Cursor, Read, Write};
use std::os::fd::RawFd; use std::os::fd::RawFd;
@@ -895,7 +897,7 @@ fn fcgi_decode_stdin_data(
let mut pattern = boundary.to_string(); let mut pattern = boundary.to_string();
pattern.push_str("\r\n"); pattern.push_str("\r\n");
if let Some(index) = twoway::find_bytes(buffer, pattern.as_bytes()) { if let Some(index) = twoway::find_bytes(buffer, pattern.as_bytes()) {
let _ = buffer.drain(0..index + pattern.len()); let _ = buffer.drain(0..cmp::min(index + pattern.len(), buffer.len()));
DEBUG!("Boundary found, decoding header"); DEBUG!("Boundary found, decoding header");
return Ok(Some(FCGIRequestBodyState::HeaderDecoding( return Ok(Some(FCGIRequestBodyState::HeaderDecoding(
boundary.to_string(), boundary.to_string(),
@@ -906,16 +908,21 @@ fn fcgi_decode_stdin_data(
FCGIRequestBodyState::HeaderDecoding(boundary) => { FCGIRequestBodyState::HeaderDecoding(boundary) => {
if let Some(end_index) = twoway::find_bytes(buffer, "\r\n\r\n".as_bytes()) { if let Some(end_index) = twoway::find_bytes(buffer, "\r\n\r\n".as_bytes()) {
let pattern = "Content-Disposition:"; let pattern = "Content-Disposition:";
if let Some(index) = twoway::find_bytes(&buffer[0..end_index], pattern.as_bytes()) { if let Some(index) =
twoway::find_bytes(buffer.get(0..end_index).ok_or(OOB!())?, pattern.as_bytes())
{
// got content-disposition, get the line // got content-disposition, get the line
let start_lime_index = index + pattern.len(); let start_lime_index = index + pattern.len();
let offset = twoway::find_bytes( let offset = twoway::find_bytes(
&buffer[start_lime_index..end_index + 2], buffer.get(start_lime_index..end_index + 2).ok_or(OOB!())?,
"\r\n".as_bytes(), "\r\n".as_bytes(),
) )
.ok_or(ERR!("Unknown ending of Content-Disposition line"))?; .ok_or(ERR!("Unknown ending of Content-Disposition line"))?;
let line = String::from_utf8( let line = String::from_utf8(
buffer[start_lime_index..start_lime_index + offset].to_vec(), buffer
.get(start_lime_index..start_lime_index + offset)
.ok_or(OOB!())?
.to_vec(),
) )
.map_err(|e| ERR!(e.to_string()))?; .map_err(|e| ERR!(e.to_string()))?;
DEBUG!("Content-Disposition: {}", line); DEBUG!("Content-Disposition: {}", line);
@@ -927,10 +934,10 @@ fn fcgi_decode_stdin_data(
for text in line.trim().split(";") { for text in line.trim().split(";") {
let trimmed = text.trim(); let trimmed = text.trim();
if let Some(index) = trimmed.find("filename=") { if let Some(index) = trimmed.find("filename=") {
fileopt = Some(&text[index + 11..trimmed.len()]); fileopt = Some(text.get(index + 11..trimmed.len()).ok_or(OOB!())?);
DEBUG!("Part filename = [{}]", fileopt.unwrap()); DEBUG!("Part filename = [{}]", fileopt.unwrap());
} else if let Some(index) = trimmed.find("name=") { } else if let Some(index) = trimmed.find("name=") {
name = Some(&text[index + 7..trimmed.len()]); name = Some(text.get(index + 7..trimmed.len()).ok_or(OOB!())?);
DEBUG!("Part name = [{}]", name.unwrap()); DEBUG!("Part name = [{}]", name.unwrap());
} else { } else {
DEBUG!("Ignore part: {}", text); DEBUG!("Ignore part: {}", text);
@@ -964,10 +971,10 @@ fn fcgi_decode_stdin_data(
vec: Vec::new(), vec: Vec::new(),
}; };
DEBUG!("Header decoding finished, go to data-decoding"); DEBUG!("Header decoding finished, go to data-decoding");
let _ = buffer.drain(0..end_index + 4); let _ = buffer.drain(0..cmp::min(end_index + 4, buffer.len()));
return Ok(Some(part_state)); return Ok(Some(part_state));
} }
let _ = buffer.drain(0..end_index + 4); let _ = buffer.drain(0..cmp::min(end_index + 4, buffer.len()));
} }
Ok(None) Ok(None)
} }
@@ -981,57 +988,59 @@ fn fcgi_decode_stdin_data(
match twoway::find_bytes(buffer, "\r\n".as_bytes()) { match twoway::find_bytes(buffer, "\r\n".as_bytes()) {
Some(index) => { Some(index) => {
let mut pattern_len = boundary.len(); let mut pattern_len = boundary.len();
let mut content_data = &buffer[0..index + 2]; let mut content_data = buffer.get(0..index + 2).ok_or(OOB!())?;
let mut remaining = &buffer[index + 2..]; let mut remaining = match buffer.get(index + 2..) {
if remaining.len() > pattern_len { Some(data) if data.len() > pattern_len => data,
//DEBUG!("content : {:?}", content_data); Some(_) => break,
//DEBUG!("boundary: {:?}", boundary.as_bytes()); None => break,
//DEBUG!("remaining : {:?}", remaining); };
if remaining.starts_with(boundary.as_bytes()) {
remaining = &remaining[pattern_len..]; //DEBUG!("content : {:?}", content_data);
let state; //DEBUG!("boundary: {:?}", boundary.as_bytes());
if remaining.starts_with("\r\n".as_bytes()) { //DEBUG!("remaining : {:?}", remaining);
state = Some(FCGIRequestBodyState::HeaderDecoding( if remaining.starts_with(boundary.as_bytes()) {
boundary.to_owned(), remaining = remaining.get(pattern_len..).ok_or(OOB!())?;
)); let state;
DEBUG!("Part Boundary end found, decoding next header"); if remaining.starts_with("\r\n".as_bytes()) {
} else if remaining.starts_with("--".as_bytes()) { state =
pattern_len += 2; Some(FCGIRequestBodyState::HeaderDecoding(boundary.to_owned()));
state = Some(FCGIRequestBodyState::BinaryData); DEBUG!("Part Boundary end found, decoding next header");
DEBUG!("Request Boundary end found, finish stdin read"); } else if remaining.starts_with("--".as_bytes()) {
} else { pattern_len += 2;
return Err(ERR!("Invalid boundary ending")); state = Some(FCGIRequestBodyState::BinaryData);
} DEBUG!("Request Boundary end found, finish stdin read");
// ignore or write to file
content_data = &buffer[0..index];
let value;
if let Some(part) = file {
value = format!(
"{{\"file\":\"{}\",\"tmp\":\"{}\"}}",
part.name, part.tmp_path
);
part.handle.write_all(content_data)?;
} else {
vec.extend(content_data);
// collect the data
value = String::from_utf8(vec.to_vec())
.map_err(|e| ERR!(e.to_string()))?;
DEBUG!("part data: {}", &value);
}
let _ = params.insert(format!("MULTIPART[{}]", name), value);
let _ = buffer.drain(0..content_data.len() + pattern_len + 4);
return Ok(state);
} else { } else {
// ignore or write to file return Err(ERR!("Invalid boundary ending"));
if let Some(part) = file {
part.handle.write_all(content_data)?;
} else {
vec.extend(content_data);
}
let _ = buffer.drain(0..content_data.len());
} }
// ignore or write to file
content_data = buffer.get(0..index).ok_or(OOB!())?;
let value;
if let Some(part) = file {
value = format!(
"{{\"file\":\"{}\",\"tmp\":\"{}\"}}",
part.name, part.tmp_path
);
part.handle.write_all(content_data)?;
} else {
vec.extend(content_data);
// collect the data
value = String::from_utf8(vec.to_vec())
.map_err(|e| ERR!(e.to_string()))?;
DEBUG!("part data: {}", &value);
}
let _ = params.insert(format!("MULTIPART[{}]", name), value);
let _ = buffer.drain(
0..cmp::min(content_data.len() + pattern_len + 4, buffer.len()),
);
return Ok(state);
} else { } else {
break; // ignore or write to file
if let Some(part) = file {
part.handle.write_all(content_data)?;
} else {
vec.extend(content_data);
}
let _ = buffer.drain(0..cmp::min(content_data.len(), buffer.len()));
} }
} }
None => { None => {
@@ -1086,13 +1095,13 @@ fn fcgi_decode_strlen(data: &[u8]) -> usize {
fn fcgi_decode_params(rq: &mut FGCIRequest, vec: &Vec<u8>) -> Result<(), std::io::Error> { fn fcgi_decode_params(rq: &mut FGCIRequest, vec: &Vec<u8>) -> Result<(), std::io::Error> {
let mut pos = 0; let mut pos = 0;
while pos < vec.len() { while pos < vec.len() {
let data = &vec[pos..]; let data = vec.get(pos..).ok_or(OOB!())?;
let mut index: usize = 1; let mut index: usize = 1;
let key_len = fcgi_decode_strlen(data); let key_len = fcgi_decode_strlen(data);
if key_len > 127 { if key_len > 127 {
index = 4; index = 4;
} }
let value_len = fcgi_decode_strlen(&data[index..]); let value_len = fcgi_decode_strlen(data.get(index..).ok_or(OOB!())?);
//INFO!("Key len {}, value len {}", key_len, value_len); //INFO!("Key len {}, value len {}", key_len, value_len);
if value_len > 127 { if value_len > 127 {
index += 4; index += 4;
@@ -1102,11 +1111,14 @@ fn fcgi_decode_params(rq: &mut FGCIRequest, vec: &Vec<u8>) -> Result<(), std::io
//DEBUG!("data: {:?}", data); //DEBUG!("data: {:?}", data);
//DEBUG!("key: {:?}", data[index..index + key_len].to_vec()); //DEBUG!("key: {:?}", data[index..index + key_len].to_vec());
//DEBUG!("Value: {:?}", data[index+key_len..index+key_len+value_len].to_vec()); //DEBUG!("Value: {:?}", data[index+key_len..index+key_len+value_len].to_vec());
let key = String::from_utf8(data[index..index + key_len].to_vec()) let key = String::from_utf8(data.get(index..index + key_len).ok_or(OOB!())?.to_vec())
.map_err(|e| ERR!(e.to_string()))?; .map_err(|e| ERR!(e.to_string()))?;
let value: String = let value: String = String::from_utf8(
String::from_utf8(data[index + key_len..index + key_len + value_len].to_vec()) data.get(index + key_len..index + key_len + value_len)
.map_err(|e| ERR!(e.to_string()))?; .ok_or(OOB!())?
.to_vec(),
)
.map_err(|e| ERR!(e.to_string()))?;
DEBUG!("PARAM: [{}] -> [{}]", key, value); DEBUG!("PARAM: [{}] -> [{}]", key, value);
pos = pos + index + key_len + value_len; pos = pos + index + key_len + value_len;

View File

@@ -2,7 +2,7 @@ use std::sync::mpsc::{self, Receiver};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
use crate::{INFO, WARN}; use crate::{ERR, ERROR, INFO, WARN};
/// A thread pool of workers /// A thread pool of workers
/// ///
@@ -82,7 +82,18 @@ impl ThreadPool {
F: FnOnce() + Send + 'static, F: FnOnce() + Send + 'static,
{ {
let job = Box::new(f); let job = Box::new(f);
self.dispatcher.as_ref().unwrap().send(job).unwrap(); if let Err(error) = self
.dispatcher
.as_ref()
.ok_or(ERR!("No sender found in dispatcher"))
.and_then(|sender| {
sender
.send(job)
.map_err(|_| ERR!("Unable to send job to worker"))
})
{
ERROR!("Error to dispatch request: {}", error);
}
} }
} }
@@ -91,7 +102,9 @@ impl Drop for ThreadPool {
drop(self.dispatcher.take()); drop(self.dispatcher.take());
for worker in self.workers.drain(..) { for worker in self.workers.drain(..) {
INFO!("Dropping worker {}", worker.id); INFO!("Dropping worker {}", worker.id);
worker.thread.join().unwrap(); if let Err(_) = worker.thread.join() {
WARN!("Unable to join worker {}", worker.id);
}
} }
} }
} }

View File

@@ -111,6 +111,16 @@ macro_rules! ERR {
) )
}; };
} }
/// Return an Error Result object from error string
///
#[macro_export]
macro_rules! OOB {
() => {
ERR!("Out of bound")
};
}
/// Bit value at address /// Bit value at address
/// ///
#[macro_export] #[macro_export]