diff --git a/CHANGELOG.md b/CHANGELOG.md index 95e073e..7fab6ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,4 +68,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Add Fuzzer extra params support ## 20230320 -- Support for context generation \ No newline at end of file +- Support for context generation + +## 20230305 +- Fix error python in Builder +- Fix error python in Generator for wchar_t string \ No newline at end of file diff --git a/README.en.md b/README.en.md index a011729..89d011e 100644 --- a/README.en.md +++ b/README.en.md @@ -30,7 +30,7 @@ Additionally, Futag provides the ability to test compiled targets. You can try to build Futag with pre-built [Docker files](https://github.com/ispras/Futag/tree/main/product-tests/build-test) for Ubuntu OS. ### 2.2. Using a prepackaged package -Download the latest [futag-llvm.2.0.0.tar.xz](https://github.com/ispras/Futag/releases/tag/2.0.0) and unzip +Download the latest [futag-llvm.2.0.1.tar.xz](https://github.com/ispras/Futag/releases/tag/2.0.0) and unzip ### 2.3. Building and installing from source diff --git a/README.md b/README.md index b31be76..8f8bf3c 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ FUTAG использует, в качестве внешнего интерф Вы можете попробовать собрать Futag с готовыми [Докер-файлами](https://github.com/ispras/Futag/tree/main/product-tests/build-test) для ОС Ubuntu. ## 2.2. Использование предварительно упакованного пакета -- Загрузите последнюю версию [futag-llvm.2.0.0.tar.xz](https://github.com/ispras/Futag/releases/tag/2.0.0) и разархивируйте. +- Загрузите последнюю версию [futag-llvm.2.0.1.tar.xz](https://github.com/ispras/Futag/releases/tag/2.0.0) и разархивируйте. ## 2.3. Сборка и установка из исходного кода @@ -82,8 +82,9 @@ FUTAG использует, в качестве внешнего интерф - Предварительно должен быть установлен пакет futag-<версия>.tar.gz по пути futag-llvm/python-package/: ```bash ~$ pip install -r futag-llvm/python-package/requirements.txt - ~$ pip install futag-llvm/python-package/futag-2.0.0.tar.gz + ~$ pip install futag-llvm/python-package/futag-2.0.1.tar.gz ``` +- Для того, чтобы Futag генерировал фаззинг-обертки в формате AFLplusplus необходимо запустить скрипт futag-llvm/export.sh ### 3.1. Автоматическая генерация фаззинг-оберток в условии отсутствия контекстов использования - Запуск сборки, проверки и анализа в условии отсутствия контекстов использования @@ -184,6 +185,7 @@ context_generator.compile_targets( #компиляция сгенерирова ## 5. Статьи и материалы - C. T. Tran and S. Kurmangaleev, ["Futag: Automated fuzz target generator for testing software libraries"](https://ieeexplore.ieee.org/document/9693749) 2021 Ivannikov Memorial Workshop (IVMEM), 2021, pp. 80-85, doi: 10.1109/IVMEM53963.2021.00021. +- C. T. Tran, D. Ponomarev and A. Kuznhesov, ["Research on automatic generation of fuzz-target for software library functions"](https://ieeexplore.ieee.org/document/10076871), 2022 Ivannikov Ispras Open Conference (ISPRAS), Moscow, Russian Federation, 2022, pp. 95-99, doi: 10.1109/ISPRAS57371.2022.10076871. - Исследования по автоматической генерации фаззинг-оберток для функций библиотек, Открытая конференция ИСП РАН им. В.П. Иванникова 2022 diff --git a/custom-llvm/build.sh b/custom-llvm/build.sh index 894ccae..ad9308c 100755 --- a/custom-llvm/build.sh +++ b/custom-llvm/build.sh @@ -1,6 +1,6 @@ #!/bin/bash -#===-- build.bash -------*- bash script -*-===// +#===-- build.sh -------*- bash script -*-===// # # This file is distributed under the GPL v3 license (https://www.gnu.org/licenses/gpl-3.0.en.html). # diff --git a/custom-llvm/buildwAFLplusplus.sh b/custom-llvm/buildwAFLplusplus.sh index faf7c59..7dd3102 100755 --- a/custom-llvm/buildwAFLplusplus.sh +++ b/custom-llvm/buildwAFLplusplus.sh @@ -1,6 +1,6 @@ #!/bin/bash -#===-- build.bash -------*- bash script -*-===// +#===-- build.sh -------*- bash script -*-===// # # This file is distributed under the GPL v3 license (https://www.gnu.org/licenses/gpl-3.0.en.html). # @@ -55,11 +55,11 @@ cp $futag_src/Checkers/lib/*.cpp $custom_llvm/clang/lib/StaticAnalyzer/Checkers/ cp -r $futag_src/Checkers/lib/$CheckerCMakeLists $custom_llvm/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt if [ $llvmVersion == "LLVM=14.0.6" ]; then - cmake -G "Unix Makefiles" -DLLVM_BUILD_TESTS=OFF -DLLVM_ENABLE_ZLIB=OFF -DCMAKE_BUILD_TYPE=Release -DLLVM_BINUTILS_INCDIR=/usr/include/ -DCMAKE_INSTALL_PREFIX=$futag_install_folder -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCLANG_INCLUDE_DOCS="OFF" -DLLVM_BUILD_LLVM_DYLIB="ON" -DLLVM_ENABLE_BINDINGS="OFF" -DLLVM_ENABLE_PROJECTS='clang;' -DLLVM_ENABLE_WARNINGS="OFF" -DLLVM_INCLUDE_BENCHMARKS="OFF" -DLLVM_INCLUDE_DOCS="OFF" -DLLVM_INCLUDE_EXAMPLES="OFF" -DLLVM_INCLUDE_TESTS="OFF" -DLLVM_LINK_LLVM_DYLIB="ON" -DLLVM_TARGETS_TO_BUILD="host" -DLLVM_ENABLE_RUNTIMES="compiler-rt;" $custom_llvm/llvm + cmake -G "Unix Makefiles" -DLLVM_BUILD_TESTS=OFF -DLLVM_ENABLE_ZLIB=ON -DCMAKE_BUILD_TYPE=Release -DLLVM_BINUTILS_INCDIR=/usr/include/ -DCMAKE_INSTALL_PREFIX=$futag_install_folder -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCLANG_INCLUDE_DOCS="OFF" -DLLVM_BUILD_LLVM_DYLIB="ON" -DLLVM_ENABLE_BINDINGS="OFF" -DLLVM_ENABLE_PROJECTS='clang;' -DLLVM_ENABLE_WARNINGS="OFF" -DLLVM_INCLUDE_BENCHMARKS="OFF" -DLLVM_INCLUDE_DOCS="OFF" -DLLVM_INCLUDE_EXAMPLES="OFF" -DLLVM_INCLUDE_TESTS="OFF" -DLLVM_LINK_LLVM_DYLIB="ON" -DLLVM_TARGETS_TO_BUILD="host" -DLLVM_ENABLE_RUNTIMES="compiler-rt;" $custom_llvm/llvm fi if [ $llvmVersion == "LLVM=13.0.1" ]; then - cmake -G "Unix Makefiles" -DLLVM_BUILD_TESTS=OFF -DLLVM_ENABLE_ZLIB=OFF -DCMAKE_BUILD_TYPE=Release -DLLVM_BINUTILS_INCDIR=/usr/include/ -DCMAKE_INSTALL_PREFIX=$futag_install_folder -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCLANG_INCLUDE_DOCS="OFF" -DLLVM_BUILD_LLVM_DYLIB="ON" -DLLVM_ENABLE_BINDINGS="OFF" -DLLVM_ENABLE_PROJECTS='clang;compiler-rt;' -DLLVM_ENABLE_WARNINGS="OFF" -DLLVM_INCLUDE_BENCHMARKS="OFF" -DLLVM_INCLUDE_DOCS="OFF" -DLLVM_INCLUDE_EXAMPLES="OFF" -DLLVM_INCLUDE_TESTS="OFF" -DLLVM_LINK_LLVM_DYLIB="ON" -DLLVM_TARGETS_TO_BUILD="host" $custom_llvm/llvm + cmake -G "Unix Makefiles" -DLLVM_BUILD_TESTS=OFF -DLLVM_ENABLE_ZLIB=ON -DCMAKE_BUILD_TYPE=Release -DLLVM_BINUTILS_INCDIR=/usr/include/ -DCMAKE_INSTALL_PREFIX=$futag_install_folder -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCLANG_INCLUDE_DOCS="OFF" -DLLVM_BUILD_LLVM_DYLIB="ON" -DLLVM_ENABLE_BINDINGS="OFF" -DLLVM_ENABLE_PROJECTS='clang;compiler-rt;' -DLLVM_ENABLE_WARNINGS="OFF" -DLLVM_INCLUDE_BENCHMARKS="OFF" -DLLVM_INCLUDE_DOCS="OFF" -DLLVM_INCLUDE_EXAMPLES="OFF" -DLLVM_INCLUDE_TESTS="OFF" -DLLVM_LINK_LLVM_DYLIB="ON" -DLLVM_TARGETS_TO_BUILD="host" $custom_llvm/llvm fi make -j$(($(nproc)/2)) && make -j$(($(nproc)/2)) install @@ -86,6 +86,7 @@ cp -r $futag_src/svres-tmpl $futag_install_folder/ cp -r ../*.md $futag_install_folder/ cp -r ../LICENSE $futag_install_folder/ cp $custom_prepare/INFO $futag_install_folder/ +cp $custom_prepare/export.sh $futag_install_folder/ git rev-parse HEAD >> $futag_install_folder/INFO cd ../product-tests diff --git a/custom-llvm/export.sh b/custom-llvm/export.sh new file mode 100755 index 0000000..36c41a0 --- /dev/null +++ b/custom-llvm/export.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +#===-- export.sh -------*- bash script -*-===// +# +# This file is distributed under the GPL v3 license (https://www.gnu.org/licenses/gpl-3.0.en.html). +# +# This script helps to build llvm with clang and compiler-rt + +echo "************************************************" +echo "* ______ __ __ ______ ___ ______ *" +echo "* / ____/ / / / / /_ __/ / | / ____/ *" +echo "* / /_ / / / / / / / /| | / / __ *" +echo "* / __/ / /_/ / / / / ___ | / /_/ / *" +echo "* /_/ \____/ /_/ /_/ |_| \____/ *" +echo "* *" +echo "* Fuzzing target Automated Generator *" +echo "* a tool of ISP RAS *" +echo "************************************************" +echo "" + +SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +echo "Exporting Futag path for AFLplusplus: "$SCRIPTPATH +echo "" +set -x +export PATH="$SCRIPTPATH/bin:$PATH" +export LLVM_CONFIG="$SCRIPTPATH/bin/llvm-config" +export LD_LIBRARY_PATH="$(llvm-config --libdir)${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" diff --git a/product-tests/build-test/ubuntu20/Docker-test-build.Dockerfile b/product-tests/build-test/ubuntu20/Docker-test-build.Dockerfile index 8cd7f1d..e263a73 100644 --- a/product-tests/build-test/ubuntu20/Docker-test-build.Dockerfile +++ b/product-tests/build-test/ubuntu20/Docker-test-build.Dockerfile @@ -24,7 +24,7 @@ RUN ./build.sh USER root WORKDIR /home/futag/Futag/ -RUN pip install futag-llvm/python-package/futag-2.0.0.tar.gz +RUN pip install futag-llvm/python-package/futag-2.0.1.tar.gz RUN pip install -r futag-llvm/python-package/requirements.txt USER futag diff --git a/product-tests/build-test/ubuntu22/Docker-test-build.Dockerfile b/product-tests/build-test/ubuntu22/Docker-test-build.Dockerfile index 1b11df0..4a8ce27 100644 --- a/product-tests/build-test/ubuntu22/Docker-test-build.Dockerfile +++ b/product-tests/build-test/ubuntu22/Docker-test-build.Dockerfile @@ -20,7 +20,7 @@ RUN ./build.sh USER root WORKDIR /home/futag/Futag/ -RUN pip install futag-llvm/python-package/futag-2.0.0.tar.gz +RUN pip install futag-llvm/python-package/futag-2.0.1.tar.gz USER futag WORKDIR /home/futag/Futag/ diff --git a/product-tests/libraries-test/ubuntu20/Docker-test-libs.Dockerfile b/product-tests/libraries-test/ubuntu20/Docker-test-libs.Dockerfile index bac6c4b..872e259 100644 --- a/product-tests/libraries-test/ubuntu20/Docker-test-libs.Dockerfile +++ b/product-tests/libraries-test/ubuntu20/Docker-test-libs.Dockerfile @@ -22,7 +22,7 @@ WORKDIR /home/futag/Futag-tests RUN ./get-Futag.sh USER root -RUN pip install futag-llvm/python-package/futag-2.0.0.tar.gz +RUN pip install futag-llvm/python-package/futag-2.0.1.tar.gz RUN pip install -r futag-llvm/python-package/requirements.txt USER futag diff --git a/product-tests/libraries-test/ubuntu22/Docker-test-libs.Dockerfile b/product-tests/libraries-test/ubuntu22/Docker-test-libs.Dockerfile index bd049cf..13c183e 100644 --- a/product-tests/libraries-test/ubuntu22/Docker-test-libs.Dockerfile +++ b/product-tests/libraries-test/ubuntu22/Docker-test-libs.Dockerfile @@ -19,7 +19,7 @@ RUN ./get-Futag.sh USER root WORKDIR /home/futag/Futag/ -RUN pip install futag-llvm/python-package/futag-2.0.0.tar.gz +RUN pip install futag-llvm/python-package/futag-2.0.1.tar.gz RUN pip install -r futag-llvm/python-package/requirements.txt USER futag diff --git a/product-tests/package-test/ubuntu20/Docker-test-package.Dockerfile b/product-tests/package-test/ubuntu20/Docker-test-package.Dockerfile index b21ea4a..3ff6074 100644 --- a/product-tests/package-test/ubuntu20/Docker-test-package.Dockerfile +++ b/product-tests/package-test/ubuntu20/Docker-test-package.Dockerfile @@ -20,7 +20,7 @@ ADD futag-llvm.latest.tar.xz /home/futag/Futag/ USER root WORKDIR /home/futag/Futag/ -RUN pip install futag-llvm/python-package/futag-2.0.0.tar.gz +RUN pip install futag-llvm/python-package/futag-2.0.1.tar.gz RUN pip install -r futag-llvm/python-package/requirements.txt USER futag diff --git a/product-tests/package-test/ubuntu22/Docker-test-package.Dockerfile b/product-tests/package-test/ubuntu22/Docker-test-package.Dockerfile index 68c0bcb..1c48ad3 100644 --- a/product-tests/package-test/ubuntu22/Docker-test-package.Dockerfile +++ b/product-tests/package-test/ubuntu22/Docker-test-package.Dockerfile @@ -17,7 +17,7 @@ ADD futag-llvm.latest.tar.xz /home/futag/Futag USER root WORKDIR /home/futag/Futag/ -RUN pip install futag-llvm/python-package/futag-2.0.0.tar.gz +RUN pip install futag-llvm/python-package/futag-2.0.1.tar.gz RUN pip install -r futag-llvm/python-package/requirements.txt USER futag diff --git a/src/clang/include/Futag/Basic.h b/src/clang/include/Futag/Basic.h index 136ff65..e46a063 100755 --- a/src/clang/include/Futag/Basic.h +++ b/src/clang/include/Futag/Basic.h @@ -126,22 +126,23 @@ typedef enum { typedef enum { F_BUILTIN, // 0: All basic types: int, float, double,... F_CSTRING, // 1: char *, const char * - F_CXXSTRING, // 2: char *, const char * - F_ENUM, // 3 - F_ARRAY, // 4 - F_VOIDP, // 5 - F_QUALIFIER, // 6: const, volatile, and restrict qualifiers - F_POINTER, // 7 - F_STRUCT, // 8 - F_UNION, // 9 - F_CLASS, // 10 - F_INCOMPLETE, // 11 - F_FUNCTION, // 12 - F_INPUT_CXXFILE, // 13 - F_OUTPUT_CXXFILE, // 14 - F_CXXFILE, // 15 - F_CFILE, // 16 - F_UNKNOWN, // 17 + F_WSTRING, // 2: char *, const char * + F_CXXSTRING, // 3: char *, const char * + F_ENUM, // 4 + F_ARRAY, // 5 + F_VOIDP, // 6 + F_QUALIFIER, // 7: const, volatile, and restrict qualifiers + F_POINTER, // 8 + F_STRUCT, // 9 + F_UNION, // 10 + F_CLASS, // 11 + F_INCOMPLETE, // 12 + F_FUNCTION, // 13 + F_INPUT_CXXFILE, // 14 + F_OUTPUT_CXXFILE, // 15 + F_CXXFILE, // 16 + F_CFILE, // 17 + F_UNKNOWN, // 18 } FutagGenType; typedef struct { diff --git a/src/clang/lib/Futag/Basic.cpp b/src/clang/lib/Futag/Basic.cpp index 4dd4d97..aec2bb6 100755 --- a/src/clang/lib/Futag/Basic.cpp +++ b/src/clang/lib/Futag/Basic.cpp @@ -13,8 +13,8 @@ * a tool of ISP RAS * ************************************************ * - * @version 1.3.1 - * @date 2023-01-29 + * @version 2.0.1 + * @date 2023-04-05 * * @copyright This file is distributed under the GPL v3 license * @@ -400,11 +400,13 @@ vector getGenType(QualType type) { if (std::find(str_types.begin(), str_types.end(), type.getCanonicalType().getAsString()) != str_types.end()) { + gen_list.gen_type = FutagGenType::F_CSTRING; gen_list.base_type_name = "char *"; if (std::find(wchar_str_types.begin(), wchar_str_types.end(), type.getCanonicalType().getAsString()) != wchar_str_types.end()) { gen_list.base_type_name = "wchar_t *"; + gen_list.gen_type = FutagGenType::F_WSTRING; } if (std::find(const_str_types.begin(), const_str_types.end(), type.getCanonicalType().getAsString()) != @@ -416,9 +418,10 @@ vector getGenType(QualType type) { if (canonical_type.getAsString() == "const wchar_t *" || canonical_type.getAsString() == "const wchar_t *const") { gen_list.base_type_name = "wchar_t *"; + gen_list.gen_type = FutagGenType::F_WSTRING; } } - gen_list.gen_type = FutagGenType::F_CSTRING; + result.insert(result.begin(), gen_list); return result; } @@ -584,6 +587,10 @@ std::string GetFutagGenTypeFromIdx(FutagGenType idx) { return "_CSTRING"; break; + case FutagGenType::F_WSTRING: + return "_WSTRING"; + break; + case FutagGenType::F_CXXSTRING: return "_CXXSTRING"; break; diff --git a/src/clang/lib/Futag/ConsumerFinder.cpp b/src/clang/lib/Futag/ConsumerFinder.cpp index 217dc0e..c54a3ff 100644 --- a/src/clang/lib/Futag/ConsumerFinder.cpp +++ b/src/clang/lib/Futag/ConsumerFinder.cpp @@ -311,7 +311,9 @@ void SearchVarDeclInBlock( futag::FutagPath &curr_analyzed_path, // for checking reverse match std::vector &init_calls, const json &analysis_jdb) { + MatchFinder Finder; + const auto matched_binaryoperator = binaryOperator( isAssignmentOperator(), @@ -321,6 +323,7 @@ void SearchVarDeclInBlock( declRefExpr(to(functionDecl().bind("DefTargetFunctionCall"))) .bind("DefDeclRefExpr")))) .bind("DefFutagBinOpArg"); + const auto matched_vardecl = varDecl(hasName(iter_arg.value), hasDescendant(declRefExpr(to(functionDecl().bind( diff --git a/src/python/futag-package/README.md b/src/python/futag-package/README.md index ffd5dba..56a05c5 100644 --- a/src/python/futag-package/README.md +++ b/src/python/futag-package/README.md @@ -20,7 +20,7 @@ This python package is for building library, generating and compiling fuzz-drive ## 1. Install ```bash -pip install dist/futag-1.3.1.tar.gz +pip install dist/futag-2.0.1.tar.gz ``` ## 2. Preprocessor diff --git a/src/python/futag-package/dist/futag-2.0.1-py3-none-any.whl b/src/python/futag-package/dist/futag-2.0.1-py3-none-any.whl new file mode 100644 index 0000000..71f345c Binary files /dev/null and b/src/python/futag-package/dist/futag-2.0.1-py3-none-any.whl differ diff --git a/src/python/futag-package/dist/futag-2.0.1.tar.gz b/src/python/futag-package/dist/futag-2.0.1.tar.gz new file mode 100644 index 0000000..5b448c4 Binary files /dev/null and b/src/python/futag-package/dist/futag-2.0.1.tar.gz differ diff --git a/src/python/futag-package/setup.cfg b/src/python/futag-package/setup.cfg index 111613d..a94299a 100644 --- a/src/python/futag-package/setup.cfg +++ b/src/python/futag-package/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = futag -version = 2.0.0 +version = 2.0.1 author = Futag-team of ISP RAS author_email = thientcgithub@gmail.com description = Python package of Futag diff --git a/src/python/futag-package/setup.py b/src/python/futag-package/setup.py index 78d0f65..05edb58 100644 --- a/src/python/futag-package/setup.py +++ b/src/python/futag-package/setup.py @@ -2,7 +2,7 @@ setup( name='futag', - version='2.0.0', + version='2.0.1', author='Futag-team of ISP RAS', author_email='thientcgithub@gmail.com', packages=['futag'], diff --git a/src/python/futag-package/src/futag.egg-info/PKG-INFO b/src/python/futag-package/src/futag.egg-info/PKG-INFO index ebcfc44..f3fd15b 100644 --- a/src/python/futag-package/src/futag.egg-info/PKG-INFO +++ b/src/python/futag-package/src/futag.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: futag -Version: 2.0.0 +Version: 2.0.1 Summary: Futag tools for creating fuzz targets of software library Home-page: https://github.com/ispras/Futag/tree/main/src/python/futag-package Author: Futag-team of ISP RAS @@ -36,7 +36,7 @@ This python package is for building library, generating and compiling fuzz-drive ## 1. Install ```bash -pip install dist/futag-1.3.1.tar.gz +pip install dist/futag-2.0.1.tar.gz ``` ## 2. Preprocessor diff --git a/src/python/futag-package/src/futag/fuzzer.py b/src/python/futag-package/src/futag/fuzzer.py index 4caa7aa..13934e1 100644 --- a/src/python/futag-package/src/futag/fuzzer.py +++ b/src/python/futag-package/src/futag/fuzzer.py @@ -582,10 +582,9 @@ def fuzz(self, extra_param: str = ""): for x in [t for t in dir.glob("*.out") if t.is_file()]: print("\n-- [Futag] FUZZING driver: " + x.stem + "... \n") my_env = os.environ.copy() - if self.leak: - my_env["ASAN_OPTIONS"] = "allocator_may_return_null=1" - else: - my_env["ASAN_OPTIONS"] = "detect_leaks=0:allocator_may_return_null=1" + if not self.leak: + my_env["ASAN_OPTIONS"] = "detect_leaks=0" + my_env["ASAN_SYMBOLIZER_PATH"] = symbolizer.as_posix() if self.coverage: my_env["LLVM_PROFILE_FILE"] = x.as_posix() + ".profraw" diff --git a/src/python/futag-package/src/futag/generator.py b/src/python/futag-package/src/futag/generator.py index 730e4bd..6bafd9a 100644 --- a/src/python/futag-package/src/futag/generator.py +++ b/src/python/futag-package/src/futag/generator.py @@ -64,7 +64,9 @@ def __init__(self, futag_llvm_package: str, library_root: str, target_type: int self.gen_lines = [] self.buffer_size = [] self.gen_free = [] - self.dyn_size_idx = 0 + self.dyn_cstring_size_idx = 0 + self.dyn_cxxstring_size_idx = 0 + self.dyn_wstring_size_idx = 0 self.file_idx = 0 self.curr_function = None self.curr_func_log = "" @@ -221,9 +223,47 @@ def __gen_header(self, target_function_name): include_lines.append("#include " + i + "\n") if self.header: for i in self.header: - include_lines.append("#include " + i + "\n") + if i not in included_headers: + include_lines.append("#include " + i + "\n") return include_lines + def __get_function_header(self, func_location): + """ Generate header for the target function + + Args: + func_location (string): function location. + + Returns: + list: list of included header. + """ + defaults = ["stdio.h", "stddef.h", "time.h", + "stdlib.h", "string.h", "stdint.h"] + compiled_files = self.target_library["compiled_files"] + included_headers = [] + found = False + for f in compiled_files: + if f["filename"] == func_location: + found = True + for header in f["headers"]: + if not header[1:-1] in defaults: + included_headers.append(header) + break + if not found: + short_filename = func_location.split('/')[-1] + for f in compiled_files: + if f["filename"].split('/')[-1] == short_filename: + found = True + for header in f["headers"]: + if not header[1:-1] in defaults: + included_headers.append(header) + break + return included_headers + + def __add_header(self, function_headers): + for h in function_headers: + if h not in self.header: + self.header.append(h) + def __gen_builtin(self, param_name, gen_type_info): """Declare and assign value for a builtin type @@ -238,33 +278,33 @@ def __gen_builtin(self, param_name, gen_type_info): "gen_lines": [ "//GEN_BUILTIN\n", gen_type_info["type_name"] + " " + param_name + ";\n", - "memcpy(&"+param_name+", pos, sizeof(" + + "memcpy(&"+param_name+", futag_pos, sizeof(" + gen_type_info["type_name"] + "));\n", - "pos += sizeof(" + gen_type_info["type_name"] + ");\n" + "futag_pos += sizeof(" + gen_type_info["type_name"] + ");\n" ], "gen_free": [], "buffer_size": ["sizeof(" + gen_type_info["type_name"]+")"] } - def __gen_strsize(self, param_name, param_type, dyn_size_idx): + def __gen_strsize(self, param_name, param_type, dyn_size_idx, array_name): return { "gen_lines": [ "//GEN_SIZE\n", param_type + " " + param_name + " = (" + param_type + - ") dyn_size[" + str(dyn_size_idx - 1) + "];\n", + ") " + array_name + "[" + str(dyn_size_idx - 1) + "];\n", ], "gen_free": [], "buffer_size": [] } - def __gen_cstring(self, param_name, gen_type_info, dyn_size_idx): + def __gen_cstring(self, param_name, gen_type_info, dyn_cstring_size_idx): """Declare and assign value for a C string type Args: param_name (str): parameter's name gen_type_info (dict): information of parameter's type - dyn_size_idx (int): id of dynamic size + dyn_cstring_size_idx (int): id of dynamic cstring size Returns: dict: (gen_lines, gen_free, buffer_size) @@ -272,24 +312,58 @@ def __gen_cstring(self, param_name, gen_type_info, dyn_size_idx): ref_name = param_name if (gen_type_info["local_qualifier"]): ref_name = "r" + ref_name - sizeof = "" - malloc = gen_type_info["base_type_name"] + " " + ref_name + \ - " = (" + gen_type_info["base_type_name"] + \ - ") malloc(dyn_size[" + str(dyn_size_idx - 1) + "] + 1);\n" - if "wchar_t" in gen_type_info["base_type_name"]: - malloc = gen_type_info["base_type_name"] + " " + ref_name + \ - " = (" + gen_type_info["base_type_name"] + \ - ") malloc(sizeof(wchar_t)*dyn_size[" + \ - str(dyn_size_idx - 1) + "] + 1);\n" gen_lines = [ "//GEN_CSTRING\n", - malloc, + gen_type_info["base_type_name"] + " " + ref_name + \ + " = (" + gen_type_info["base_type_name"] + \ + ") malloc((dyn_cstring_size[" + str(dyn_cstring_size_idx - 1) + "] + 1)* sizeof(char));\n", + "memset(" + ref_name + + ", 0, dyn_cstring_size[" + str(dyn_cstring_size_idx - 1) + "] + 1);\n", + "memcpy(" + ref_name + + ", futag_pos, dyn_cstring_size[" + str(dyn_cstring_size_idx - 1) + "]);\n", + "futag_pos += dyn_cstring_size[" + str(dyn_cstring_size_idx - 1) + "];\n", + ] + if (gen_type_info["local_qualifier"]): + gen_lines += [gen_type_info["type_name"] + + " " + param_name + " = " + ref_name + ";\n"] + + return { + "gen_lines": gen_lines, + "gen_free": [ + "if (" + ref_name + ") {\n", + " free(" + ref_name + ");\n", + " " + ref_name + " = NULL;\n", + "}\n" + ], + "buffer_size": [] + } + + def __gen_wstring(self, param_name, gen_type_info, dyn_wstring_size_idx): + """Declare and assign value for a C string type + + Args: + param_name (str): parameter's name + gen_type_info (dict): information of parameter's type + dyn_wstring_size_idx (int): id of dynamic wstring size + + Returns: + dict: (gen_lines, gen_free, buffer_size) + """ + ref_name = param_name + if (gen_type_info["local_qualifier"]): + ref_name = "r" + ref_name + + gen_lines = [ + "//GEN_WSTRING\n", + gen_type_info["base_type_name"] + " " + ref_name + \ + " = (" + gen_type_info["base_type_name"] + \ + ") malloc((dyn_wstring_size[" + str(dyn_wstring_size_idx - 1) + "] + 1)* sizeof(wchar_t));\n", "memset(" + ref_name + - ", 0, dyn_size[" + str(dyn_size_idx - 1) + "] + 1);\n", + ", 0, (dyn_wstring_size[" + str(dyn_wstring_size_idx - 1) + "] + 1)* sizeof(wchar_t));\n", "memcpy(" + ref_name + - ", pos, dyn_size[" + str(dyn_size_idx - 1) + "] );\n", - "pos += dyn_size[" + str(dyn_size_idx - 1) + "];\n", + ", futag_pos, dyn_wstring_size[" + str(dyn_wstring_size_idx - 1) + "]* sizeof(wchar_t)]);\n", + "futag_pos += dyn_wstring_size[" + str(dyn_wstring_size_idx - 1) + "]* sizeof(wchar_t)];\n", ] if (gen_type_info["local_qualifier"]): gen_lines += [gen_type_info["type_name"] + @@ -306,7 +380,7 @@ def __gen_cstring(self, param_name, gen_type_info, dyn_size_idx): "buffer_size": [] } - def __gen_cxxstring(self, param_name, gen_type_info, dyn_size_idx): + def __gen_cxxstring(self, param_name, gen_type_info, dyn_cxxstring_size_idx): """Declare and assign value for a C++ string type Args: @@ -329,8 +403,8 @@ def __gen_cxxstring(self, param_name, gen_type_info, dyn_size_idx): return { "gen_lines": [ gen_type_info["type_name"] + " " + param_name + - "(pos, dyn_size[" + str(dyn_size_idx - 1) + "]); \n", - "pos += dyn_size[" + str(dyn_size_idx - 1) + "];\n", + "(futag_pos, dyn_cxxstring_size[" + str(dyn_cxxstring_size_idx - 1) + "]); \n", + "futag_pos += dyn_cxxstring_size[" + str(dyn_cxxstring_size_idx - 1) + "];\n", ], "gen_free": [], "buffer_size": [] @@ -351,7 +425,7 @@ def __gen_enum(self, enum_record, param_name, gen_type_info, compiler_info, anon "//GEN_ENUM\n", "unsigned int " + param_name + "_enum_index; \n", "memcpy(&" + param_name + - "_enum_index, pos, sizeof(unsigned int));\n", + "_enum_index, futag_pos, sizeof(unsigned int));\n", enum_name + " " + param_name + " = " + param_name + "_enum_index % " + str(enum_length) + ";\n" @@ -365,7 +439,7 @@ def __gen_enum(self, enum_record, param_name, gen_type_info, compiler_info, anon "//GEN_ENUM\n", "unsigned int " + param_name + "_enum_index; \n", "memcpy(&" + param_name + - "_enum_index, pos, sizeof(unsigned int));\n", + "_enum_index, futag_pos, sizeof(unsigned int));\n", # "enum " + enum_name + " " + param_name + " = static_cast(" + param_name + "_enum_index % " + str(enum_length) + ");\n" @@ -381,9 +455,9 @@ def __gen_array(self, param_name, gen_type_info): gen_type_info["type_name"] + " " + param_name + " = (" + gen_type_info["type_name"] + ") " + "malloc(sizeof(" + gen_type_info["base_type_name"] + ") * " + str(gen_type_info["length"]) + ");\n", - "memcpy(" + param_name + ", pos, " + str( + "memcpy(" + param_name + ", futag_pos, " + str( gen_type_info["length"]) + " * sizeof(" + gen_type_info["base_type_name"] + "));\n", - "pos += " + + "futag_pos += " + str(gen_type_info["length"]) + " * sizeof(" + gen_type_info["base_type_name"] + ");\n" ], @@ -439,11 +513,22 @@ def __gen_struct(self, struct_name, struct, gen_info): for gen_type_info in field["gen_list"]: this_gen_size = False if gen_type_info["gen_type"] == GEN_BUILTIN: - if field_id > 0 and (struct["fields"][field_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_CXXSTRING]): + if field_id > 0 and (struct["fields"][field_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_WSTRING, GEN_CXXSTRING]): if gen_type_info["type_name"] in ["size_t", "unsigned char", "char", "int", "unsigned", "unsigned int", "short", "unsigned short", "short int", "unsigned short int"]: + dyn_size_idx = 0 + array_name = "" + if struct["fields"][field_id - 1]["gen_list"][0]["gen_type"] == GEN_CSTRING: + dyn_size_idx = self.dyn_cstring_size_idx + array_name = "dyn_cstring_size" + elif struct["fields"][field_id - 1]["gen_list"][0]["gen_type"] == GEN_WSTRING: + dyn_size_idx = self.dyn_wstring_size_idx + array_name = "dyn_wstring_size" + else: + dyn_size_idx = self.dyn_cxxstring_size_idx + array_name = "dyn_cxxstring_size" curr_name = "sz_" + curr_name # size_prefix curr_gen = self.__gen_strsize( - curr_name, gen_type_info["type_name"], self.dyn_size_idx) + curr_name, gen_type_info["type_name"], dyn_size_idx, array_name) buffer_size += curr_gen["buffer_size"] gen_lines += curr_gen["gen_lines"] gen_free += curr_gen["gen_free"] @@ -459,18 +544,27 @@ def __gen_struct(self, struct_name, struct, gen_info): if gen_type_info["gen_type"] == GEN_CSTRING: curr_name = "strc_" + curr_name # string_prefix - self.dyn_size_idx += 1 + self.dyn_cstring_size_idx += 1 curr_gen = self.__gen_cstring( - curr_name, gen_type_info, self.dyn_size_idx) + curr_name, gen_type_info, self.dyn_cstring_size_idx) + buffer_size += curr_gen["buffer_size"] + gen_lines += curr_gen["gen_lines"] + gen_free += curr_gen["gen_free"] + + if gen_type_info["gen_type"] == GEN_WSTRING: + curr_name = "strc_" + curr_name # string_prefix + self.dyn_wstring_size_idx += 1 + curr_gen = self.__gen_wstring( + curr_name, gen_type_info, self.dyn_wstring_size_idx) buffer_size += curr_gen["buffer_size"] gen_lines += curr_gen["gen_lines"] gen_free += curr_gen["gen_free"] if gen_type_info["gen_type"] == GEN_CXXSTRING: curr_name = "strcxx_" + curr_name # string_prefix - self.dyn_size_idx += 1 + self.dyn_cxxstring_size_idx += 1 curr_gen = self.__gen_cxxstring( - curr_name, gen_type_info, self.dyn_size_idx) + curr_name, gen_type_info, self.dyn_cxxstring_size_idx) buffer_size += curr_gen["buffer_size"] gen_lines += curr_gen["gen_lines"] gen_free += curr_gen["gen_free"] @@ -558,9 +652,9 @@ def __gen_union(self, param_name, class_record, gen_type_info): "gen_lines": [ "//GEN_UNION\n", gen_type_info["type_name"] + " " + param_name + ";\n", - "memcpy(&"+param_name+", pos, sizeof(" + + "memcpy(&"+param_name+", futag_pos, sizeof(" + gen_type_info["type_name"] + "));\n", - "pos += sizeof(" + gen_type_info["type_name"] + ");\n" + "futag_pos += sizeof(" + gen_type_info["type_name"] + ");\n" ], "gen_free": [], "buffer_size": ["sizeof(" + gen_type_info["type_name"] + ")"] @@ -589,10 +683,19 @@ def __gen_class(self, param_name, class_record): def __gen_input_file(self, param_name, gen_type_info): cur_gen_free = [" " + x for x in self.gen_free] + if gen_type_info["gen_type"] == GEN_CSTRING: + line = "const char* " + param_name + " = \"futag_input_file_" + str(self.file_idx - 1) + "\";\n" + elif gen_type_info["gen_type"] == GEN_WSTRING: + line = "const wchar_t * " + param_name + " = L\"futag_input_file_" + str(self.file_idx - 1) + "\";\n" + else: + return { + "gen_lines": [], + "gen_free": [], + "buffer_size": [] + } gen_lines = [ "//GEN_INPUT_FILE\n", - "const char* " + param_name + " = \"futag_input_file_" + - str(self.file_idx - 1) + "\";\n", + line, "FILE * fp_" + str(self.file_idx - 1) + " = fopen(" + param_name + ",\"w\");\n", "if (fp_" + str(self.file_idx - 1) + " == NULL) {\n", @@ -601,10 +704,10 @@ def __gen_input_file(self, param_name, gen_type_info): gen_lines += [ " return 0;\n", "}\n", - "fwrite(pos, 1, file_size[" + str(self.file_idx - 1) + + "fwrite(futag_pos, 1, file_size[" + str(self.file_idx - 1) + "], fp_" + str(self.file_idx - 1) + ");\n", "fclose(fp_" + str(self.file_idx - 1) + ");\n", - "pos += file_size[" + str(self.file_idx - 1) + "];\n" + "futag_pos += file_size[" + str(self.file_idx - 1) + "];\n" ] return { "gen_lines": gen_lines, @@ -628,10 +731,10 @@ def __gen_file_descriptor(self, param_name, gen_type_info): gen_lines += [ " return 0;\n", "}\n", - "fwrite(pos, 1, file_size[" + str(self.file_idx - 1) + + "fwrite(futag_pos, 1, file_size[" + str(self.file_idx - 1) + "], fp_" + str(self.file_idx - 1) + ");\n", "fclose(fp_" + str(self.file_idx - 1) + ");\n", - "pos += file_size[" + str(self.file_idx - 1) + "];\n", + "futag_pos += file_size[" + str(self.file_idx - 1) + "];\n", gen_type_info["type_name"] + " " + param_name + "= open(" + param_name + "_tmp" + str(self.file_idx) + ", O_RDWR);\n" ] gen_free = ["close(" + param_name + ");\n"] @@ -734,11 +837,22 @@ def __gen_var_function(self, func_param_name: str, func): gen_dict["gen_lines"] += curr_gen["gen_lines"] gen_dict["gen_free"] += curr_gen["gen_free"] break - elif param_id > 0 and (func["params"][param_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_CXXSTRING] or arg["param_usage"] == "SIZE_FIELD"): + elif param_id > 0 and (func["params"][param_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_WSTRING, GEN_CXXSTRING] or arg["param_usage"] == "SIZE_FIELD"): if gen_type_info["type_name"] in ["size_t", "unsigned char", "char", "int", "unsigned", "unsigned int", "short", "unsigned short", "short int", "unsigned short int"]: + dyn_size_idx = 0 + array_name = "" + if func["params"][param_id - 1]["gen_list"][0]["gen_type"] == GEN_CSTRING: + dyn_size_idx = self.dyn_cstring_size_idx + array_name = "dyn_cstring_size" + elif func["params"][param_id - 1]["gen_list"][0]["gen_type"] == GEN_WSTRING: + dyn_size_idx = self.dyn_wstring_size_idx + array_name = "dyn_wstring_size" + else: + dyn_size_idx = self.dyn_cxxstring_size_idx + array_name = "dyn_cxxstring_size" curr_name = "sz_" + curr_name # size_prefix curr_gen = self.__gen_strsize( - curr_name, arg["param_type"], self.dyn_size_idx) + curr_name, arg["param_type"], dyn_size_idx, array_name) gen_dict["buffer_size"] += curr_gen["buffer_size"] gen_dict["gen_lines"] += curr_gen["gen_lines"] gen_dict["gen_free"] += curr_gen["gen_free"] @@ -754,28 +868,52 @@ def __gen_var_function(self, func_param_name: str, func): if gen_type_info["gen_type"] == GEN_CSTRING: # GEN FILE NAME OR # GEN STRING if (arg["param_usage"] in ["FILE_PATH_READ", "FILE_PATH_WRITE", "FILE_PATH_RW", "FILE_PATH"] or arg["param_name"] in ["filename", "file", "filepath"] or arg["param_name"].find('file') != -1 or arg["param_name"].find('File') != -1) and len(arg["gen_list"]) == 1: - curr_name = "f_" + curr_name # string_prefix + curr_name = "f_" + curr_name + str(self.file_idx) # string_prefix self.file_idx += 1 curr_gen = self.__gen_input_file( curr_name, gen_type_info) else: - curr_name = "str_" + curr_name # string_prefix - self.dyn_size_idx += 1 + curr_name = "str_" + curr_name + str(self.dyn_cstring_size_idx) # string_prefix + self.dyn_cstring_size_idx += 1 curr_gen = self.__gen_cstring( - curr_name, gen_type_info, self.dyn_size_idx) + curr_name, gen_type_info, self.dyn_cstring_size_idx) gen_dict["buffer_size"] += curr_gen["buffer_size"] gen_dict["gen_lines"] += curr_gen["gen_lines"] gen_dict["gen_free"] += curr_gen["gen_free"] - - if gen_type_info["gen_type"] == GEN_CXXSTRING: - curr_name = "str_" + curr_name # string_prefix - self.dyn_size_idx += 1 - curr_gen = self.__gen_cxxstring( - curr_name, gen_type_info, self.dyn_size_idx) + + if gen_type_info["gen_type"] == GEN_WSTRING: + # GEN FILE NAME OR # GEN STRING + if (arg["param_usage"] in ["FILE_PATH_READ", "FILE_PATH_WRITE", "FILE_PATH_RW", "FILE_PATH"] or arg["param_name"] in ["filename", "file", "filepath"] or arg["param_name"].find('file') != -1 or arg["param_name"].find('File') != -1) and len(arg["gen_list"]) == 1: + curr_name = "f_" + curr_name + str(self.file_idx) # string_prefix + self.file_idx += 1 + curr_gen = self.__gen_input_file( + curr_name, gen_type_info) + else: + curr_name = "str_" + curr_name + str(self.dyn_wstring_size_idx) # string_prefix + self.dyn_wstring_size_idx += 1 + curr_gen = self.__gen_wstring( + curr_name, gen_type_info, self.dyn_wstring_size_idx) gen_dict["buffer_size"] += curr_gen["buffer_size"] gen_dict["gen_lines"] += curr_gen["gen_lines"] gen_dict["gen_free"] += curr_gen["gen_free"] + if gen_type_info["gen_type"] == GEN_CXXSTRING: + + if (arg["param_name"] in ["filename", "file", "filepath", "path"] or arg["param_name"].find('file') != -1 or arg["param_name"].find('File') != -1 or arg["param_name"].find('path') != -1) and len(arg["gen_list"]) == 1: + curr_name = "f_" + curr_name + str(self.file_idx) # string_prefix + self.file_idx += 1 + curr_gen = self.__gen_input_file( + curr_name, gen_type_info) + else: + + curr_name = "str_" + curr_name + str(self.dyn_cxxstring_size_idx) # string_prefix + self.dyn_cxxstring_size_idx += 1 + curr_gen = self.__gen_cxxstring( + curr_name, gen_type_info, self.dyn_cxxstring_size_idx) + gen_dict["buffer_size"] += curr_gen["buffer_size"] + gen_dict["gen_lines"] += curr_gen["gen_lines"] + gen_dict["gen_free"] += curr_gen["gen_free"] + if gen_type_info["gen_type"] == GEN_ENUM: # GEN_ENUM curr_name = "e_" + curr_name # enum_prefix @@ -857,7 +995,7 @@ def __wrapper_file(self, func, anonymous: bool = False): # filename = func["name"] # filepath = self.tmp_output_path / "anonymous" # else: - filename = func["qname"] + filename = func["qname"].replace(":", "_") filepath = self.tmp_output_path self.target_extension = func["location"]["fullpath"].split(".")[-1] @@ -937,7 +1075,9 @@ def __save_old_values(self): "buffer_size": copy.copy(self.buffer_size), "gen_lines": copy.copy(self.gen_lines), "gen_free": copy.copy(self.gen_free), - "dyn_size_idx": copy.copy(self.dyn_size_idx), + "dyn_cstring_size_idx": copy.copy(self.dyn_cstring_size_idx), + "dyn_cxxstring_size_idx": copy.copy(self.dyn_cxxstring_size_idx), + "dyn_wstring_size_idx": copy.copy(self.dyn_wstring_size_idx), "var_function_idx": copy.copy(self.var_function_idx), "param_list": copy.copy(self.param_list), "curr_func_log": copy.copy(self.curr_func_log), @@ -950,7 +1090,9 @@ def __retrieve_old_values(self, old_values): self.buffer_size = copy.copy(old_values["buffer_size"]) self.gen_lines = copy.copy(old_values["gen_lines"]) self.gen_free = copy.copy(old_values["gen_free"]) - self.dyn_size_idx = copy.copy(old_values["dyn_size_idx"]) + self.dyn_cstring_size_idx = copy.copy(old_values["dyn_cstring_size_idx"]) + self.dyn_cxxstring_size_idx = copy.copy(old_values["dyn_cxxstring_size_idx"]) + self.dyn_wstring_size_idx = copy.copy(old_values["dyn_wstring_size_idx"]) self.var_function_idx = copy.copy(old_values["var_function_idx"]) self.param_list = copy.copy(old_values["param_list"]) self.curr_func_log = copy.copy(old_values["curr_func_log"]) @@ -979,7 +1121,7 @@ def __gen_target_function(self, func, param_id) -> bool: self.gen_this_function = False # If there is no buffer - return! - if (not len(self.buffer_size) and not self.dyn_size_idx and not self.file_idx) or not self.gen_this_function: + if (not len(self.buffer_size) and not self.dyn_cstring_size_idx and not self.dyn_cxxstring_size_idx and not self.dyn_wstring_size_idx and not self.file_idx) or not self.gen_this_function: log = self.__log_file(func, self.gen_anonymous) if not log: print(CANNOT_CREATE_LOG_FILE, func["qname"]) @@ -1009,53 +1151,93 @@ def __gen_target_function(self, func, param_id) -> bool: else: f.write(AFLPLUSPLUS_PREFIX) - buffer_check = " if (Fuzz_Size < " + \ - str(self.dyn_size_idx) + " + " + str(self.file_idx) - f.write(buffer_check) + # buffer_check = " if (Fuzz_Size < " + \ + # str(self.dyn_wstring_size_idx) + "*sizeof(wchar_t) +" + str(self.dyn_cxxstring_size_idx) + "*sizeof(char) + " + str(self.dyn_cstring_size_idx) + " + " + str(self.file_idx) + buffer_check = str(self.dyn_wstring_size_idx) + "*sizeof(wchar_t) + " + str(self.dyn_cxxstring_size_idx) + "*sizeof(char) + " + str(self.dyn_cstring_size_idx) + " + " + str(self.file_idx) if self.buffer_size: - f.write(" + " + "+".join(self.buffer_size)) - f.write(") return 0;\n") - - if self.dyn_size_idx > 0: - f.write(" size_t dyn_buffer = (size_t) ((Fuzz_Size - ( " + str(self.file_idx) + " + " + - str(self.dyn_size_idx)) - if self.buffer_size: - f.write(" + " + "+".join(self.buffer_size)) - f.write(")));\n") + buffer_check += " + " + " + ".join(self.buffer_size) + f.write(" if (Fuzz_Size < " + buffer_check + ") return 0;\n") + + if self.dyn_cstring_size_idx > 0: + f.write(" size_t dyn_cstring_buffer = (size_t) ((Fuzz_Size + sizeof(char) - (" + buffer_check +" )));\n") f.write(" //generate random array of dynamic string sizes\n") - f.write(" size_t dyn_size[" + - str(self.dyn_size_idx) + "];\n") - if self.dyn_size_idx > 1: + f.write(" size_t dyn_cstring_size[" + + str(self.dyn_cstring_size_idx) + "];\n") + if self.dyn_cstring_size_idx > 1: f.write(" srand(time(NULL));\n") f.write( - " if(dyn_buffer == 0) dyn_size[0] = dyn_buffer; \n") - f.write(" else dyn_size[0] = rand() % dyn_buffer; \n") - f.write(" size_t remain = dyn_size[0];\n") + " if(dyn_cstring_buffer == 0) dyn_cstring_size[0] = dyn_cstring_buffer; \n") + f.write(" else dyn_cstring_size[0] = rand() % dyn_cstring_buffer; \n") + f.write(" size_t remain = dyn_cstring_size[0];\n") f.write(" for(size_t i = 1; i< " + - str(self.dyn_size_idx) + " - 1; i++){\n") + str(self.dyn_cstring_size_idx) + " - 1; i++){\n") f.write( - " if(dyn_buffer - remain == 0) dyn_size[i] = dyn_buffer - remain;\n") + " if(dyn_cstring_buffer - remain == 0) dyn_cstring_size[i] = dyn_cstring_buffer - remain;\n") f.write( - " else dyn_size[i] = rand() % (dyn_buffer - remain);\n") - f.write(" remain += dyn_size[i];\n") + " else dyn_cstring_size[i] = rand() % (dyn_cstring_buffer - remain);\n") + f.write(" remain += dyn_cstring_size[i];\n") f.write(" }\n") f.write( - " dyn_size[" + str(self.dyn_size_idx) + " - 1] = dyn_buffer - remain;\n") + " dyn_cstring_size[" + str(self.dyn_cstring_size_idx) + " - 1] = dyn_cstring_buffer - remain;\n") else: - f.write(" dyn_size[0] = dyn_buffer;\n") + f.write(" dyn_cstring_size[0] = dyn_cstring_buffer;\n") f.write( " //end of generation random array of dynamic string sizes\n") - if self.file_idx > 0: - if self.dyn_size_idx > 0: + if self.dyn_wstring_size_idx > 0: + f.write(" size_t dyn_wstring_buffer = (size_t) ((Fuzz_Size + sizeof(wchar_t) - (" + buffer_check +" )));\n") + f.write(" //generate random array of dynamic string sizes\n") + f.write(" size_t dyn_wstring_size[" + + str(self.dyn_wstring_size_idx) + "];\n") + if self.dyn_wstring_size_idx > 1: + f.write(" srand(time(NULL));\n") + f.write( + " if(dyn_wstring_buffer == 0) dyn_wstring_size[0] = dyn_wstring_buffer; \n") + f.write(" else dyn_wstring_size[0] = rand() % dyn_wstring_buffer; \n") + f.write(" size_t remain = dyn_wstring_size[0];\n") + f.write(" for(size_t i = 1; i< " + + str(self.dyn_wstring_size_idx) + " - 1; i++){\n") + f.write( + " if(dyn_wstring_buffer - remain == 0) dyn_wstring_size[i] = dyn_wstring_buffer - remain;\n") + f.write( + " else dyn_wstring_size[i] = rand() % (dyn_wstring_buffer - remain);\n") + f.write(" remain += dyn_wstring_size[i];\n") + f.write(" }\n") f.write( - " size_t file_buffer = (size_t) ((Fuzz_Size - dyn_buffer - (" + str(self.dyn_size_idx)) + " dyn_wstring_size[" + str(self.dyn_wstring_size_idx) + " - 1] = dyn_wstring_buffer - remain;\n") else: + f.write(" dyn_wstring_size[0] = dyn_wstring_buffer;\n") + f.write( + " //end of generation random array of dynamic string sizes\n") + + if self.dyn_cxxstring_size_idx > 0: + f.write(" size_t dyn_cxxstring_buffer = (size_t) ((Fuzz_Size + sizeof(char) - (" + buffer_check +" )));\n") + f.write(" //generate random array of dynamic string sizes\n") + f.write(" size_t dyn_cxxstring_size[" + + str(self.dyn_cxxstring_size_idx) + "];\n") + if self.dyn_cxxstring_size_idx > 1: + f.write(" srand(time(NULL));\n") + f.write( + " if(dyn_cxxstring_buffer == 0) dyn_cxxstring_size[0] = dyn_cxxstring_buffer; \n") + f.write(" else dyn_cxxstring_size[0] = rand() % dyn_cxxstring_buffer; \n") + f.write(" size_t remain = dyn_cxxstring_size[0];\n") + f.write(" for(size_t i = 1; i< " + + str(self.dyn_cxxstring_size_idx) + " - 1; i++){\n") + f.write( + " if(dyn_cxxstring_buffer - remain == 0) dyn_cxxstring_size[i] = dyn_cxxstring_buffer - remain;\n") + f.write( + " else dyn_cxxstring_size[i] = rand() % (dyn_cxxstring_buffer - remain);\n") + f.write(" remain += dyn_cxxstring_size[i];\n") + f.write(" }\n") f.write( - " size_t file_buffer = (size_t) ((Fuzz_Size - (" + str(self.dyn_size_idx)) - if self.buffer_size: - f.write(" + " + "+".join(self.buffer_size)) - f.write(")));\n") + " dyn_cxxstring_size[" + str(self.dyn_cxxstring_size_idx) + " - 1] = dyn_cxxstring_buffer - remain;\n") + else: + f.write(" dyn_cxxstring_size[0] = dyn_cxxstring_buffer;\n") + f.write( + " //end of generation random array of dynamic string sizes\n") + + if self.file_idx > 0: + f.write(" size_t file_buffer = (size_t) ((Fuzz_Size + "+ str(self.file_idx) + " - (" + buffer_check +" )));\n") f.write(" //generate random array of dynamic file sizes\n") f.write(" size_t file_size[" + str(self.file_idx) + "];\n") @@ -1070,7 +1252,7 @@ def __gen_target_function(self, func, param_id) -> bool: f.write( " if(file_buffer - remain == 0) file_size[i] = file_buffer - remain;\n") f.write( - " else file_size[i] = rand() % (file_buffer - remain));\n") + " else file_size[i] = rand() % (file_buffer - remain);\n") f.write(" remain += file_size[i];\n") f.write(" }\n") f.write( @@ -1080,7 +1262,7 @@ def __gen_target_function(self, func, param_id) -> bool: f.write( " //end of generation random array of dynamic file sizes\n") - f.write(" uint8_t * pos = Fuzz_Data;\n") + f.write(" uint8_t * futag_pos = Fuzz_Data;\n") for line in self.gen_lines: f.write(" " + line) @@ -1149,7 +1331,7 @@ def __gen_target_function(self, func, param_id) -> bool: if len(curr_param["gen_list"]) == 0: self.gen_this_function = False return False - if curr_param["gen_list"][0]["gen_type"] in [GEN_BUILTIN, GEN_CSTRING, GEN_CXXSTRING, GEN_ENUM, GEN_ARRAY, GEN_INPUT_FILE, GEN_OUTPUT_FILE]: + if curr_param["gen_list"][0]["gen_type"] in [GEN_BUILTIN, GEN_CSTRING, GEN_WSTRING, GEN_CXXSTRING, GEN_ENUM, GEN_ARRAY, GEN_INPUT_FILE, GEN_OUTPUT_FILE]: for gen_type_info in curr_param["gen_list"]: prev_param_name = curr_name if gen_type_info["gen_type"] == GEN_BUILTIN: @@ -1163,12 +1345,22 @@ def __gen_target_function(self, func, param_id) -> bool: break # GEN STRING SIZE - elif param_id > 0 and (func["params"][param_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_CXXSTRING] or curr_param["param_usage"] == "SIZE_FIELD"): - + elif param_id > 0 and (func["params"][param_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_WSTRING, GEN_CXXSTRING] or curr_param["param_usage"] == "SIZE_FIELD"): if gen_type_info["type_name"] in ["size_t", "unsigned char", "char", "int", "unsigned", "unsigned int", "short", "unsigned short", "short int", "unsigned short int"]: + dyn_size_idx = 0 + array_name = "" + if func["params"][param_id - 1]["gen_list"][0]["gen_type"] == GEN_CSTRING: + dyn_size_idx = self.dyn_cstring_size_idx + array_name = "dyn_cstring_size" + elif func["params"][param_id - 1]["gen_list"][0]["gen_type"] == GEN_WSTRING: + dyn_size_idx = self.dyn_wstring_size_idx + array_name = "dyn_wstring_size" + else: + dyn_size_idx = self.dyn_cxxstring_size_idx + array_name = "dyn_cxxstring_size" curr_name = "sz_" + curr_name # size_prefix curr_gen = self.__gen_strsize( - curr_name, curr_param["param_type"], self.dyn_size_idx) + curr_name, curr_param["param_type"], dyn_size_idx, array_name) self.__append_gen_dict(curr_gen) this_gen_size = True break @@ -1187,17 +1379,31 @@ def __gen_target_function(self, func, param_id) -> bool: else: # GEN STRING curr_name = "str_" + curr_name # string_prefix - self.dyn_size_idx += 1 + self.dyn_cstring_size_idx += 1 curr_gen = self.__gen_cstring( - curr_name, gen_type_info, self.dyn_size_idx) + curr_name, gen_type_info, self.dyn_cstring_size_idx) + self.__append_gen_dict(curr_gen) + if gen_type_info["gen_type"] == GEN_WSTRING: + # GEN FILE NAME OR # GEN STRING + if (curr_param["param_usage"] in ["FILE_PATH_READ", "FILE_PATH_WRITE", "FILE_PATH_RW", "FILE_PATH"] or curr_param["param_name"] in ["filename", "file", "filepath"] or curr_param["param_name"].find('file') != -1 or curr_param["param_name"].find('File') != -1) and len(curr_param["gen_list"]) == 1: + curr_name = "f_" + curr_name # string_prefix + self.file_idx += 1 + curr_gen = self.__gen_input_file( + curr_name, gen_type_info) + else: + # GEN STRING + curr_name = "str_" + curr_name # string_prefix + self.dyn_wstring_size_idx += 1 + curr_gen = self.__gen_wstring( + curr_name, gen_type_info, self.dyn_wstring_size_idx) self.__append_gen_dict(curr_gen) if gen_type_info["gen_type"] == GEN_CXXSTRING: curr_name = "str_" + curr_name # string_prefix - self.dyn_size_idx += 1 + self.dyn_cxxstring_size_idx += 1 curr_gen = self.__gen_cxxstring( - curr_name, gen_type_info, self.dyn_size_idx) + curr_name, gen_type_info, self.dyn_cxxstring_size_idx) self.__append_gen_dict(curr_gen) if gen_type_info["gen_type"] == GEN_ENUM: # GEN_ENUM @@ -1297,6 +1503,7 @@ def __gen_target_function(self, func, param_id) -> bool: self.param_list += [curr_name] curr_gen = self.__gen_var_function( curr_name, curr_return_func["function"]) + self.__add_header(self.__get_function_header(func["location"]["fullpath"])) self.__append_gen_dict(curr_gen) #!!!call recursive param_id += 1 @@ -1327,8 +1534,8 @@ def __gen_target_function(self, func, param_id) -> bool: self.var_function_idx += 1 self.gen_lines += ["\n"] self.param_list += [curr_name] - curr_gen = self.__gen_var_function( - curr_name, curr_return_func["function"]) + curr_gen = self.__gen_var_function(curr_name, curr_return_func["function"]) + self.__add_header(self.__get_function_header(func["location"]["fullpath"])) self.__append_gen_dict(curr_gen) #!!!call recursive param_id += 1 @@ -1377,6 +1584,7 @@ def __gen_target_function(self, func, param_id) -> bool: self.param_list += [curr_name] curr_gen = self.__gen_var_function( curr_name, curr_return_func["function"]) + self.__add_header(self.__get_function_header(func["location"]["fullpath"])) self.__append_gen_dict(curr_gen) #!!!call recursive param_id += 1 @@ -1426,7 +1634,9 @@ def gen_targets(self, anonymous: bool = False): self.buffer_size = [] self.gen_lines = [] self.gen_free = [] - self.dyn_size_idx = 0 + self.dyn_cstring_size_idx = 0 + self.dyn_wstring_size_idx = 0 + self.dyn_cxxstring_size_idx = 0 self.file_idx = 0 self.var_function_idx = 0 self.param_list = [] @@ -1443,7 +1653,9 @@ def gen_targets(self, anonymous: bool = False): self.buffer_size = [] self.gen_lines = [] self.gen_free = [] - self.dyn_size_idx = 0 + self.dyn_cstring_size_idx = 0 + self.dyn_wstring_size_idx = 0 + self.dyn_cxxstring_size_idx = 0 self.file_idx = 0 self.var_function_idx = 0 self.param_list = [] @@ -1582,7 +1794,7 @@ def compile_targets(self, workers: int = 4, keep_failed: bool = False, extra_inc # Extract compiler cwd, to resolve relative includes search_curr_func = [ - f for f in self.target_library['functions'] if f['qname'] == func_dir.name] + f for f in self.target_library['functions'] if f['qname'].replace(":", "_") == func_dir.name] if not len(search_curr_func): continue current_func = search_curr_func[0] @@ -1776,7 +1988,9 @@ def __init__(self, futag_llvm_package: str, library_root: str, target_type: int self.gen_lines = [] self.buffer_size = [] self.gen_free = [] - self.dyn_size_idx = 0 + self.dyn_cstring_size_idx = 0 + self.dyn_cxxstring_size_idx = 0 + self.dyn_wstring_size_idx = 0 self.file_idx = 0 self.curr_function = None self.curr_func_log = "" @@ -1950,6 +2164,43 @@ def __gen_header(self, target_function_name): include_lines.append("#include " + i + "\n") return include_lines + def __get_function_header(self, func_location): + """ Generate header for the target function + + Args: + func_location (string): function location. + + Returns: + list: list of included header. + """ + defaults = ["stdio.h", "stddef.h", "time.h", + "stdlib.h", "string.h", "stdint.h"] + compiled_files = self.target_library["compiled_files"] + included_headers = [] + found = False + for f in compiled_files: + if f["filename"] == func_location: + found = True + for header in f["headers"]: + if not header[1:-1] in defaults: + included_headers.append(header) + break + if not found: + short_filename = func_location.split('/')[-1] + for f in compiled_files: + if f["filename"].split('/')[-1] == short_filename: + found = True + for header in f["headers"]: + if not header[1:-1] in defaults: + included_headers.append(header) + break + return included_headers + + def __add_header(self, function_headers): + for h in function_headers: + if h not in self.header: + self.header.append(h) + def __gen_builtin(self, param_name, gen_type_info): """Declare and assign value for a builtin type @@ -1964,33 +2215,33 @@ def __gen_builtin(self, param_name, gen_type_info): "gen_lines": [ "//GEN_BUILTIN\n", gen_type_info["type_name"] + " " + param_name + ";\n", - "memcpy(&"+param_name+", pos, sizeof(" + + "memcpy(&"+param_name+", futag_pos, sizeof(" + gen_type_info["type_name"] + "));\n", - "pos += sizeof(" + gen_type_info["type_name"] + ");\n" + "futag_pos += sizeof(" + gen_type_info["type_name"] + ");\n" ], "gen_free": [], "buffer_size": ["sizeof(" + gen_type_info["type_name"]+")"] } - def __gen_strsize(self, param_name, param_type, dyn_size_idx): + def __gen_strsize(self, param_name, param_type, dyn_size_idx, array_name): return { "gen_lines": [ "//GEN_SIZE\n", param_type + " " + param_name + " = (" + param_type + - ") dyn_size[" + str(dyn_size_idx - 1) + "];\n", + ") " + array_name + "[" + str(dyn_size_idx - 1) + "];\n", ], "gen_free": [], "buffer_size": [] } - def __gen_cstring(self, param_name, gen_type_info, dyn_size_idx): + def __gen_cstring(self, param_name, gen_type_info, dyn_cstring_size_idx): """Declare and assign value for a C string type Args: param_name (str): parameter's name gen_type_info (dict): information of parameter's type - dyn_size_idx (int): id of dynamic size + dyn_cstring_size_idx (int): id of dynamic size Returns: dict: (gen_lines, gen_free, buffer_size) @@ -2002,20 +2253,61 @@ def __gen_cstring(self, param_name, gen_type_info, dyn_size_idx): malloc = gen_type_info["base_type_name"] + " " + ref_name + \ " = (" + gen_type_info["base_type_name"] + \ - ") malloc(dyn_size[" + str(dyn_size_idx - 1) + "] + 1);\n" + ") malloc(dyn_cstring_size[" + str(dyn_cstring_size_idx - 1) + "] + 1);\n" if "wchar_t" in gen_type_info["base_type_name"]: malloc = gen_type_info["base_type_name"] + " " + ref_name + \ " = (" + gen_type_info["base_type_name"] + \ - ") malloc(sizeof(wchar_t)*dyn_size[" + \ - str(dyn_size_idx - 1) + "] + 1);\n" + ") malloc(sizeof(wchar_t)*dyn_cstring_size[" + \ + str(dyn_cstring_size_idx - 1) + "] + 1);\n" gen_lines = [ "//GEN_CSTRING\n", malloc, "memset(" + ref_name + - ", 0, dyn_size[" + str(dyn_size_idx - 1) + "] + 1);\n", + ", 0, dyn_cstring_size[" + str(dyn_cstring_size_idx - 1) + "] + 1);\n", + "memcpy(" + ref_name + + ", futag_pos, dyn_cstring_size[" + str(dyn_cstring_size_idx - 1) + "] );\n", + "futag_pos += dyn_cstring_size[" + str(dyn_cstring_size_idx - 1) + "];\n", + ] + if (gen_type_info["local_qualifier"]): + gen_lines += [gen_type_info["type_name"] + + " " + param_name + " = " + ref_name + ";\n"] + + return { + "gen_lines": gen_lines, + "gen_free": [ + "if (" + ref_name + ") {\n", + " free(" + ref_name + ");\n", + " " + ref_name + " = NULL;\n", + "}\n" + ], + "buffer_size": [] + } + + def __gen_wstring(self, param_name, gen_type_info, dyn_wstring_size_idx): + """Declare and assign value for a C string type + + Args: + param_name (str): parameter's name + gen_type_info (dict): information of parameter's type + dyn_wstring_size_idx (int): id of dynamic wstring size + + Returns: + dict: (gen_lines, gen_free, buffer_size) + """ + ref_name = param_name + if (gen_type_info["local_qualifier"]): + ref_name = "r" + ref_name + + gen_lines = [ + "//GEN_WSTRING\n", + gen_type_info["base_type_name"] + " " + ref_name + \ + " = (" + gen_type_info["base_type_name"] + \ + ") malloc((dyn_wstring_size[" + str(dyn_wstring_size_idx - 1) + "] + 1)* sizeof(wchar_t));\n", + "memset(" + ref_name + + ", 0, (dyn_wstring_size[" + str(dyn_wstring_size_idx - 1) + "] + 1)* sizeof(wchar_t));\n", "memcpy(" + ref_name + - ", pos, dyn_size[" + str(dyn_size_idx - 1) + "] );\n", - "pos += dyn_size[" + str(dyn_size_idx - 1) + "];\n", + ", futag_pos, dyn_wstring_size[" + str(dyn_wstring_size_idx - 1) + "]* sizeof(wchar_t)] );\n", + "futag_pos += dyn_wstring_size[" + str(dyn_wstring_size_idx - 1) + "]* sizeof(wchar_t)];\n", ] if (gen_type_info["local_qualifier"]): gen_lines += [gen_type_info["type_name"] + @@ -2032,7 +2324,8 @@ def __gen_cstring(self, param_name, gen_type_info, dyn_size_idx): "buffer_size": [] } - def __gen_cxxstring(self, param_name, gen_type_info, dyn_size_idx): + + def __gen_cxxstring(self, param_name, gen_type_info, dyn_cxxstring_size_idx): """Declare and assign value for a C++ string type Args: @@ -2055,8 +2348,8 @@ def __gen_cxxstring(self, param_name, gen_type_info, dyn_size_idx): return { "gen_lines": [ gen_type_info["type_name"] + " " + param_name + - "(pos, dyn_size[" + str(dyn_size_idx - 1) + "]); \n", - "pos += dyn_size[" + str(dyn_size_idx - 1) + "];\n", + "(futag_pos, dyn_cxxstring_size[" + str(dyn_cxxstring_size_idx - 1) + "]); \n", + "futag_pos += dyn_cxxstring_size[" + str(dyn_cxxstring_size_idx - 1) + "];\n", ], "gen_free": [], "buffer_size": [] @@ -2077,10 +2370,11 @@ def __gen_enum(self, enum_record, param_name, gen_type_info, compiler_info, anon "//GEN_ENUM\n", "unsigned int " + param_name + "_enum_index; \n", "memcpy(&" + param_name + - "_enum_index, pos, sizeof(unsigned int));\n", + "_enum_index, futag_pos, sizeof(unsigned int));\n", enum_name + " " + param_name + " = " + param_name + "_enum_index % " + - str(enum_length) + ";\n" + str(enum_length) + ";\n", + "futag_pos += sizeof(unsigned int);\n" ], "gen_free": [], "buffer_size": ["sizeof(unsigned int)"] @@ -2091,10 +2385,11 @@ def __gen_enum(self, enum_record, param_name, gen_type_info, compiler_info, anon "//GEN_ENUM\n", "unsigned int " + param_name + "_enum_index; \n", "memcpy(&" + param_name + - "_enum_index, pos, sizeof(unsigned int));\n", + "_enum_index, futag_pos, sizeof(unsigned int));\n", # "enum " + enum_name + " " + param_name + " = static_cast(" + param_name + "_enum_index % " + str(enum_length) + ");\n" + ">(" + param_name + "_enum_index % " + str(enum_length) + ");\n", + "futag_pos += sizeof(unsigned int);\n" ], "gen_free": [], "buffer_size": ["sizeof(unsigned int)"] @@ -2107,9 +2402,9 @@ def __gen_array(self, param_name, gen_type_info): gen_type_info["type_name"] + " " + param_name + " = (" + gen_type_info["type_name"] + ") " + "malloc(sizeof(" + gen_type_info["base_type_name"] + ") * " + str(gen_type_info["length"]) + ");\n", - "memcpy(" + param_name + ", pos, " + str( + "memcpy(" + param_name + ", futag_pos, " + str( gen_type_info["length"]) + " * sizeof(" + gen_type_info["base_type_name"] + "));\n", - "pos += " + + "futag_pos += " + str(gen_type_info["length"]) + " * sizeof(" + gen_type_info["base_type_name"] + ");\n" ], @@ -2165,11 +2460,23 @@ def __gen_struct(self, struct_name, struct, gen_info): for gen_type_info in field["gen_list"]: this_gen_size = False if gen_type_info["gen_type"] == GEN_BUILTIN: - if field_id > 0 and (struct["fields"][field_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_CXXSTRING]): + if field_id > 0 and (struct["fields"][field_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_WSTRING, GEN_CXXSTRING]): if gen_type_info["type_name"] in ["size_t", "unsigned char", "char", "int", "unsigned", "unsigned int", "short", "unsigned short", "short int", "unsigned short int"]: + dyn_size_idx = 0 + array_name = "" + if struct["fields"][field_id - 1]["gen_list"][0]["gen_type"] == GEN_CSTRING: + dyn_size_idx = self.dyn_cstring_size_idx + array_name = "dyn_cstring_size" + elif struct["fields"][field_id - 1]["gen_list"][0]["gen_type"] == GEN_WSTRING: + dyn_size_idx = self.dyn_wstring_size_idx + array_name = "dyn_wstring_size" + else: + dyn_size_idx = self.dyn_cxxstring_size_idx + array_name = "dyn_cxxstring_size" + curr_name = "sz_" + curr_name # size_prefix curr_gen = self.__gen_strsize( - curr_name, gen_type_info["type_name"], self.dyn_size_idx) + curr_name, gen_type_info["type_name"], dyn_size_idx, array_name) buffer_size += curr_gen["buffer_size"] gen_lines += curr_gen["gen_lines"] gen_free += curr_gen["gen_free"] @@ -2185,18 +2492,27 @@ def __gen_struct(self, struct_name, struct, gen_info): if gen_type_info["gen_type"] == GEN_CSTRING: curr_name = "strc_" + curr_name # string_prefix - self.dyn_size_idx += 1 + self.dyn_cstring_size_idx += 1 curr_gen = self.__gen_cstring( - curr_name, gen_type_info, self.dyn_size_idx) + curr_name, gen_type_info, self.dyn_cstring_size_idx) + buffer_size += curr_gen["buffer_size"] + gen_lines += curr_gen["gen_lines"] + gen_free += curr_gen["gen_free"] + + if gen_type_info["gen_type"] == GEN_WSTRING: + curr_name = "strw_" + curr_name # string_prefix + self.dyn_wstring_size_idx += 1 + curr_gen = self.__gen_wstring( + curr_name, gen_type_info, self.dyn_wstring_size_idx) buffer_size += curr_gen["buffer_size"] gen_lines += curr_gen["gen_lines"] gen_free += curr_gen["gen_free"] if gen_type_info["gen_type"] == GEN_CXXSTRING: curr_name = "strcxx_" + curr_name # string_prefix - self.dyn_size_idx += 1 + self.dyn_cxxstring_size_idx += 1 curr_gen = self.__gen_cxxstring( - curr_name, gen_type_info, self.dyn_size_idx) + curr_name, gen_type_info, self.dyn_cxxstring_size_idx) buffer_size += curr_gen["buffer_size"] gen_lines += curr_gen["gen_lines"] gen_free += curr_gen["gen_free"] @@ -2284,9 +2600,9 @@ def __gen_union(self, param_name, class_record, gen_type_info): "gen_lines": [ "//GEN_UNION\n", gen_type_info["type_name"] + " " + param_name + ";\n", - "memcpy(&"+param_name+", pos, sizeof(" + + "memcpy(&"+param_name+", futag_pos, sizeof(" + gen_type_info["type_name"] + "));\n", - "pos += sizeof(" + gen_type_info["type_name"] + ");\n" + "futag_pos += sizeof(" + gen_type_info["type_name"] + ");\n" ], "gen_free": [], "buffer_size": ["sizeof(" + gen_type_info["type_name"] + ")"] @@ -2327,10 +2643,10 @@ def __gen_input_file(self, param_name, gen_type_info): gen_lines += [ " return 0;\n", "}\n", - "fwrite(pos, 1, file_size[" + str(self.file_idx - 1) + + "fwrite(futag_pos, 1, file_size[" + str(self.file_idx - 1) + "], fp_" + str(self.file_idx - 1) + ");\n", "fclose(fp_" + str(self.file_idx - 1) + ");\n", - "pos += file_size[" + str(self.file_idx - 1) + "];\n" + "futag_pos += file_size[" + str(self.file_idx - 1) + "];\n" ] return { "gen_lines": gen_lines, @@ -2354,10 +2670,10 @@ def __gen_file_descriptor(self, param_name, gen_type_info): gen_lines += [ " return 0;\n", "}\n", - "fwrite(pos, 1, file_size[" + str(self.file_idx - 1) + + "fwrite(futag_pos, 1, file_size[" + str(self.file_idx - 1) + "], fp_" + str(self.file_idx - 1) + ");\n", "fclose(fp_" + str(self.file_idx - 1) + ");\n", - "pos += file_size[" + str(self.file_idx - 1) + "];\n", + "futag_pos += file_size[" + str(self.file_idx - 1) + "];\n", gen_type_info["type_name"] + " " + param_name + "= open(" + param_name + "_tmp" + str(self.file_idx) + ", O_RDWR);\n" ] gen_free = ["close(" + param_name + ");\n"] @@ -2452,7 +2768,7 @@ def __gen_var_function(self, func_param_name: str, func): for gen_type_info in arg["gen_list"]: if gen_type_info["gen_type"] == GEN_BUILTIN: this_gen_size = False - if curr_param["param_usage"] in ["FILE_DESCRIPTOR"]: + if arg["param_usage"] in ["FILE_DESCRIPTOR"]: curr_name = "fd_" + curr_name + str(self.file_idx) # string_prefix self.file_idx += 1 curr_gen = self.__gen_file_descriptor( @@ -2461,11 +2777,23 @@ def __gen_var_function(self, func_param_name: str, func): gen_dict["gen_lines"] += curr_gen["gen_lines"] gen_dict["gen_free"] += curr_gen["gen_free"] break - elif param_id > 0 and (func["params"][param_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_CXXSTRING] or arg["param_usage"] == "SIZE_FIELD"): + elif param_id > 0 and (func["params"][param_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_WSTRING, GEN_CXXSTRING] or arg["param_usage"] == "SIZE_FIELD"): if gen_type_info["type_name"] in ["size_t", "unsigned char", "char", "int", "unsigned", "unsigned int", "short", "unsigned short", "short int", "unsigned short int"]: + dyn_size_idx = 0 + array_name = "" + if func["params"][param_id - 1]["gen_list"][0]["gen_type"] == GEN_CSTRING: + dyn_size_idx = self.dyn_cstring_size_idx + array_name = "dyn_cstring_size" + elif func["params"][param_id - 1]["gen_list"][0]["gen_type"] == GEN_WSTRING: + dyn_size_idx = self.dyn_wstring_size_idx + array_name = "dyn_wstring_size" + else: + dyn_size_idx = self.dyn_cxxstring_size_idx + array_name = "dyn_cxxstring_size" + curr_name = "sz_" + curr_name # size_prefix curr_gen = self.__gen_strsize( - curr_name, arg["param_type"], self.dyn_size_idx) + curr_name, arg["param_type"], dyn_size_idx, array_name) gen_dict["buffer_size"] += curr_gen["buffer_size"] gen_dict["gen_lines"] += curr_gen["gen_lines"] gen_dict["gen_free"] += curr_gen["gen_free"] @@ -2488,18 +2816,34 @@ def __gen_var_function(self, func_param_name: str, func): curr_name, gen_type_info) else: curr_name = "str_" + curr_name # string_prefix - self.dyn_size_idx += 1 + self.dyn_cstring_size_idx += 1 curr_gen = self.__gen_cstring( - curr_name, gen_type_info, self.dyn_size_idx) + curr_name, gen_type_info, self.dyn_cstring_size_idx) + gen_dict["buffer_size"] += curr_gen["buffer_size"] + gen_dict["gen_lines"] += curr_gen["gen_lines"] + gen_dict["gen_free"] += curr_gen["gen_free"] + + if gen_type_info["gen_type"] == GEN_WSTRING: + # GEN FILE NAME OR # GEN STRING + if (arg["param_usage"] in ["FILE_PATH_READ", "FILE_PATH_WRITE", "FILE_PATH_RW", "FILE_PATH"] or arg["param_name"] in ["filename", "file", "filepath"] or arg["param_name"].find('file') != -1 or arg["param_name"].find('File') != -1) and len(arg["gen_list"]) == 1: + curr_name = "f_" + curr_name # string_prefix + self.file_idx += 1 + curr_gen = self.__gen_input_file( + curr_name, gen_type_info) + else: + curr_name = "strw_" + curr_name # string_prefix + self.dyn_wstring_size_idx += 1 + curr_gen = self.__gen_wstring( + curr_name, gen_type_info, self.dyn_wstring_size_idx) gen_dict["buffer_size"] += curr_gen["buffer_size"] gen_dict["gen_lines"] += curr_gen["gen_lines"] gen_dict["gen_free"] += curr_gen["gen_free"] if gen_type_info["gen_type"] == GEN_CXXSTRING: curr_name = "str_" + curr_name # string_prefix - self.dyn_size_idx += 1 + self.dyn_cxxstring_size_idx += 1 curr_gen = self.__gen_cxxstring( - curr_name, gen_type_info, self.dyn_size_idx) + curr_name, gen_type_info, self.dyn_cxxstring_size_idx) gen_dict["buffer_size"] += curr_gen["buffer_size"] gen_dict["gen_lines"] += curr_gen["gen_lines"] gen_dict["gen_free"] += curr_gen["gen_free"] @@ -2585,7 +2929,7 @@ def __wrapper_file(self, func, anonymous: bool = False): # filename = func["name"] # filepath = self.tmp_output_path / "anonymous" # else: - filename = func["qname"] + filename = func["qname"].replace(":", "_") filepath = self.tmp_output_path self.target_extension = func["location"]["fullpath"].split(".")[-1] @@ -2665,7 +3009,9 @@ def __save_old_values(self): "buffer_size": copy.copy(self.buffer_size), "gen_lines": copy.copy(self.gen_lines), "gen_free": copy.copy(self.gen_free), - "dyn_size_idx": copy.copy(self.dyn_size_idx), + "dyn_cstring_size_idx": copy.copy(self.dyn_cstring_size_idx), + "dyn_cxxstring_size_idx": copy.copy(self.dyn_cxxstring_size_idx), + "dyn_wstring_size_idx": copy.copy(self.dyn_wstring_size_idx), "var_function_idx": copy.copy(self.var_function_idx), "param_list": copy.copy(self.param_list), "curr_func_log": copy.copy(self.curr_func_log), @@ -2678,7 +3024,9 @@ def __retrieve_old_values(self, old_values): self.buffer_size = copy.copy(old_values["buffer_size"]) self.gen_lines = copy.copy(old_values["gen_lines"]) self.gen_free = copy.copy(old_values["gen_free"]) - self.dyn_size_idx = copy.copy(old_values["dyn_size_idx"]) + self.dyn_cstring_size_idx = copy.copy(old_values["dyn_cstring_size_idx"]) + self.dyn_cxxstring_size_idx = copy.copy(old_values["dyn_cxxstring_size_idx"]) + self.dyn_wstring_size_idx = copy.copy(old_values["dyn_wstring_size_idx"]) self.var_function_idx = copy.copy(old_values["var_function_idx"]) self.param_list = copy.copy(old_values["param_list"]) self.curr_func_log = copy.copy(old_values["curr_func_log"]) @@ -2828,7 +3176,7 @@ def __gen_target_function(self, call, func, param_id) -> bool: self.__append_gen_dict(curr_gen) param_id += 1 self.__gen_target_function(call, func, param_id) - elif curr_param["gen_list"][0]["gen_type"] in [GEN_BUILTIN, GEN_CSTRING, GEN_CXXSTRING, GEN_ENUM, GEN_ARRAY, GEN_INPUT_FILE, GEN_OUTPUT_FILE]: + elif curr_param["gen_list"][0]["gen_type"] in [GEN_BUILTIN, GEN_CSTRING, GEN_WSTRING, GEN_CXXSTRING, GEN_ENUM, GEN_ARRAY, GEN_INPUT_FILE, GEN_OUTPUT_FILE]: for gen_type_info in curr_param["gen_list"]: # prev_param_name = curr_name + str(self.var_idx) if gen_type_info["gen_type"] == GEN_BUILTIN: @@ -2842,11 +3190,23 @@ def __gen_target_function(self, call, func, param_id) -> bool: curr_name, gen_type_info) self.__append_gen_dict(curr_gen) break - elif param_id > 0 and (func["params"][param_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_CXXSTRING] or curr_param["param_usage"] == "SIZE_FIELD"): + elif param_id > 0 and (func["params"][param_id - 1]["gen_list"][0]["gen_type"] in [GEN_CSTRING, GEN_WSTRING, GEN_CXXSTRING] or curr_param["param_usage"] == "SIZE_FIELD"): if gen_type_info["type_name"] in ["size_t", "unsigned char", "char", "int", "unsigned", "unsigned int", "short", "unsigned short", "short int", "unsigned short int"]: + dyn_size_idx = 0 + array_name = "" + if func["params"][param_id - 1]["gen_list"][0]["gen_type"] == GEN_CSTRING: + dyn_size_idx = self.dyn_cstring_size_idx + array_name = "dyn_cstring_size" + elif func["params"][param_id - 1]["gen_list"][0]["gen_type"] == GEN_WSTRING: + dyn_size_idx = self.dyn_wstring_size_idx + array_name = "dyn_wstring_size" + else: + dyn_size_idx = self.dyn_cxxstring_size_idx + array_name = "dyn_cxxstring_size" + curr_name = "sz_" + curr_name # size_prefix curr_gen = self.__gen_strsize( - curr_name, curr_param["param_type"], self.dyn_size_idx) + curr_name, curr_param["param_type"], dyn_size_idx, array_name) self.__append_gen_dict(curr_gen) this_gen_size = True # with break, we may not need this variable :) break @@ -2865,17 +3225,31 @@ def __gen_target_function(self, call, func, param_id) -> bool: else: # GEN STRING curr_name = "str_" + curr_name # string_prefix - self.dyn_size_idx += 1 + self.dyn_cstring_size_idx += 1 curr_gen = self.__gen_cstring( - curr_name, gen_type_info, self.dyn_size_idx) + curr_name, gen_type_info, self.dyn_cstring_size_idx) + self.__append_gen_dict(curr_gen) + if gen_type_info["gen_type"] == GEN_WSTRING: + # GEN FILE NAME OR # GEN STRING + if (curr_param["param_usage"] in ["FILE_PATH_READ", "FILE_PATH_WRITE", "FILE_PATH_RW", "FILE_PATH"] or curr_param["param_name"] in ["filename", "file", "filepath"] or curr_param["param_name"].find('file') != -1 or curr_param["param_name"].find('File') != -1) and len(curr_param["gen_list"]) == 1: + curr_name = "f_" + curr_name # string_prefix + self.file_idx += 1 + curr_gen = self.__gen_input_file( + curr_name, gen_type_info) + else: + # GEN STRING + curr_name = "strw_" + curr_name # string_prefix + self.dyn_wstring_size_idx += 1 + curr_gen = self.__gen_wstring( + curr_name, gen_type_info, self.dyn_wstring_size_idx) self.__append_gen_dict(curr_gen) if gen_type_info["gen_type"] == GEN_CXXSTRING: curr_name = "str_" + curr_name # string_prefix - self.dyn_size_idx += 1 + self.dyn_cxxstring_size_idx += 1 curr_gen = self.__gen_cxxstring( - curr_name, gen_type_info, self.dyn_size_idx) + curr_name, gen_type_info, self.dyn_cxxstring_size_idx) self.__append_gen_dict(curr_gen) if gen_type_info["gen_type"] == GEN_ENUM: # GEN_ENUM @@ -2975,6 +3349,7 @@ def __gen_target_function(self, call, func, param_id) -> bool: self.param_list += [curr_name] curr_gen = self.__gen_var_function( curr_name, curr_return_func["function"]) + self.__add_header(self.__get_function_header(func["location"]["fullpath"])) self.__append_gen_dict(curr_gen) #!!!call recursive param_id += 1 @@ -3008,6 +3383,7 @@ def __gen_target_function(self, call, func, param_id) -> bool: self.param_list += [curr_name] curr_gen = self.__gen_var_function( curr_name, curr_return_func["function"]) + self.__add_header(self.__get_function_header(func["location"]["fullpath"])) self.__append_gen_dict(curr_gen) #!!!call recursive param_id += 1 @@ -3056,6 +3432,7 @@ def __gen_target_function(self, call, func, param_id) -> bool: self.param_list += [curr_name] curr_gen = self.__gen_var_function( curr_name, curr_return_func["function"]) + self.__add_header(self.__get_function_header(func["location"]["fullpath"])) self.__append_gen_dict(curr_gen) #!!!call recursive param_id += 1 @@ -3198,7 +3575,7 @@ def compile_targets(self, workers: int = 4, keep_failed: bool = False, extra_inc # Extract compiler cwd, to resolve relative includes search_curr_func = [ - f for f in self.target_library['functions'] if f['qname'] == func_dir.name] + f for f in self.target_library['functions'] if f['qname'].replace(":", "_") == func_dir.name] if not len(search_curr_func): continue current_func = search_curr_func[0] @@ -3419,7 +3796,7 @@ def __gen_context_wrapper(self, func): self.gen_this_function = False # If there is no buffer - return! - if (not len(self.buffer_size) and not self.dyn_size_idx and not self.file_idx) or not self.gen_this_function: + if (not len(self.buffer_size) and not self.dyn_cstring_size_idx and not self.dyn_cxxstring_size_idx and not self.dyn_wstring_size_idx and not self.file_idx) or not self.gen_this_function: log = self.__log_file(func, self.gen_anonymous) if not log: print(CANNOT_CREATE_LOG_FILE, func["qname"]) @@ -3449,52 +3826,91 @@ def __gen_context_wrapper(self, func): else: f.write(AFLPLUSPLUS_PREFIX) - buffer_check = " if (Fuzz_Size < " + \ - str(self.dyn_size_idx) + " + " + str(self.file_idx) - f.write(buffer_check) + buffer_check = str(self.dyn_wstring_size_idx) + "*sizeof(wchar_t) + " + str(self.dyn_cxxstring_size_idx) + "*sizeof(char) + " + str(self.dyn_cstring_size_idx) + " + " + str(self.file_idx) if self.buffer_size: - f.write(" + " + "+".join(self.buffer_size)) - f.write(") return 0;\n") + buffer_check += " + " + " + ".join(self.buffer_size) + f.write(" if (Fuzz_Size < " + buffer_check + ") return 0;\n") - if self.dyn_size_idx > 0: - f.write(" size_t dyn_buffer = (size_t) ((Fuzz_Size - ( " + str(self.file_idx) + " + " + - str(self.dyn_size_idx)) - if self.buffer_size: - f.write(" + " + "+".join(self.buffer_size)) - f.write(")));\n") + if self.dyn_cstring_size_idx > 0: + f.write(" size_t dyn_cstring_buffer = (size_t) ((Fuzz_Size + sizeof(char) - (" + buffer_check +" )));\n") f.write(" //generate random array of dynamic string sizes\n") - f.write(" size_t dyn_size[" + - str(self.dyn_size_idx) + "];\n") - if self.dyn_size_idx > 1: + f.write(" size_t dyn_cstring_size[" + + str(self.dyn_cstring_size_idx) + "];\n") + if self.dyn_cstring_size_idx > 1: f.write(" srand(time(NULL));\n") - f.write(" if(dyn_buffer == 0) dyn_size[0] = dyn_buffer; \n") - f.write(" else dyn_size[0] = rand() % dyn_buffer; \n") - f.write(" size_t remain = dyn_size[0];\n") + f.write( + " if(dyn_cstring_buffer == 0) dyn_cstring_size[0] = dyn_cstring_buffer; \n") + f.write(" else dyn_cstring_size[0] = rand() % dyn_cstring_buffer; \n") + f.write(" size_t remain = dyn_cstring_size[0];\n") f.write(" for(size_t i = 1; i< " + - str(self.dyn_size_idx) + " - 1; i++){\n") + str(self.dyn_cstring_size_idx) + " - 1; i++){\n") f.write( - " if(dyn_buffer - remain == 0) dyn_size[i] = dyn_buffer - remain;\n") + " if(dyn_cstring_buffer - remain == 0) dyn_cstring_size[i] = dyn_cstring_buffer - remain;\n") f.write( - " else dyn_size[i] = rand() % (dyn_buffer - remain);\n") - f.write(" remain += dyn_size[i];\n") + " else dyn_cstring_size[i] = rand() % (dyn_cstring_buffer - remain);\n") + f.write(" remain += dyn_cstring_size[i];\n") f.write(" }\n") f.write( - " dyn_size[" + str(self.dyn_size_idx) + " - 1] = dyn_buffer - remain;\n") + " dyn_cstring_size[" + str(self.dyn_cstring_size_idx) + " - 1] = dyn_cstring_buffer - remain;\n") else: - f.write(" dyn_size[0] = dyn_buffer;\n") + f.write(" dyn_cstring_size[0] = dyn_cstring_buffer;\n") f.write( " //end of generation random array of dynamic string sizes\n") - if self.file_idx > 0: - if self.dyn_size_idx > 0: + if self.dyn_wstring_size_idx > 0: + f.write(" size_t dyn_wstring_buffer = (size_t) ((Fuzz_Size + sizeof(wchar_t) - (" + buffer_check +" )));\n") + f.write(" //generate random array of dynamic string sizes\n") + f.write(" size_t dyn_wstring_size[" + + str(self.dyn_wstring_size_idx) + "];\n") + if self.dyn_wstring_size_idx > 1: + f.write(" srand(time(NULL));\n") f.write( - " size_t file_buffer = (size_t) ((Fuzz_Size - dyn_buffer - (" + str(self.dyn_size_idx)) + " if(dyn_wstring_buffer == 0) dyn_wstring_size[0] = dyn_wstring_buffer; \n") + f.write(" else dyn_wstring_size[0] = rand() % dyn_wstring_buffer; \n") + f.write(" size_t remain = dyn_wstring_size[0];\n") + f.write(" for(size_t i = 1; i< " + + str(self.dyn_wstring_size_idx) + " - 1; i++){\n") + f.write( + " if(dyn_wstring_buffer - remain == 0) dyn_wstring_size[i] = dyn_wstring_buffer - remain;\n") + f.write( + " else dyn_wstring_size[i] = rand() % (dyn_wstring_buffer - remain);\n") + f.write(" remain += dyn_wstring_size[i];\n") + f.write(" }\n") + f.write( + " dyn_wstring_size[" + str(self.dyn_wstring_size_idx) + " - 1] = dyn_wstring_buffer - remain;\n") else: + f.write(" dyn_wstring_size[0] = dyn_wstring_buffer;\n") + f.write( + " //end of generation random array of dynamic string sizes\n") + + if self.dyn_cxxstring_size_idx > 0: + f.write(" size_t dyn_cxxstring_buffer = (size_t) ((Fuzz_Size + sizeof(char) - (" + buffer_check +" )));\n") + f.write(" //generate random array of dynamic string sizes\n") + f.write(" size_t dyn_cxxstring_size[" + + str(self.dyn_cxxstring_size_idx) + "];\n") + if self.dyn_cxxstring_size_idx > 1: + f.write(" srand(time(NULL));\n") f.write( - " size_t file_buffer = (size_t) ((Fuzz_Size - (" + str(self.dyn_size_idx)) - if self.buffer_size: - f.write(" + " + "+".join(self.buffer_size)) - f.write(")));\n") + " if(dyn_cxxstring_buffer == 0) dyn_cxxstring_size[0] = dyn_cxxstring_buffer; \n") + f.write(" else dyn_cxxstring_size[0] = rand() % dyn_cxxstring_buffer; \n") + f.write(" size_t remain = dyn_cxxstring_size[0];\n") + f.write(" for(size_t i = 1; i< " + + str(self.dyn_cxxstring_size_idx) + " - 1; i++){\n") + f.write( + " if(dyn_cxxstring_buffer - remain == 0) dyn_cxxstring_size[i] = dyn_cxxstring_buffer - remain;\n") + f.write( + " else dyn_cxxstring_size[i] = rand() % (dyn_cxxstring_buffer - remain);\n") + f.write(" remain += dyn_cxxstring_size[i];\n") + f.write(" }\n") + f.write( + " dyn_cxxstring_size[" + str(self.dyn_cxxstring_size_idx) + " - 1] = dyn_cxxstring_buffer - remain;\n") + else: + f.write(" dyn_cxxstring_size[0] = dyn_cxxstring_buffer;\n") + f.write( + " //end of generation random array of dynamic string sizes\n") + + if self.file_idx > 0: + f.write(" size_t file_buffer = (size_t) ((Fuzz_Size + "+ str(self.file_idx) + " - (" + buffer_check +" )));\n") f.write(" //generate random array of dynamic file sizes\n") f.write(" size_t file_size[" + str(self.file_idx) + "];\n") @@ -3509,7 +3925,7 @@ def __gen_context_wrapper(self, func): f.write( " if(file_buffer - remain == 0) file_size[i] = file_buffer - remain;\n") f.write( - " else file_size[i] = rand() % (file_buffer - remain));\n") + " else file_size[i] = rand() % (file_buffer - remain);\n") f.write(" remain += file_size[i];\n") f.write(" }\n") f.write( @@ -3519,7 +3935,7 @@ def __gen_context_wrapper(self, func): f.write( " //end of generation random array of dynamic file sizes\n") - f.write(" uint8_t * pos = Fuzz_Data;\n") + f.write(" uint8_t * futag_pos = Fuzz_Data;\n") for line in self.gen_lines: f.write(" " + line) @@ -3539,7 +3955,9 @@ def gen_context(self): self.buffer_size = [] self.gen_lines = [] self.gen_free = [] - self.dyn_size_idx = 0 + self.dyn_cstring_size_idx = 0 + self.dyn_wstring_size_idx = 0 + self.dyn_cxxstring_size_idx = 0 self.file_idx = 0 self.var_function_idx = 0 self.var_idx = 0 diff --git a/src/python/futag-package/src/futag/preprocessor.py b/src/python/futag-package/src/futag/preprocessor.py index e562408..dd15854 100644 --- a/src/python/futag-package/src/futag/preprocessor.py +++ b/src/python/futag-package/src/futag/preprocessor.py @@ -77,7 +77,7 @@ def __init__(self, futag_llvm_package: str, library_root: str, flags: str = "", self.futag_llvm_package = pathlib.Path( self.futag_llvm_package).absolute() else: - sys.exit(INVALID_FUTAG_PATH, futag_llvm_package) + sys.exit(INVALID_FUTAG_PATH + futag_llvm_package) if pathlib.Path(library_root).absolute().exists(): self.library_root = pathlib.Path(self.library_root).absolute() @@ -846,7 +846,7 @@ def __init__(self, futag_llvm_package: str, library_root: str, consumer_root: st self.futag_llvm_package = pathlib.Path( self.futag_llvm_package).absolute() else: - sys.exit(INVALID_FUTAG_PATH, futag_llvm_package) + sys.exit(INVALID_FUTAG_PATH + futag_llvm_package) if pathlib.Path(library_root).absolute().exists(): self.library_root = pathlib.Path(self.library_root).absolute() diff --git a/src/python/futag-package/src/futag/sysmsg.py b/src/python/futag-package/src/futag/sysmsg.py index 6b0bc88..13848b5 100644 --- a/src/python/futag-package/src/futag/sysmsg.py +++ b/src/python/futag-package/src/futag/sysmsg.py @@ -82,23 +82,23 @@ # Constants for GENERATOR GEN_BUILTIN = 0 -GEN_STRING = 1 GEN_CSTRING = 1 -GEN_CXXSTRING = 2 -GEN_ENUM = 3 -GEN_ARRAY = 4 -GEN_VOID = 5 -GEN_QUALIFIER = 6 -GEN_POINTER = 7 -GEN_STRUCT = 8 -GEN_UNION = 9 -GEN_CLASS = 10 -GEN_INCOMPLETE = 11 -GEN_FUNCTION = 12 -GEN_INPUT_FILE = 13 -GEN_OUTPUT_FILE = 14 -GEN_UNKNOWN = 15 -GEN_VARADDR = 15 +GEN_WSTRING = 2 +GEN_CXXSTRING = 3 +GEN_ENUM = 4 +GEN_ARRAY = 5 +GEN_VOID = 6 +GEN_QUALIFIER = 7 +GEN_POINTER = 8 +GEN_STRUCT = 9 +GEN_UNION = 10 +GEN_CLASS = 11 +GEN_INCOMPLETE = 12 +GEN_FUNCTION = 13 +GEN_INPUT_FILE = 14 +GEN_OUTPUT_FILE = 15 +GEN_UNKNOWN = 16 +GEN_VARADDR = 17 # Constants for ParamUsage FILE_PATH_READ = 0