diff --git a/.github/workflows/mayhem.yml b/.github/workflows/mayhem.yml new file mode 100644 index 00000000..f003bd88 --- /dev/null +++ b/.github/workflows/mayhem.yml @@ -0,0 +1,66 @@ +name: Mayhem +on: + push: + pull_request: + workflow_dispatch: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build: + name: '${{ matrix.os }} shared=${{ matrix.shared }} ${{ matrix.build_type }}' + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + shared: [false] + build_type: [Release] + include: + - os: ubuntu-latest + triplet: x64-linux + + steps: + - uses: actions/checkout@v2 + + - name: Log in to the Container registry + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + with: + context: . + push: true + build-args: --no-cache + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Start analysis of Parser + uses: ForAllSecure/mcode-action@v1 + with: + mayhem-token: ${{ secrets.MAYHEM_TOKEN }} + args: --file mayhemfiles/Mayhemfile_Parser --image ${{ steps.meta.outputs.tags }} + sarif-output: sarif + + - name: Start analysis of Filename + uses: ForAllSecure/mcode-action@v1 + with: + mayhem-token: ${{ secrets.MAYHEM_TOKEN }} + args: --file mayhemfiles/Mayhemfile_Filename --image ${{ steps.meta.outputs.tags }} + sarif-output: sarif + + - name: Upload SARIF file(s) + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: sarif diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..7cf1b15a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +# Build Stage +FROM --platform=linux/amd64 rustlang/rust:nightly as builder + +ENV DEBIAN_FRONTEND=noninteractive +## Install build dependencies. +RUN apt-get update +RUN apt-get install -y cmake clang +RUN cargo install cargo-fuzz + +## Add source code to the build stage. +ADD . /lightningcss/ + +# needed to fix bug with nightly version not parsing cargo.toml +WORKDIR /lightningcss/ +RUN sed '/serde = \[\"smallvec\/serde\", \"cssparser\/serde\"\]/d' Cargo.toml > Cargo.toml2 +RUN mv Cargo.toml2 Cargo.toml + +WORKDIR /lightningcss/fuzz/ + +RUN cargo +nightly fuzz build + +FROM --platform=linux/amd64 rustlang/rust:nightly + +## TODO: Change +COPY --from=builder /lightningcss/fuzz/target/x86_64-unknown-linux-gnu/release/filename / +COPY --from=builder /lightningcss/fuzz/target/x86_64-unknown-linux-gnu/release/parser / diff --git a/fuzz/.gitignore b/fuzz/.gitignore new file mode 100644 index 00000000..a0925114 --- /dev/null +++ b/fuzz/.gitignore @@ -0,0 +1,3 @@ +target +corpus +artifacts diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 00000000..16704442 --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "lightningcss-fuzz" +version = "0.0.0" +authors = ["Automatically generated"] +publish = false +edition = "2018" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" + +[dependencies.lightningcss] +path = ".." + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "parser" +path = "fuzz_targets/parser.rs" +test = false +doc = false + +[[bin]] +name = "filename" +path = "fuzz_targets/filename.rs" +test = false +doc = false diff --git a/fuzz/fuzz_targets/filename.rs b/fuzz/fuzz_targets/filename.rs new file mode 100644 index 00000000..7a658908 --- /dev/null +++ b/fuzz/fuzz_targets/filename.rs @@ -0,0 +1,37 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| { + match std::str::from_utf8(data) { + Ok(s) => { + use lightningcss::stylesheet::{ + StyleSheet, ParserOptions, MinifyOptions, PrinterOptions + }; + + let mut opts = ParserOptions::default(); + opts.filename = s.to_owned(); + + // Parse a style sheet from a string. + match StyleSheet::parse( + r#" + .foo { + color: red; + } + + .bar { + color: red; + } + "#, + opts + ) { + Ok(mut stylesheet) => { + stylesheet.minify(MinifyOptions::default()).unwrap(); + stylesheet.to_css(PrinterOptions::default()).unwrap(); + }, + _ => { + }, + }; + }, + _ => {}, + } +}); diff --git a/fuzz/fuzz_targets/parser.rs b/fuzz/fuzz_targets/parser.rs new file mode 100644 index 00000000..2362b14d --- /dev/null +++ b/fuzz/fuzz_targets/parser.rs @@ -0,0 +1,26 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| { + match std::str::from_utf8(data) { + Ok(s) => { + use lightningcss::stylesheet::{ + StyleSheet, ParserOptions, MinifyOptions, PrinterOptions + }; + + // Parse a style sheet from a string. + match StyleSheet::parse( + s, + ParserOptions::default() + ) { + Ok(mut stylesheet) => { + stylesheet.minify(MinifyOptions::default()).unwrap(); + stylesheet.to_css(PrinterOptions::default()).unwrap(); + }, + _ => { + }, + }; + }, + _ => {}, + } +}); diff --git a/mayhemfiles/Filename.mayhemfile b/mayhemfiles/Filename.mayhemfile new file mode 100644 index 00000000..1e384f97 --- /dev/null +++ b/mayhemfiles/Filename.mayhemfile @@ -0,0 +1,6 @@ +project: lightningcss +target: filename +duration: 90 + +cmds: + - cmd: /filename diff --git a/mayhemfiles/Parser.mayhemfile b/mayhemfiles/Parser.mayhemfile new file mode 100644 index 00000000..bb231a62 --- /dev/null +++ b/mayhemfiles/Parser.mayhemfile @@ -0,0 +1,6 @@ +project: lightningcss +target: parser +duration: 90 + +cmds: + - cmd: /parser