From a892b3faaf66f4e9c3f46832d067dd5156cc0ef8 Mon Sep 17 00:00:00 2001 From: Brad Kotsopoulos Date: Thu, 6 Dec 2018 16:56:10 -0500 Subject: [PATCH 01/11] Add Cmake support --- CMakeLists.txt | 59 +++++++++++++++++++++++++++++++++++++++++++ cmake/Config.cmake.in | 16 ++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 cmake/Config.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..bafefcac --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,59 @@ +cmake_minimum_required(VERSION 3.0) + +project(nanosvg LANGUAGES CXX VERSION "0.0.0") + +set(NANOSVG_HEADERS "src/nanosvg.h" "src/nanosvgrast.h") + +add_library(nanosvg INTERFACE) + +target_include_directories( + nanosvg + INTERFACE + "$" +) + +# Introduce variables: +# * CMAKE_INSTALL_INCLUDEDIR +include(GNUInstallDirs) + +set(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") +set(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake") +set(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}Config.cmake") + +set(CONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") + +set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets") +set(NAMESPACE "${PROJECT_NAME}::") + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${VERSION_CONFIG}" COMPATIBILITY ExactVersion +) + +configure_package_config_file( + "cmake/Config.cmake.in" + "${PROJECT_CONFIG}" + INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}" +) + +install( + TARGETS nanosvg + EXPORT "${TARGETS_EXPORT_NAME}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" +) + +install( + FILES ${NANOSVG_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} +) + +install( + FILES "${PROJECT_CONFIG}" "${VERSION_CONFIG}" + DESTINATION "${CONFIG_INSTALL_DIR}" +) + +install( + EXPORT "${TARGETS_EXPORT_NAME}" + NAMESPACE "${NAMESPACE}" + DESTINATION "${CONFIG_INSTALL_DIR}" +) diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in new file mode 100644 index 00000000..cc15d725 --- /dev/null +++ b/cmake/Config.cmake.in @@ -0,0 +1,16 @@ +# Copyright (c) 2016, Ruslan Baratov +# +# Licensed under the MIT License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# http://opensource.org/licenses/MIT +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake") +check_required_components("@PROJECT_NAME@") From 1fec50c9acf1e9128c2b9f2236bdd5ac0f707bc2 Mon Sep 17 00:00:00 2001 From: Michael Tesch Date: Fri, 8 Feb 2019 17:10:04 +0100 Subject: [PATCH 02/11] added cmake targets for the two examples let demo programs take a file argument --- CMakeLists.txt | 5 +++- example/CMakeLists.txt | 16 +++++++++++ example/dump.c | 61 ++++++++++++++++++++++++++++++++++++++++++ example/example1.c | 12 ++++++--- example/example2.c | 6 ++++- 5 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 example/CMakeLists.txt create mode 100644 example/dump.c diff --git a/CMakeLists.txt b/CMakeLists.txt index bafefcac..c9798443 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.0) -project(nanosvg LANGUAGES CXX VERSION "0.0.0") +project(nanosvg LANGUAGES C VERSION "0.0.0") set(NANOSVG_HEADERS "src/nanosvg.h" "src/nanosvgrast.h") @@ -12,6 +12,9 @@ target_include_directories( "$" ) +# Build examples +add_subdirectory(example) + # Introduce variables: # * CMAKE_INSTALL_INCLUDEDIR include(GNUInstallDirs) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 00000000..42dd36ee --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,16 @@ + +include_directories(${CMAKE_SOURCE_DIR}/src) +include_directories(${CMAKE_SOURCE_DIR}/example) + +find_package(PkgConfig REQUIRED) +pkg_search_module(GLFW REQUIRED glfw3) +include_directories(${GLFW_INCLUDE_DIRS}) + +#add_executable(dump dump.c) +add_executable(example1 example1.c) +add_executable(example2 example2.c) + +#target_link_libraries(dump m GL ${GLFW_STATIC_LIBRARIES}) +target_link_libraries(example1 m GL ${GLFW_STATIC_LIBRARIES}) +target_link_libraries(example2 m GL ${GLFW_STATIC_LIBRARIES}) + diff --git a/example/dump.c b/example/dump.c new file mode 100644 index 00000000..72a23491 --- /dev/null +++ b/example/dump.c @@ -0,0 +1,61 @@ +// +// Copyright (c) 2017 Michael Tesch tesch1@gmail.com +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#include +#include +#include + +#define NANOSVG_IMPLEMENTATION +#include "nanosvg.h" + +NSVGimage* g_image = NULL; + +int main(int argc, char *argv[]) +{ + for (int arg = 1; arg < argc; arg++) { + const char* filename = argv[arg]; + + g_image = nsvgParseFromFile(filename, "px", 96.0f); + if (g_image == NULL) { + printf("Could not open SVG image '%s'.\n", filename); + return -1; + } + + printf("%s:\n", filename); + printf("size: %f x %f.\n", g_image->width, g_image->height); + + for (NSVGgroup* group = g_image->groups; group != NULL; group = group->next) { + printf("group: %s parent:%s\n", group->id, group->parent ? group->parent->id : "-"); + } + + for (NSVGshape* shape = g_image->shapes; shape != NULL; shape = shape->next) { + printf("shape: '%s' visible:%d\n", shape->id, 0 != (shape->flags & NSVG_FLAGS_VISIBLE)); + if (shape->group) + printf(" : group '%s'\n", shape->group->id); + for (NSVGpath* path = shape->paths; path != NULL; path = path->next) { + //drawPath(path->pts, path->npts, path->closed, px * 1.5f); + printf(" npts: %d [%f %f %f %f]\n", path->npts, + path->bounds[0], path->bounds[1], path->bounds[2], path->bounds[3]); + } + } + + nsvgDelete(g_image); + } + + return 0; +} diff --git a/example/example1.c b/example/example1.c index 100831be..582e4ccb 100644 --- a/example/example1.c +++ b/example/example1.c @@ -22,6 +22,7 @@ #include #define NANOSVG_IMPLEMENTATION +#define NANOSVG_ALL_COLOR_KEYWORDS #include "nanosvg.h" NSVGimage* g_image = NULL; @@ -215,7 +216,7 @@ void resizecb(GLFWwindow* window, int width, int height) drawframe(window); } -int main() +int main(int argc, char *argv[]) { GLFWwindow* window; const GLFWvidmode* mode; @@ -224,7 +225,7 @@ int main() return -1; mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); - window = glfwCreateWindow(mode->width - 40, mode->height - 80, "Nano SVG", NULL, NULL); + window = glfwCreateWindow(mode->width - 40, mode->height - 80, "Nano SVG", NULL, NULL); if (!window) { printf("Could not open window\n"); @@ -238,13 +239,18 @@ int main() glEnable(GL_LINE_SMOOTH); - g_image = nsvgParseFromFile("../example/nano.svg", "px", 96.0f); + const char* filename = "../example/nano.svg"; + if (argc > 1) + filename = argv[1]; + g_image = nsvgParseFromFile(filename, "px", 96.0f); if (g_image == NULL) { printf("Could not open SVG image.\n"); glfwTerminate(); return -1; } + printf("size: %f x %f.\n", g_image->width, g_image->height); + while (!glfwWindowShouldClose(window)) { drawframe(window); diff --git a/example/example2.c b/example/example2.c index 9ae9b595..df71c1b9 100644 --- a/example/example2.c +++ b/example/example2.c @@ -22,17 +22,21 @@ #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" #define NANOSVG_IMPLEMENTATION +#define NANOSVG_ALL_COLOR_KEYWORDS #include "nanosvg.h" #define NANOSVGRAST_IMPLEMENTATION #include "nanosvgrast.h" -int main() +int main(int argc, char *argv[]) { NSVGimage *image = NULL; NSVGrasterizer *rast = NULL; unsigned char* img = NULL; int w, h; + const char* filename = "../example/23.svg"; + if (argc > 1) + filename = argv[1]; printf("parsing %s\n", filename); image = nsvgParseFromFile(filename, "px", 96.0f); From 7de23026974fa2de204b741a2f667bf84fc75902 Mon Sep 17 00:00:00 2001 From: Michael Tesch Date: Fri, 8 Feb 2019 17:59:08 +0100 Subject: [PATCH 03/11] simple fuzzing via afl --- example/CMakeLists.txt | 39 +++++++++++++++++++++ example/example2.c | 11 ++++-- example/fuzz.dict | 77 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 example/fuzz.dict diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 42dd36ee..7de9642f 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,10 +1,13 @@ +option (BUILD_FUZZ "Build binaries with tooling for fuzzing." OFF) + include_directories(${CMAKE_SOURCE_DIR}/src) include_directories(${CMAKE_SOURCE_DIR}/example) find_package(PkgConfig REQUIRED) pkg_search_module(GLFW REQUIRED glfw3) include_directories(${GLFW_INCLUDE_DIRS}) +add_compile_options(-O2 -Wall) #add_executable(dump dump.c) add_executable(example1 example1.c) @@ -14,3 +17,39 @@ add_executable(example2 example2.c) target_link_libraries(example1 m GL ${GLFW_STATIC_LIBRARIES}) target_link_libraries(example2 m GL ${GLFW_STATIC_LIBRARIES}) +# +# if fuzzing is enabled +# +if (BUILD_FUZZ) + include (ExternalProject) + # + # Afl + # + ExternalProject_Add (aflX + PREFIX aflX + URL http://lcamtuf.coredump.cx/afl/releases/afl-2.52b.tgz + CONFIGURE_COMMAND "" + BUILD_COMMAND "make" + BUILD_IN_SOURCE 1 + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + ) + ExternalProject_Get_Property (aflX source_dir) + set (AFL_DIR "${source_dir}") + message ("American Fuzzy Lop in ${AFL_DIR}") + #set (CMAKE_C_COMPILER ${AFL_DIR}/afl-gcc) + #set (CMAKE_CXX_COMPILER ${AFL_DIR}/afl-g++) + set (CMAKE_C_COMPILER ${AFL_DIR}/afl-clang) + set (CMAKE_CXX_COMPILER ${AFL_DIR}/afl-clang++) + + add_dependencies (example1 aflX) + add_dependencies (example2 aflX) + + add_custom_target (fuzz + COMMAND mkdir -p fuzz-data + COMMAND cp nano.svg fuzz-data/ + COMMAND ${AFL_DIR}/afl-fuzz -i fuzz-data -o fuzz-out -x fuzz.dict $ @@ '' + ) + add_dependencies (fuzz example1) + +endif (BUILD_FUZZ) diff --git a/example/example2.c b/example/example2.c index df71c1b9..b328b71f 100644 --- a/example/example2.c +++ b/example/example2.c @@ -33,10 +33,13 @@ int main(int argc, char *argv[]) NSVGrasterizer *rast = NULL; unsigned char* img = NULL; int w, h; - const char* filename = "../example/23.svg"; + const char* out_filename = "svg.png"; + if (argc > 1) filename = argv[1]; + if (argc > 2) + out_filename = argv[2]; printf("parsing %s\n", filename); image = nsvgParseFromFile(filename, "px", 96.0f); @@ -62,8 +65,10 @@ int main(int argc, char *argv[]) printf("rasterizing image %d x %d\n", w, h); nsvgRasterize(rast, image, 0,0,1, img, w, h, w*4); - printf("writing svg.png\n"); - stbi_write_png("svg.png", w, h, 4, img, w*4); + if (out_filename[0]) { + printf("writing %s\n", out_filename); + stbi_write_png(out_filename, w, h, 4, img, w*4); + } error: nsvgDeleteRasterizer(rast); diff --git a/example/fuzz.dict b/example/fuzz.dict new file mode 100644 index 00000000..b50dd156 --- /dev/null +++ b/example/fuzz.dict @@ -0,0 +1,77 @@ +# +# AFL dictionary for svg parsers +# + +tag_a="" +tag_animate="" +tag_animateMotion="" +tag_animateTransform="" +tag_circle="" +tag_clipPath="" +tag_color_profile="" +tag_defs="" +tag_desc="" +tag_discard="" +tag_ellipse="" +tag_feBlend="" +tag_feColorMatrix="" +tag_feComponentTransfer="" +tag_feComposite="" +tag_feConvolveMatrix="" +tag_feDiffuseLighting="" +tag_feDisplacementMap="" +tag_feDistantLight="" +tag_feDropShadow="" +tag_feFlood="" +tag_feFuncA="" +tag_feFuncB="" +tag_feFuncG="" +tag_feFuncR="" +tag_feGaussianBlur="" +tag_feImage="" +tag_feMerge="" +tag_feMergeNode="" +tag_feMorphology="" +tag_feOffset="" +tag_fePointLight="" +tag_feSpecularLighting="" +tag_feSpotLight="" +tag_feTile="" +tag_feTurbulence="" +tag_filter="" +tag_foreignObject="" +tag_g="" +tag_hatch="" +tag_hatchpath="" +tag_image="" +tag_line="" +tag_linearGradient="" +tag_marker="" +tag_mask="" +tag_mesh="" +tag_meshgradient="" +tag_meshpatch="" +tag_meshrow="" +tag_metadata="" +tag_mpath="" +tag_path="" +tag_pattern="" +tag_polygon="" +tag_polyline="" +tag_radialGradient="" +tag_rect="" +tag_script="