From 14edf4088d74e95898addb8aab04b4b58e29975d Mon Sep 17 00:00:00 2001 From: Wojciech Rauner Date: Sun, 2 Jun 2019 23:05:29 +0200 Subject: [PATCH] Initial mJS support --- .dockerignore | 1 + Makefile | 12 ++++ Makefile.conf | 2 + docker/mjs.Dockerfile | 18 ++++++ docker/scripts/build_mjs.sh | 16 ++++++ src/BUILD | 38 +++++++++++++ src/WORKSPACE | 6 ++ src/grammars/js_grammar_mjs.yaml | 66 ++++++++++++++++++++++ src/interfaces/BUILD | 13 ++++- src/interfaces/builtins.h | 4 ++ src/interfaces/builtins_mjs.h | 33 +++++++++++ src/interfaces/javascript_interface_mjs.cc | 25 ++++++++ src/mjs.BUILD | 6 ++ 13 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 docker/mjs.Dockerfile create mode 100755 docker/scripts/build_mjs.sh create mode 100644 src/grammars/js_grammar_mjs.yaml create mode 100644 src/interfaces/builtins_mjs.h create mode 100644 src/interfaces/javascript_interface_mjs.cc create mode 100644 src/mjs.BUILD diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f59ec20 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +* \ No newline at end of file diff --git a/Makefile b/Makefile index 2981adc..fbdbd6b 100644 --- a/Makefile +++ b/Makefile @@ -59,3 +59,15 @@ v8: check_folder build_base v8 \ ./fluff/docker/scripts/build_v8.sh +mjs: check_folder build_base + @echo "[*] Building mjs images" + docker build -q \ + -t mjs \ + --build-arg ver=$(MJS_VERSION) \ + -f docker/mjs.Dockerfile . + docker run \ + --rm \ + -v `pwd`:/home/build/fluff \ + mjs \ + ./fluff/docker/scripts/build_mjs.sh + diff --git a/Makefile.conf b/Makefile.conf index 3ad5b9e..77594ed 100644 --- a/Makefile.conf +++ b/Makefile.conf @@ -6,3 +6,5 @@ JERRYSCRIPT_VERSION="latest" DUKTAPE_URL="https://duktape.org/duktape-2.3.0.tar.xz" # V8 offical git url: https://github.com/v8/v8 V8_VERSION="latest" +# mjs official git repository https://github.com/cesanta/mjs +MJS_VERSION="latest" diff --git a/docker/mjs.Dockerfile b/docker/mjs.Dockerfile new file mode 100644 index 0000000..562659c --- /dev/null +++ b/docker/mjs.Dockerfile @@ -0,0 +1,18 @@ +FROM base + +ARG ver +ENV CC /home/build/afl/afl-2.52b/afl-clang + +RUN git clone https://github.com/cesanta/mjs +RUN if [ "latest" != "$ver" ]; then cd mjs && git checkout $ver; fi +RUN ln -s /usr/bin/clang-6.0 /usr/bin/clang +WORKDIR /home/build/mjs/mjs +RUN ${CC} -c -fsanitize=address -lm -std=c99 -Wall -Wextra -pedantic -g -O3 -I. -I.. -Isrc -DMJS_MAIN -DMJS_EXPOSE_PRIVATE -DCS_ENABLE_STDIO -DMJS_ENABLE_DEBUG -I../frozen -DCS_MMAP -DMJS_MODULE_LINES -Wl,--no-as-needed -ldl src/../../common/cs_dbg.c src/../../common/cs_file.c src/../../common/cs_varint.c src/../../common/mbuf.c src/../../common/mg_str.c src/../../common/str_util.c src/../../frozen/frozen.c src/ffi/ffi.c src/mjs_array.c src/mjs_bcode.c src/mjs_builtin.c src/mjs_conversion.c src/mjs_core.c src/mjs_dataview.c src/mjs_exec.c src/mjs_ffi.c src/mjs_gc.c src/mjs_json.c src/mjs_main.c src/mjs_object.c src/mjs_parser.c src/mjs_primitive.c src/mjs_string.c src/mjs_tok.c src/mjs_util.c +RUN ar -rv libmjs.a cs_dbg.o cs_file.o cs_varint.o mbuf.o mg_str.o str_util.o frozen.o ffi.o mjs_array.o mjs_bcode.o mjs_builtin.o mjs_conversion.o mjs_core.o mjs_dataview.o mjs_exec.o mjs_ffi.o mjs_gc.o mjs_json.o mjs_main.o mjs_object.o mjs_parser.o mjs_primitive.o mjs_string.o mjs_tok.o mjs_util.o + +WORKDIR /home/build/mjs/mjs/build +RUN cp ../libmjs.a . +WORKDIR /home/build/mjs/mjs/build/mjs +RUN cp /home/build/mjs/mjs.h . +WORKDIR /home/build/ +CMD [ "/bin/bash", "-c" ] \ No newline at end of file diff --git a/docker/scripts/build_mjs.sh b/docker/scripts/build_mjs.sh new file mode 100755 index 0000000..7548623 --- /dev/null +++ b/docker/scripts/build_mjs.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +echo "[*] Creating build directory" +mkdir /home/build/fluff/build +cd /home/build/fluff/src +echo "[*] Building fluff_mjs" +bazel build --show_result=0 --noshow_progress --cxxopt='-std=c++17' --cxxopt='-fsanitize=address' --test_output=errors --action_env="GTEST_COLOR=1" :fluff_mjs +if [ $? -ne 0 ]; then exit 1; fi +echo "[*] Building fluff_mjs_dry" +bazel build --show_result=0 --noshow_progress --cxxopt='-std=c++17' --cxxopt='-fsanitize=address' --test_output=errors --action_env="GTEST_COLOR=1" :fluff_mjs_dry +if [ $? -ne 0 ]; then exit 1; fi +cp /home/build/fluff/src/bazel-bin/fluff_mjs /home/build/fluff/build +cp /home/build/fluff/src/bazel-bin/fluff_mjs_dry /home/build/fluff/build +cp -R /home/build/fluff/src/grammars/js_grammar_mjs.yaml /home/build/fluff/build +echo "[!] Build successfull, all files available in build directory" +tree /home/build/fluff/build diff --git a/src/BUILD b/src/BUILD index e0cbf5b..da4734d 100644 --- a/src/BUILD +++ b/src/BUILD @@ -166,3 +166,41 @@ cc_binary( ], defines = ["FUZZ_JERRYSCRIPT"] ) + +cc_binary( + name = "fluff_mjs", + srcs = ["fluff.cc"], + linkopts = [ + "-lyaml-cpp", + "-fsanitize=address", + ], + deps = [ + "//utils:identifier_register", + "//statements:instruction", + "//interfaces:builtins", + "//interfaces:javascript_interface_mjs", + "//utils:parser", + "//utils:reader_file", + "//utils:status" + ], + defines = ["FUZZ_MJS"] +) + +cc_binary( + name = "fluff_mjs_dry", + srcs = ["fluff.cc"], + linkopts = [ + "-lyaml-cpp", + "-fsanitize=address", + ], + deps = [ + "//utils:identifier_register", + "//statements:instruction", + "//interfaces:builtins", + "//interfaces:javascript_interface_dryrun", + "//utils:parser", + "//utils:reader_file", + "//utils:status" + ], + defines = ["FUZZ_MJS"] +) diff --git a/src/WORKSPACE b/src/WORKSPACE index 0e22803..dc96fc8 100644 --- a/src/WORKSPACE +++ b/src/WORKSPACE @@ -21,3 +21,9 @@ new_local_repository( build_file = "v8.BUILD", path = "/home/build/v8/", ) + +new_local_repository( + name = "mjs", + build_file = "mjs.BUILD", + path = "/home/build/mjs/mjs/build" +) diff --git a/src/grammars/js_grammar_mjs.yaml b/src/grammars/js_grammar_mjs.yaml new file mode 100644 index 0000000..0658ee5 --- /dev/null +++ b/src/grammars/js_grammar_mjs.yaml @@ -0,0 +1,66 @@ +# mjs has a stripped down version of JS +# for more info check https://github.com/cesanta/mjs +0: + 0: LoopWhile + 1: LoopFor + 2: ConditionalIf + 3: ConditionalIfElse + 4: Return + 5: Break + 6: Continue + 7: LetDeclaration +1: + 0: Addition + 1: Subtraction + 2: Multiplication + 3: Division + 4: + 0: Integer + 1: Real + 2: Boolean + 3: String + 4: SimpleArray + 5: ENull + 5: Variable + 6: LeftShift + 7: RightShiftSigned + 8: RightShiftUnsigned + 9: BitwiseOr + 10: BitwiseXor + 11: BitwiseAnd + 12: LogicalOr + 13: LogicalNot + 14: LogicalAnd + 15: + 0: SimpleAssign + 1: AddAssign + 2: SubAssign + 3: MulAssign + 4: DivAssign + 5: ModAssign + 6: LeftShiftAssign + 7: RightShiftUnsignedAssign + 8: RightShiftSignedAssign + 9: BitwiseAndAssign + 10: BitwiseOrAssign + 11: BitwiseXorAssign + 16: FunctionApplication + 17: MethodApplication + 18: ClassFieldDotAccess + 19: ClassFieldBracketAccess + 20: PreIncrement + 21: PostIncrement + 22: PreDecrement + 23: PostDecrement + 24: FunctionDefinition + 25: ClassDefinition + 26: + 0: Greater + 1: Smaller + 2: GreaterEqual + 3: SmallerEqual + 4: Equal + 5: NotEqual + 6: EqualType + 7: NotEqualType + 27: ShortIf diff --git a/src/interfaces/BUILD b/src/interfaces/BUILD index 9ae7617..4b836c2 100644 --- a/src/interfaces/BUILD +++ b/src/interfaces/BUILD @@ -71,9 +71,20 @@ cc_library( ] ) +cc_library( + name = "javascript_interface_mjs", + srcs = ["javascript_interface_mjs.cc"], + hdrs = ["javascript_interface.h"], + deps = [ + "builtins", + "//statements:instruction", + "@mjs//:mjs_lib" + ] +) + cc_library( name = "builtins", hdrs = ["builtins.h", "builtins_chakra.h", "builtins_njs.h", "builtins_duktape.h", "builtins_espruino.h", "builtins_jerryscript.h", - "builtins_spidermonkey.h", "builtins_v8.h"] + "builtins_spidermonkey.h", "builtins_v8.h", "builtins_mjs.h"] ) diff --git a/src/interfaces/builtins.h b/src/interfaces/builtins.h index 6e55068..fef606f 100644 --- a/src/interfaces/builtins.h +++ b/src/interfaces/builtins.h @@ -25,3 +25,7 @@ #ifdef FUZZ_V8 #include "builtins_v8.h" #endif // ifdef FUZZ_V8 + +#ifdef FUZZ_MJS +#include "builtins_mjs.h" +#endif // ifdef FUZZ_MJS diff --git a/src/interfaces/builtins_mjs.h b/src/interfaces/builtins_mjs.h new file mode 100644 index 0000000..ce1f33f --- /dev/null +++ b/src/interfaces/builtins_mjs.h @@ -0,0 +1,33 @@ +#ifndef BUILTINS_H_ +#define BUILTINS_H_ +#include +namespace builtins { +const std::string functions[] = { + "load", + "print", + "ffi", + "ffi_cb_free", + "mkstr", + "getMJS", + "die", + "gc", + "chr", + "s2o", + }; +const std::string methods[] = { + "stringify", + "parse", + "create", + "isNaN", + "at", + "length", + "indexOf", + "slice", + "splice", + "push", + "apply" + }; +const std::string variables[] = {"global", "Object", "JSON"}; +}; // namespace builtins + +#endif // ifndef BUILTINS_H_ \ No newline at end of file diff --git a/src/interfaces/javascript_interface_mjs.cc b/src/interfaces/javascript_interface_mjs.cc new file mode 100644 index 0000000..5768050 --- /dev/null +++ b/src/interfaces/javascript_interface_mjs.cc @@ -0,0 +1,25 @@ +#include +#include "mjs/mjs.h" +#include +#include + +#include "javascript_interface.h" + +using std::string; +using std::unique_ptr; +using std::vector; + +static struct mjs *mjs; + +void JavascriptInterface::Init(const char* exeuction_path) { + mjs = mjs_create(); +} + +void JavascriptInterface::Execute( + const vector>& instructions) { + string code; + for (const auto& instr : instructions) { + code += instr->Emit() + ";\n"; + } + mjs_exec(mjs, code.c_str(), NULL); +} diff --git a/src/mjs.BUILD b/src/mjs.BUILD new file mode 100644 index 0000000..552a5c8 --- /dev/null +++ b/src/mjs.BUILD @@ -0,0 +1,6 @@ +cc_import( + name = "mjs_lib", + static_library = "libmjs.a", + hdrs = glob(["mjs/*.h"]), + visibility = ["//visibility:public"], +) \ No newline at end of file