diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cc43453 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,110 @@ +name: CI Build Tests + +on: + push: + pull_request: + release: + types: [published] + schedule: + - cron: '30 3 * * 0' + +jobs: + cpp_build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: ubuntu-latest + CC: gcc-11 + CXX: g++-11 + CMAKE_CMD: cmake .. + NAME: gcc-11 + + - os: ubuntu-latest + CC: gcc-12 + CXX: g++-12 + CMAKE_CMD: cmake .. + NAME: gcc-12 + + - os: ubuntu-latest + CC: clang-11 + CXX: clang++-11 + CMAKE_CMD: cmake .. + NAME: clang-11 + + - os: ubuntu-latest + CC: clang-12 + CXX: clang++-12 + CMAKE_CMD: cmake .. + NAME: clang-12 + + - os: ubuntu-latest + CC: clang-13 + CXX: clang++-13 + CMAKE_CMD: cmake .. + NAME: clang-13 + + - os: ubuntu-latest + CC: clang-14 + CXX: clang++-14 + CMAKE_CMD: cmake .. + NAME: clang-14 + + - os: ubuntu-latest + CC: clang-15 + CXX: clang++-15 + CMAKE_CMD: cmake .. + NAME: clang-15 + + - os: macos-latest + CC: /usr/local/opt/llvm/bin/clang + CXX: /usr/local/opt/llvm/bin/clang++ + CMAKE_CMD: cmake .. + NAME: clang + + - os: macos-latest + CMAKE_CMD: cmake .. + NAME: AppleClang + + - os: windows-latest + CMAKE_CMD: cmake .. + NAME: msvc + + - os: windows-latest + CMAKE_CMD: cmake .. -G "Unix Makefiles" + NAME: mingw-gcc + + name: ${{ matrix.os }}-${{ matrix.NAME }} - C++ Test + env: + MSBUILD_PATH: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/MSBuild/Current/Bin" + steps: + - uses: actions/checkout@v1 + - name: Checkout Submodules + run: | + git submodule update --init --recursive + - name: Create Build Directory + run: mkdir build + + - name: Install Dependencies (Linux) + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt update + sudo apt install -y ${{ matrix.CC }} + if [[ "${{ matrix.CXX }}" != *"clang"* ]]; then sudo apt install -y ${{ matrix.CXX }}; fi + - name: Install Dependencies (OSX) + if: matrix.os == 'macos-latest' && matrix.name != 'AppleClang' + run: | + brew cask uninstall --force oclint || true + brew install llvm || brew upgrade llvm + + - name: Execute CMake Process + env: + CC: ${{ matrix.CC }} + CXX: ${{ matrix.CXX }} + run: | + cd build + ${{ matrix.CMAKE_CMD }} + - name: Build Project + run: | + cd build + cmake --build . -j diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml deleted file mode 100644 index d11d132..0000000 --- a/.github/workflows/cmake.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: CMake - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -env: - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release - -jobs: - build: - # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. - # You can convert this to a matrix build if you need cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - - - name: Build - # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - - - name: Test - working-directory: ${{github.workspace}}/build - # Execute tests defined by the CMake configuration. - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest -C ${{env.BUILD_TYPE}} - diff --git a/.gitignore b/.gitignore index aaef641..b320129 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ build*/ *.swp *.swo +.idea/ +cmake-build-debug/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 58cc169..7a2ae40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,49 @@ cmake_minimum_required(VERSION 3.1) -project(ipv6) +find_program(CCACHE_PROGRAM ccache) +if(CCACHE_PROGRAM) + message(STATUS "IPv6-Parse: Found ccache package... Activating...") + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") +endif() + +set(LIB_MAJOR_VERSION "1") +set(LIB_MINOR_VERSION "2") +set(LIB_PATCH_VERSION "1") +set(LIB_VERSION_STRING "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_PATCH_VERSION}") + +if(CMAKE_VERSION VERSION_LESS 3.0) + project(ipv6 C) + enable_language(C) + enable_language(CXX) +else() + cmake_policy(SET CMP0003 NEW) + cmake_policy(SET CMP0048 NEW) + project(ipv6 VERSION "${LIB_VERSION_STRING}" LANGUAGES C CXX) +endif() + +## This section describes our general CMake setup options +set_property(GLOBAL PROPERTY USE_FOLDERS ON) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_SKIP_INSTALL_RULES OFF FORCE) +set(CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY ON FORCE) +set(CMAKE_SUPPRESS_REGENERATION ON) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +# Build with c++17 support. +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +## We only build static binaries -- this is left here for our dependencies +set(STATIC ON CACHE BOOL FORCE "Link libraries statically? Forced to ON") +add_definitions(-DSTATICLIB) SET(PARSE_TRACE 0 CACHE BOOL "Enable tracing of address parsing") -# Check the for the windows secure CRT version of snprintf -if (MSVC) - message("Detecting _snprintf_s for MSVC") - include(CheckSymbolExists) - set (CMAKE_REQUIRED_FLAGS "/MTd") - check_symbol_exists(_snprintf_s "stdio.h" HAVE__SNPRINTF_S) -endif (MSVC) +option(IPV6_PARSE_LIBRARY_ONLY "Build Only the Library" ON) +if(DEFINED ENV{IPV6_PARSE_LIBRARY_ONLY}) + set(IPV6_PARSE_LIBRARY_ONLY $ENV{IPV6_PARSE_LIBRARY_ONLY}) +endif() # Include header checks include (CheckIncludeFiles) @@ -22,7 +55,7 @@ CHECK_INCLUDE_FILES(stdarg.h HAVE_STDARG_H) configure_file(ipv6_config.h.in ipv6_config.h) set(IPV6_CONFIG_HEADER_PATH ${CMAKE_CURRENT_BINARY_DIR}) -message("-- Including ipv6_config.h from ${IPV6_CONFIG_HEADER_PATH}") +message("-- Including ipv6_config.h from ${IPV6_CONFIG_HEADER_PATH}") # Use bin as the directory for all executables. # This will make protoc easy to find. @@ -39,22 +72,15 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/bin) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/bin) -# Build with c++14 support. -set(CMAKE_CXX_STANDARD 14) - # Allow creating filters for projects in visual studio. set_property(GLOBAL PROPERTY USE_FOLDERS ON) -if(COMMAND cmake_policy) - cmake_policy(SET CMP0003 NEW) -endif() - file(GLOB ipv6_sources "ipv6.h" "ipv6.c" ${IPV6_CONFIG_HEADER_PATH}/ipv6_config.h) if (MSVC) set(ipv6_target_compile_flags "/MTd /Wall /ZI /Od /D_NO_CRT_STDIO_INLINE=1") else () - set(ipv6_target_compile_flags "-Wall -Wno-long-long -pedantic -std=c99") + set(ipv6_target_compile_flags "-Wall -Wno-long-long -pedantic -std=c99 -Wno-unused-but-set-variable") endif () if (NOT IPV6_PARSE_LIBRARY_ONLY) @@ -76,7 +102,7 @@ if (NOT IPV6_PARSE_LIBRARY_ONLY) target_include_directories(ipv6-test PRIVATE ${IPV6_CONFIG_HEADER_PATH} ${IPV6_TEST_CONFIG_HEADER_PATH}) target_include_directories(ipv6-cmd PRIVATE ${IPV6_CONFIG_HEADER_PATH}) - + if (MSVC) target_link_libraries(ipv6-test ws2_32) target_link_libraries(ipv6-cmd ws2_32) @@ -95,3 +121,12 @@ if (PARSE_TRACE) set_target_properties(ipv6-test PROPERTIES COMPILE_DEFINITIONS PARSE_TRACE=1) set_target_properties(ipv6-cmd PROPERTIES COMPILE_DEFINITIONS PARSE_TRACE=1) endif () + +foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + string(REGEX REPLACE "/RTC[^ ]*" "" ${flag_var} "${${flag_var}}") + string(REGEX REPLACE "/Od" "" ${flag_var} "${${flag_var}}") +endforeach(flag_var) diff --git a/ipv6.c b/ipv6.c index fefb4cb..8c5716f 100644 --- a/ipv6.c +++ b/ipv6.c @@ -28,14 +28,6 @@ snprintf(buffer, bytes, format, __VA_ARGS__) #endif - -// Original core address RFC 3513: https://tools.ietf.org/html/rfc3513 -// Replacement address RFC 4291: https://tools.ietf.org/html/rfc4291 - -const uint32_t IPV6_STRING_SIZE = - sizeof "[1234:1234:1234:1234:1234:1234:1234:1234/128%longinterface]:65535"; -const uint32_t IPV4_STRING_SIZE = sizeof "255.255.255.255:65535"; - // // Distinct states of parsing an address // @@ -723,7 +715,7 @@ bool IPV6_API_DEF(ipv6_from_str_diag) ( return false; } - if (input_bytes > IPV6_STRING_SIZE) { + if (input_bytes > 66) { ipv6_error(&state, IPV6_DIAG_STRING_SIZE_EXCEEDED, "Input string size exceeded"); return false; @@ -918,10 +910,9 @@ size_t IPV6_API_DEF(ipv6_to_str) ( const uint16_t* components = in->address.components; char* wp = output; // write pointer const char* ep = output + output_bytes - 1; // end pointer with one octet for nul - char token[IPV4_STRING_SIZE]; - token[0] = '\0'; + char token[22] = {0}; - // If the address is an IPv4 compatible address shortcut the IPv6 rules and + // If the address is an IPv4 compatible address shortcut the IPv6 rules and // print an address or address:port if (in->flags & IPV6_FLAG_IPV4_COMPAT) { int32_t n = platform_snprintf(token, sizeof(token), "%d.%d.%d.%d", diff --git a/ipv6_config.h.in b/ipv6_config.h.in index 86846cc..d4ccf40 100644 --- a/ipv6_config.h.in +++ b/ipv6_config.h.in @@ -9,4 +9,6 @@ #pragma warning(disable: 4820) // Disable alignment errors in windows headers #pragma warning(disable: 4255) // Disable prototype () -> (void) conversion warning #pragma warning(disable: 5045) // Disable /Qspectre mitigation info warnings -#endif \ No newline at end of file +#pragma warning(disable: 4061) // Disable specified enumerator identifier is not explicitly handled by a case level +#pragma warning(disable: 4034) +#endif