diff --git a/.circleci/config.yml b/.circleci/config.yml index 010be2c..e7f3923 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,20 +1,47 @@ -version: 2.0 -jobs: - build: - docker: - - image: debian +version: 2.1 + +commands: + tests: + description: "Run tests" + parameters: + features: + type: string steps: - checkout - run: - name: Setup, Build & Test + name: Setup command: | - export PATH="$HOME/.cargo/bin:$HOME:$PATH" - + echo "Installing curl..." apt-get update && apt-get install -y curl - echo "Installing Rust..." curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable echo "Installing just..." curl -LSfs https://japaric.github.io/trust/install.sh | sh -s -- --git casey/just --target x86_64-unknown-linux-musl --to $HOME - hash -r - just ci-debian + - run: + name: Test + command: | + export PATH="$HOME/.cargo/bin:$HOME:$PATH" + just FEATURES="<>" ci-debian + + +jobs: + test-features-default: + docker: + - image: debian + steps: + - tests: + features: "" + test-features-patched: + docker: + - image: debian + steps: + - tests: + features: "patched" + +workflows: + version: 2 + tests: + jobs: + - test-features-default + - test-features-patched + diff --git a/Cargo.toml b/Cargo.toml index e52a2a7..c39ecfc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,6 @@ libquickjs-sys = { version = "0.3.0", path = "./libquickjs-sys" } members = [ "libquickjs-sys", ] + +[features] +patched = ["libquickjs-sys/patched"] diff --git a/README.md b/README.md index 427a460..a88fe55 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,12 @@ If you would like to use a system version instead, see below. QuickJS will always be statically linked to your binary. +### Features + +The crate supports the following features: + +* `patched` applies QuickJS patches that can be found in `libquickjs-sys/embed/patches` directory. + ### System installation To use the system installation, without the bundled feature, first install the required diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 15c7778..be6fdaa 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -23,6 +23,12 @@ jobs: - job: macos_stable displayName: Mac OS Stable + strategy: + matrix: + default: + FEATURES: '' + patched: + FEATURES: 'patched' pool: vmImage: 'macOS-10.14' @@ -37,5 +43,5 @@ jobs: echo "Installing just..." curl -LSfs https://japaric.github.io/trust/install.sh | sh -s -- --git casey/just --to $HOME hash -r - just ci-macos + just FEATURES="$FEATURES" ci-macos displayName: setup and test diff --git a/justfile b/justfile index 7eb3c23..8766072 100644 --- a/justfile +++ b/justfile @@ -1,6 +1,7 @@ embed_dir := "./libquickjs-sys/embed/quickjs" DOWNLOAD_URL := "https://bellard.org/quickjs/quickjs-2019-08-10.tar.xz" +FEATURES := "" download-new: test -d {{embed_dir}} && rm -r {{embed_dir}} || echo "" @@ -25,7 +26,7 @@ ci-debian-setup: ci-test: # Limit test threads to 1 to show test name before execution. - RUST_TEST_THREADS=1 cargo test --verbose + RUST_TEST_THREADS=1 cargo test --verbose --features="{{FEATURES}}" ci-lint: rustup component add rustfmt clippy diff --git a/libquickjs-sys/Cargo.toml b/libquickjs-sys/Cargo.toml index 953e75c..5167bfb 100644 --- a/libquickjs-sys/Cargo.toml +++ b/libquickjs-sys/Cargo.toml @@ -20,6 +20,7 @@ copy_dir = { version = "0.1.2", optional = true } [features] bundled = ["copy_dir"] +patched = [] default = ["bundled"] system = ["bindgen"] diff --git a/libquickjs-sys/build.rs b/libquickjs-sys/build.rs index f2785a4..34501f5 100644 --- a/libquickjs-sys/build.rs +++ b/libquickjs-sys/build.rs @@ -19,6 +19,9 @@ fn main() { #[cfg(not(feature = "bindgen"))] panic!("Invalid configuration for libquickjs-sys: Must either enable the bundled or the bindgen feature"); + #[cfg(feature = "patched")] + panic!("Invalid configuration for libquickjs-sys: the patched feature is incompatible with the system feature"); + let lib = if cfg!(unix) { if exists("/usr/lib/quickjs/libquickjs.a") { "/usr/lib/quickjs" @@ -58,6 +61,9 @@ fn main() { } copy_dir::copy_dir("./embed/quickjs", &code_dir).expect("Could not copy quickjs directory"); + #[cfg(feature = "patched")] + apply_patches(&code_dir); + eprintln!("Compiling quickjs..."); std::process::Command::new("make") .arg("libquickjs.a") @@ -77,3 +83,26 @@ fn main() { ); println!("cargo:rustc-link-lib=static=quickjs"); } + +#[cfg(feature = "patched")] +fn apply_patches(code_dir: &PathBuf) { + use std::fs; + + eprintln!("Applying patches..."); + for patch in fs::read_dir("./embed/patches").expect("Could not open patches directory") { + let patch = patch.expect("Could not open patch"); + eprintln!("Applying {:?}...", patch.file_name()); + let status = std::process::Command::new("patch") + .current_dir(&code_dir) + .arg("-i") + .arg(fs::canonicalize(patch.path()).expect("Cannot canonicalize patch path")) + .spawn() + .expect("Could not apply patches") + .wait() + .expect("Could not apply patches"); + assert!( + status.success(), + "Patch command returned non-zero exit code" + ); + } +} diff --git a/libquickjs-sys/embed/patches/stack-overflow-signed.patch b/libquickjs-sys/embed/patches/stack-overflow-signed.patch new file mode 100644 index 0000000..c4ce46b --- /dev/null +++ b/libquickjs-sys/embed/patches/stack-overflow-signed.patch @@ -0,0 +1,15 @@ +diff -urN quickjs-2019-07-28/quickjs.c quickjs-2019-07-28-stack-overflow-signed/quickjs.c +--- quickjs-2019-07-28/quickjs.c 2019-07-28 15:03:03.000000000 +0000 ++++ quickjs-2019-07-28-stack-overflow-signed/quickjs.c 2019-08-09 20:00:03.666846091 +0000 +@@ -1732,9 +1732,9 @@ + + static inline BOOL js_check_stack_overflow(JSContext *ctx, size_t alloca_size) + { +- size_t size; ++ ptrdiff_t size; + size = ctx->stack_top - js_get_stack_pointer(); +- return unlikely((size + alloca_size) > ctx->stack_size); ++ return unlikely((size + (ptrdiff_t)alloca_size) > (ptrdiff_t)ctx->stack_size); + } + #endif +