diff options
| author | Jörg Frings-Fürst <debian@jff-webhsoting.net> | 2021-04-26 20:34:38 +0200 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff-webhsoting.net> | 2021-04-26 20:34:38 +0200 | 
| commit | 57be5b9e80075d32249105407879dd1d2bac460b (patch) | |
| tree | f161e88bc941e1c861b1dd1a34a332f8cdc53f7a | |
| parent | cf9293531802f491b4b145d98a4900e72a7d105b (diff) | |
| parent | 7d4216c07bd36b69ae7f5eabb7b4d6b59166a508 (diff) | |
Merge branch 'feature/upstream' into develop
| -rw-r--r-- | .github/dependabot.yml | 15 | ||||
| -rw-r--r-- | .github/workflows/build-and-test.yml | 116 | ||||
| -rw-r--r-- | .travis.yml | 86 | ||||
| -rw-r--r-- | CMakeLists.txt | 146 | ||||
| -rw-r--r-- | ChangeLog | 41 | ||||
| -rw-r--r-- | README.md | 11 | ||||
| -rw-r--r-- | THANKS | 6 | ||||
| -rw-r--r-- | appveyor.yml | 1 | ||||
| -rw-r--r-- | doc/Mainpage.txt | 41 | ||||
| -rw-r--r-- | include/uriparser/Uri.h | 2 | ||||
| -rw-r--r-- | include/uriparser/UriBase.h | 2 | ||||
| -rw-r--r-- | include/uriparser/UriDefsConfig.h | 8 | ||||
| -rw-r--r-- | include/uriparser/UriDefsUnicode.h | 2 | ||||
| -rw-r--r-- | liburiparser.pc.in | 6 | ||||
| -rw-r--r-- | src/UriCommon.c | 96 | ||||
| -rw-r--r-- | src/UriCommon.h | 2 | ||||
| -rw-r--r-- | test/MemoryManagerSuite.cpp | 4 | ||||
| -rw-r--r-- | test/test.cpp | 57 | 
18 files changed, 430 insertions, 212 deletions
diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b149019 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# Copyright (C) 2021 Sebastian Pipping <sebastian@pipping.org> +# Licensed under the MIT license + +version: 2 +updates: + +  - package-ecosystem: "github-actions" +    commit-message: +      include: "scope" +      prefix: "Actions" +    directory: "/" +    labels: +      - "enhancement" +    schedule: +      interval: "weekly" diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 0000000..ba5cb84 --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,116 @@ +# Copyright (C) 2021 Sebastian Pipping <sebastian@pipping.org> +# Licensed under the MIT license + +name: Build and test + +on: +  pull_request: +  push: +  schedule: +    - cron: '0 4 * * 5'  # Every Friday at 4am + +jobs: +  build_and_test: +    name: Build and test +    runs-on: ubuntu-latest +    steps: +      - uses: actions/checkout@v2.3.4 + +      - name: Add Clang/LLVM repositories +        run: |- +          wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - +          sudo add-apt-repository 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' + +      - name: Install build dependencies +        run: |- +          sudo apt-get install --yes --no-install-recommends -V \ +              clang-11 \ +              cmake \ +              doxygen \ +              graphviz \ +              llvm-11 \ +              lzip \ +              qhelpgenerator-qt5 \ +              qtchooser + +      - name: Build, test and install +        run: |- +          sed 's,:,\n,g' <<<"${PATH}" +          clang --version + +          GTEST_VERSION=1.8.1 +          GTEST_PREFIX=~/.local/ + +          wget https://github.com/google/googletest/archive/release-${GTEST_VERSION}.tar.gz +          tar xf release-${GTEST_VERSION}.tar.gz +          ( +            cd googletest-release-${GTEST_VERSION}/ +            cmake \ +                -DBUILD_SHARED_LIBS=ON \ +                -DCVF_VERSION=${GTEST_VERSION} \ +                -DCMAKE_INSTALL_PREFIX:PATH=${GTEST_PREFIX} \ +                . +            make +            make install +          ) + +          mkdir build +          pushd build +            compile_flags=( +              -pipe + +              -O1 +              -g +              -fsanitize=address,undefined,leak +              -fno-sanitize-recover=all +              -fno-omit-frame-pointer + +              -Wall +              -Wextra +              -pedantic +            ) +            CFLAGS="${compile_flags[*]} -std=c89" +            CXXFLAGS="${compile_flags[*]} -std=c++98" +            LDFLAGS='-g -fsanitize=address' +            cmake_args=( +              -DCMAKE_INSTALL_PREFIX:PATH=${GTEST_PREFIX} + +              -Wdev +              -Werror=dev +              -Wdeprecated +              -Werror=deprecated + +              -DCMAKE_C_COMPILER=clang-11 +              -DCMAKE_CXX_COMPILER=clang++-11 +              -DCMAKE_C_FLAGS="${CFLAGS}" +              -DCMAKE_CXX_FLAGS="${CXXFLAGS}" +              -DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}" +              -DCMAKE_MODULE_LINKER_FLAGS="${LDFLAGS}" +              -DCMAKE_SHARED_LINKER_FLAGS="${LDFLAGS}" + +              -DURIPARSER_WARNINGS_AS_ERRORS=ON +            ) +            cmake "${cmake_args[@]}" -DCMAKE_INSTALL_INCLUDEDIR=include123 .. + +            make VERBOSE=1 all + +            make VERBOSE=1 test ARGS=--verbose +            cat Testing/Temporary/LastTest.log + +            make install +            make DESTDIR="${PWD}"/ROOT/ install +            find ROOT | sort + +            ./doc/release.sh +          popd +          pushd cmake/test_find_package +            cmake "${cmake_args[@]}" . +            make VERBOSE=1 +            ./hello +          popd + +          git fetch --tags --unshallow origin  # for "git describe" in make-distcheck.sh + +          ./make-distcheck.sh -DCMAKE_INSTALL_PREFIX:PATH=${GTEST_PREFIX}  # without AddressSanitizer + +          ! git status | fgrep -A100 'Untracked files:'  # works best at the very end diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0096384..0000000 --- a/.travis.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright (C) 2018 Sebastian Pipping <sebastian@pipping.org> -# Licensed under the MIT license - -language: cpp -dist: xenial - -addons: -  apt: -    sources: -    # Clang 8: -      - llvm-toolchain-xenial-8 -      - ubuntu-toolchain-r-test -    packages: -      - clang-8 -      - cmake -      - lzip -    # Documentation: -      - doxygen -      - graphviz -      - qt4-dev-tools -      - qtchooser - -script: -  - set -e -  - GTEST_VERSION=1.8.1 -    ; GTEST_PREFIX=~/.local/ -    ; wget https://github.com/google/googletest/archive/release-${GTEST_VERSION}.tar.gz -    && tar xf release-${GTEST_VERSION}.tar.gz -    && ( cd googletest-release-${GTEST_VERSION}/ -      && cmake -          -DBUILD_SHARED_LIBS=ON -          -DCVF_VERSION=${GTEST_VERSION} -          -DCMAKE_INSTALL_PREFIX:PATH=${GTEST_PREFIX} -          . -      && make -      && make install ) -  - mkdir build -  - pushd build -  - compile_flags=( -        -pipe - -        -O1 -        -g -        -fsanitize=address -        -fno-omit-frame-pointer - -        -Wall -        -Wextra -        -pedantic -    ) -    && CFLAGS="${compile_flags[*]} -std=c89" -    && CXXFLAGS="${compile_flags[*]} -std=c++98" -    && LDFLAGS='-g -fsanitize=address' -    && cmake_args=( -        -DCMAKE_INSTALL_PREFIX:PATH=${GTEST_PREFIX} - -        -Wdev -        -Werror=dev -        -Wdeprecated -        -Werror=deprecated - -        -DCMAKE_C_COMPILER=clang-8 -        -DCMAKE_CXX_COMPILER=clang++-8 -        -DCMAKE_C_FLAGS="${CFLAGS}" -        -DCMAKE_CXX_FLAGS="${CXXFLAGS}" -        -DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}" -        -DCMAKE_MODULE_LINKER_FLAGS="${LDFLAGS}" -        -DCMAKE_SHARED_LINKER_FLAGS="${LDFLAGS}" -    ) -    && cmake "${cmake_args[@]}" -DCMAKE_INSTALL_INCLUDEDIR=include123 ..  # -Werror would fail checks! -  - make VERBOSE=1 C_FLAGS="${CFLAGS} -fPIC -Werror" CXX_FLAGS="${CXXFLAGS} -Werror" all -  - make VERBOSE=1 C_FLAGS="${CFLAGS} -fPIC -Werror" CXX_FLAGS="${CXXFLAGS} -Werror" test ARGS=--verbose -  - cat Testing/Temporary/LastTest.log -  - make install -  - ./doc/release.sh -  - make DESTDIR="${PWD}"/ROOT/ install -  - find ROOT | sort -  - popd -  - pushd cmake/test_find_package -  - cmake "${cmake_args[@]}" . -  - make VERBOSE=1 -  - ./hello -  - popd -  - git fetch --tags --unshallow origin  # for "git describe" in make-distcheck.sh -  - ./make-distcheck.sh -DCMAKE_INSTALL_PREFIX:PATH=${GTEST_PREFIX}  # without AddressSanitizer -  - "! git status | fgrep -A100 'Untracked files:'  # works best at the very end" diff --git a/CMakeLists.txt b/CMakeLists.txt index 70088b1..4b1ce44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,14 +38,14 @@ cmake_minimum_required(VERSION 3.3)  project(uriparser      VERSION -        0.9.4 +        0.9.5      LANGUAGES          C  ) -# See https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html +# See https://verbump.de/ for what these numbers do  set(URIPARSER_SO_CURRENT    1) -set(URIPARSER_SO_REVISION  27) +set(URIPARSER_SO_REVISION  28)  set(URIPARSER_SO_AGE        0)  include(CheckCCompilerFlag) @@ -65,6 +65,7 @@ option(URIPARSER_BUILD_TOOLS "Build tools (e.g. CLI \"uriparse\")" ON)  option(URIPARSER_BUILD_CHAR "Build code supporting data type 'char'" ON)  option(URIPARSER_BUILD_WCHAR_T "Build code supporting data type 'wchar_t'" ON)  option(URIPARSER_ENABLE_INSTALL "Enable installation of uriparser" ON) +option(URIPARSER_WARNINGS_AS_ERRORS "Treat all compiler warnings as errors" OFF)  set(URIPARSER_MSVC_RUNTIME "" CACHE STRING "Use of specific runtime library (/MT /MTd /MD /MDd) with MSVC")  if(NOT URIPARSER_BUILD_CHAR AND NOT URIPARSER_BUILD_WCHAR_T) @@ -103,6 +104,14 @@ if(URIPARSER_COMPILER_SUPPORTS_VISIBILITY)      set(URIPARSER_EXTRA_COMPILE_FLAGS "${URIPARSER_EXTRA_COMPILE_FLAGS} -fvisibility=hidden")  endif() +if(URIPARSER_WARNINGS_AS_ERRORS) +    if(MSVC) +        add_definitions(/WX) +    else() +        set(URIPARSER_EXTRA_COMPILE_FLAGS "${URIPARSER_EXTRA_COMPILE_FLAGS} -Werror") +    endif() +endif() +  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${URIPARSER_EXTRA_COMPILE_FLAGS}")  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${URIPARSER_EXTRA_COMPILE_FLAGS}") @@ -111,40 +120,40 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${URIPARSER_EXTRA_COMPILE_FLAGS}")  #  check_symbol_exists(wprintf wchar.h HAVE_WPRINTF)  check_function_exists(reallocarray HAVE_REALLOCARRAY)  # no luck with CheckSymbolExists -configure_file(src/UriConfig.h.in config.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/UriConfig.h.in config.h)  #  # C library  #  set(API_HEADER_FILES -    include/uriparser/UriBase.h -    include/uriparser/UriDefsAnsi.h -    include/uriparser/UriDefsConfig.h -    include/uriparser/UriDefsUnicode.h -    include/uriparser/Uri.h -    include/uriparser/UriIp4.h +    ${CMAKE_CURRENT_SOURCE_DIR}/include/uriparser/UriBase.h +    ${CMAKE_CURRENT_SOURCE_DIR}/include/uriparser/UriDefsAnsi.h +    ${CMAKE_CURRENT_SOURCE_DIR}/include/uriparser/UriDefsConfig.h +    ${CMAKE_CURRENT_SOURCE_DIR}/include/uriparser/UriDefsUnicode.h +    ${CMAKE_CURRENT_SOURCE_DIR}/include/uriparser/Uri.h +    ${CMAKE_CURRENT_SOURCE_DIR}/include/uriparser/UriIp4.h  )  set(LIBRARY_CODE_FILES -    src/UriCommon.c -    src/UriCommon.h -    src/UriCompare.c -    src/UriEscape.c -    src/UriFile.c -    src/UriIp4Base.c -    src/UriIp4Base.h -    src/UriIp4.c -    src/UriMemory.c -    src/UriMemory.h -    src/UriNormalizeBase.c -    src/UriNormalizeBase.h -    src/UriNormalize.c -    src/UriParseBase.c -    src/UriParseBase.h -    src/UriParse.c -    src/UriQuery.c -    src/UriRecompose.c -    src/UriResolve.c -    src/UriShorten.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriCommon.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriCommon.h +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriCompare.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriEscape.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriFile.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriIp4Base.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriIp4Base.h +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriIp4.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriMemory.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriMemory.h +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriNormalizeBase.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriNormalizeBase.h +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriNormalize.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriParseBase.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriParseBase.h +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriParse.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriQuery.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriRecompose.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriResolve.c +    ${CMAKE_CURRENT_SOURCE_DIR}/src/UriShorten.c  )  add_library(uriparser @@ -157,7 +166,10 @@ if(NOT MSVC)      set_property(TARGET uriparser PROPERTY VERSION ${URIPARSER_SO_CURRENT_MINUS_AGE}.${URIPARSER_SO_AGE}.${URIPARSER_SO_REVISION})      set_property(TARGET uriparser PROPERTY SOVERSION ${URIPARSER_SO_CURRENT_MINUS_AGE})      if(WIN32) -        set_property(TARGET uriparser PROPERTY SUFFIX "-${URIPARSER_SO_CURRENT_MINUS_AGE}${CMAKE_SHARED_LIBRARY_SUFFIX}") +        set_target_properties(uriparser PROPERTIES +            OUTPUT_NAME uriparser +            RUNTIME_OUTPUT_NAME uriparser-${URIPARSER_SO_CURRENT_MINUS_AGE} +            ARCHIVE_OUTPUT_NAME uriparser)      endif()  endif() @@ -214,7 +226,7 @@ uriparser_install(  #  if(URIPARSER_BUILD_TOOLS)      add_executable(uriparse -        tool/uriparse.c +        ${CMAKE_CURRENT_SOURCE_DIR}/tool/uriparse.c      )      target_link_libraries(uriparse PUBLIC uriparser) @@ -260,10 +272,10 @@ if(URIPARSER_BUILD_TESTS)      find_package(GTest 1.8.0 REQUIRED)      add_executable(testrunner -        test/FourSuite.cpp -        test/MemoryManagerSuite.cpp -        test/test.cpp -        test/VersionSuite.cpp +        ${CMAKE_CURRENT_SOURCE_DIR}/test/FourSuite.cpp +        ${CMAKE_CURRENT_SOURCE_DIR}/test/MemoryManagerSuite.cpp +        ${CMAKE_CURRENT_SOURCE_DIR}/test/test.cpp +        ${CMAKE_CURRENT_SOURCE_DIR}/test/VersionSuite.cpp          # These library code files have non-public symbols that the test suite          # needs to link to, so they appear here as well: @@ -290,6 +302,15 @@ if(URIPARSER_BUILD_TESTS)          ${GTEST_BOTH_LIBRARIES}      ) +    # NOTE: uriparser does not use pthreads itself but gtest does +    find_package(Threads REQUIRED) +    target_link_libraries(testrunner PRIVATE Threads::Threads) + +    if(MSVC) +        # Specify unwind semantics so that MSVC knowns how to handle exceptions +        target_compile_options(testrunner PRIVATE /EHsc) +    endif() +      add_test(          NAME              test @@ -305,11 +326,20 @@ endif()  #  if(URIPARSER_BUILD_DOCS)      find_package(Doxygen REQUIRED dot doxygen) -    find_program(QHG_LOCATION -        NAMES -            qhelpgenerator -            qhelpgenerator-qt5  # e.g. CentOS 7 -    ) + +    set(QHG_LOCATION "" CACHE FILEPATH "Path to qhelpgenerator program (default: auto-detect)") +    if(NOT QHG_LOCATION) +        find_package(Qt5Help QUIET) +        if(TARGET Qt5::qhelpgenerator) +            get_target_property(QHG_LOCATION Qt5::qhelpgenerator LOCATION) +            mark_as_advanced(Qt5Core_DIR) +            mark_as_advanced(Qt5Gui_DIR) +            mark_as_advanced(Qt5Help_DIR) +            mark_as_advanced(Qt5Sql_DIR) +            mark_as_advanced(Qt5Widgets_DIR) +        endif() +    endif() +      include(FindHTMLHelp)      # Generate Doxyfile @@ -323,8 +353,8 @@ if(URIPARSER_BUILD_DOCS)      else()          set(GENERATE_QHP NO)      endif() -    configure_file(doc/Doxyfile.in doc/Doxyfile @ONLY) -    configure_file(doc/release.sh.in doc/release.sh @ONLY) +    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in doc/Doxyfile @ONLY) +    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doc/release.sh.in doc/release.sh @ONLY)      add_custom_target(doc          ALL @@ -358,7 +388,7 @@ endif()  # CMake files for find_package(uriparser [..] CONFIG [..])  #  configure_package_config_file( -        cmake/uriparser-config.cmake.in +        ${CMAKE_CURRENT_SOURCE_DIR}/cmake/uriparser-config.cmake.in          cmake/uriparser-config.cmake      INSTALL_DESTINATION          ${CMAKE_INSTALL_LIBDIR}/cmake/uriparser-${PROJECT_VERSION}/ @@ -393,7 +423,7 @@ uriparser_install(  # pkg-config file  #  if(NOT MSVC) -    configure_file(liburiparser.pc.in liburiparser.pc @ONLY) +    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/liburiparser.pc.in liburiparser.pc @ONLY)      uriparser_install(          FILES              ${CMAKE_CURRENT_BINARY_DIR}/liburiparser.pc @@ -408,13 +438,25 @@ endif()  message(STATUS "===========================================================================")  message(STATUS "")  message(STATUS "Configuration") -message(STATUS "  Prefix ............... ${CMAKE_INSTALL_PREFIX}") -message(STATUS "  Shared libraries ..... ${BUILD_SHARED_LIBS}") -message(STATUS "  Code for char * ...... ${URIPARSER_BUILD_CHAR}") -message(STATUS "  Code for wchar_t * ... ${URIPARSER_BUILD_WCHAR_T}") -message(STATUS "  Tools ................ ${URIPARSER_BUILD_TOOLS}") -message(STATUS "  Test suite ........... ${URIPARSER_BUILD_TESTS}") -message(STATUS "  Documentation ........ ${URIPARSER_BUILD_DOCS}") +message(STATUS "  Build type ............. ${CMAKE_BUILD_TYPE}") +message(STATUS "  Shared libraries ....... ${BUILD_SHARED_LIBS}") +message(STATUS "  Compiler flags") +message(STATUS "    C .................... ${CMAKE_C_FLAGS}") +message(STATUS "    C++ .................. ${CMAKE_CXX_FLAGS}") +message(STATUS "  Linker flags") +message(STATUS "    Executable ........... ${CMAKE_EXE_LINKER_FLAGS}") +message(STATUS "    Module ............... ${CMAKE_MODULE_LINKER_FLAGS}") +message(STATUS "    Shared ............... ${CMAKE_SHARED_LINKER_FLAGS}") +message(STATUS "  Paths") +message(STATUS "    Prefix ............... ${CMAKE_INSTALL_PREFIX}") +message(STATUS "    qhelpgenerator ....... ${QHG_LOCATION}") +message(STATUS "") +message(STATUS "  Features") +message(STATUS "    Code for char * ...... ${URIPARSER_BUILD_CHAR}") +message(STATUS "    Code for wchar_t * ... ${URIPARSER_BUILD_WCHAR_T}") +message(STATUS "    Tools ................ ${URIPARSER_BUILD_TOOLS}") +message(STATUS "    Test suite ........... ${URIPARSER_BUILD_TESTS}") +message(STATUS "    Documentation ........ ${URIPARSER_BUILD_DOCS}")  message(STATUS "")  if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")      message(STATUS "Continue with") @@ -2,6 +2,43 @@ NOTE: uriparser is looking for help with a few things:        https://github.com/uriparser/uriparser/labels/help%20wanted        If you can help, please get in touch.  Thanks! +2021-03-18 -- 0.9.5 + +  * Fixed: Fix a bug regarding section "5.2.4. Remove Dot Segments" +      of RFC 3986 that affected both normalization and reference resolution +      with regard to trailing slashes (GitHub #92, #97) +      Thanks to Dan Pape for the report! +  * Fixed: MinGW: Fix name of static library (GitHub #90) +      Thanks to SpaceIm for the patch and Sandro Mani for review! +  * Fixed: Use correct inline marker "__forceinline" for Intel C++ Compiler +      (GitHub #93) +      Thanks to jensenrichardson for the patch! +  * Fixed: Link against pthreads for (default) -DURIPARSER_BUILD_TESTS=ON +      (GitHub #99, #100) +  * Fixed: When integrated using CMake function add_subdirectory, installation +      could fail due to lack of prefix ${CMAKE_CURRENT_SOURCE_DIR} (GitHub #98) +      Thanks for the patch to Shehzan Mohammed! +  * Fixed: Addressed MSVC compile warning about lack of /EHsc when compiling +      the C++ test suite code (GitHub #102) +  * Fixed: Stopped misadvertising wide characters as Unicode support +      (GitHub #104) +  * Added: CMake option URIPARSER_WARNINGS_AS_ERRORS=(ON|OFF) +      to turn compile warnings into errors, defaults to "OFF" (GitHub #102) +  * Improved: pkg-config: Use ${prefix} and ${exec_prefix} to ease +      overriding variables using --define-variable=NAME=VALUE, +      e.g. as done on OpenWRT (GitHub #91) +      Thanks to Karel Kočí for the pull request! +  * Improved: Auto-detection of the qhelpgenerator command based on CMake +      package "Qt5Help" when available.  CMake option "QHG_LOCATION" can still +      be used to enforce a specific location (GitHub #103) +      Thanks for his help to Andreas Sturmlechner! +  * Improved: Make documentation use pkg-config in example on how to +      check for uriparser from within configure.ac (GNU Autoconf) +      (GitHub #37, #106) +  * Improved: In testing code, add a missing 'extern "C"' (GitHub #109) +      Thanks to Jørgen Ibsen for the patch! +  * Soname: 1:28:0 — see https://verbump.de/ for what these numbers do +  2020-05-31 -- 0.9.4    * Fixed: testrunner: No longer crashes when compiled with NDEBUG (GitHub #67) @@ -22,7 +59,7 @@ NOTE: uriparser is looking for help with a few things:    * Added: CMake option URIPARSER_ENABLE_INSTALL to toggle installation of        files, defaults to "ON" (GitHub #74, #75)        Thanks to Scott Donelan for the patch! -  * Soname: 1:26:0 +  * Soname: 1:27:0  2019-04-28 -- 0.9.3 @@ -487,7 +524,7 @@ NOTE: uriparser is looking for help with a few things:  2007-03-26 -- 0.3.0    * Added: New API, old marked deprecated -  * Added: Unicode support (think wchar_t) +  * Added: Added support for wide strings (think wchar_t)    * Added: Doxygen code documentation    * Added: Test suite using CppTest    * Changed: Library code is now licensed under the new BSD license. @@ -1,4 +1,4 @@ -[](https://travis-ci.org/uriparser/uriparser) +[](https://github.com/uriparser/uriparser/actions/workflows/build-and-test.yml)  [](https://ci.appveyor.com/project/uriparseradmin/uriparser) @@ -10,7 +10,7 @@ URI parsing and handling library  written in C89 ("ANSI C").  uriparser is cross-platform,  fast, -supports Unicode, and +supports both `char` and `wchar_t`, and  is licensed under the [New BSD license](https://github.com/uriparser/uriparser/blob/master/COPYING).  To learn more about uriparser, @@ -55,8 +55,8 @@ CMAKE_BUILD_TYPE:STRING=  // Install path prefix, prepended onto install directories.  CMAKE_INSTALL_PREFIX:PATH=/usr/local -// Path to a program. -QHG_LOCATION:FILEPATH=/usr/bin/qhelpgenerator +// Path to qhelpgenerator program (default: auto-detect) +QHG_LOCATION:FILEPATH=  // Build code supporting data type 'char'  URIPARSER_BUILD_CHAR:BOOL=ON @@ -78,4 +78,7 @@ URIPARSER_ENABLE_INSTALL:BOOL=ON  // Use of specific runtime library (/MT /MTd /MD /MDd) with MSVC  URIPARSER_MSVC_RUNTIME:STRING= + +// Treat all compiler warnings as errors +URIPARSER_WARNINGS_AS_ERRORS:BOOL=OFF  ``` @@ -4,9 +4,11 @@ Adeodato Sim  Adrian Manrique  Alexander Klink  Arkadiusz Miskiewicz +Andreas Sturmlechner  Blair Sadewitz  Chris Hills  Cristian Rodriguez +Dan Pape  Daniel Chapiesky  Daniel Solano Gómez  David Demelier @@ -22,11 +24,13 @@ Friedrich Delgado Friedrichs  Gary Mazzaferro  Graham Percival  Harvey Vrsalovic +jensenrichardson  Jerome Custodio  Joel Cunningham  Jørgen Ibsen  Juan Pablo Gonzlez Tognarelli  KangLin +Karel Kočí  Kouhei Sutou  Kurt Schwehr  Marc Novakowski @@ -51,6 +55,8 @@ Sandro Mani  Schrijvers Luc  Scott Donelan  Sezai Tekin +Shehzan Mohammed +SpaceIm  Valentin Haenel  Vitaly Lipatov  Yang Yu diff --git a/appveyor.yml b/appveyor.yml index 09890c0..7e36cdb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -88,6 +88,7 @@ before_build:        -DGTEST_ROOT=googletest-release-%GTEST_VERSION%/googletest        -DURIPARSER_BUILD_DOCS=OFF        -DURIPARSER_MSVC_RUNTIME=/MT +      -DURIPARSER_WARNINGS_AS_ERRORS=ON        ..  build: diff --git a/doc/Mainpage.txt b/doc/Mainpage.txt index bb5723c..19d8115 100644 --- a/doc/Mainpage.txt +++ b/doc/Mainpage.txt @@ -10,8 +10,8 @@   *   - <a href="#shortening">Creating References</a>   *   - <a href="#filenames">Filenames and URIs</a>   *   - <a href="#normalization">Normalizing URIs</a> - *   - <a href="#querystrings">Working with query strings</a> - * - <a href="#chartypes">Ansi and Unicode</a> + *   - <a href="#querystrings">Working with Query Strings</a> + * - <a href="#chartypes">Narrow Strings and Wide Strings</a>   * - <a href="#autoconf">Autoconf Check</a>   *   * @@ -226,7 +226,7 @@   * @endcode   *   * - * @section querystrings Working with query strings + * @section querystrings Working with Query Strings   * <a href="http://tools.ietf.org/html/rfc3986" target="_blank">RFC 3986</a>   * itself does not understand the query part of a URI as a list of key/value pairs.   * But HTML 2.0 does and defines a media type <i>application/x-www-form-urlencoded</i> @@ -281,37 +281,20 @@   * @endcode   *   * - * @section chartypes Ansi and Unicode + * @section chartypes Narrow Strings and Wide Strings   * uriparser comes with two versions of every structure and function: - * one handling Ansi text (char *) and one working with Unicode text (wchar_t *), + * one handling narrow strings (<code>char *</code>) and one working with wide strings (<code>wchar_t *</code>),   * for instance - * - uriParseSingleUriA() for Ansi and - * - uriParseSingleUriW() for Unicode. + * - uriParseSingleUriA() for <code>char *</code> + * - uriParseSingleUriW() for <code>wchar_t *</code>.   * - * This tutorial only shows the usage of the Ansi editions but - * their Unicode counterparts work in the very same way. + * This tutorial only shows the usage of the narrow string editions but + * their wide string counterparts work in the very same way.   *   *   * @section autoconf Autoconf Check   * You can use the code below to make <c>./configure</c> test for presence - * of uriparser 0.6.4 or later. - * - *<div class="fragment"><pre class="fragment">URIPARSER_MISSING=<span class="stringliteral">"Please install uriparser 0.9.0 or later. - *   On a Debian-based system enter 'sudo apt-get install liburiparser-dev'."</span> - *AC_CHECK_LIB(uriparser, uriParseSingleUriA,, AC_MSG_ERROR(${URIPARSER_MISSING})) - *AC_CHECK_HEADER(uriparser/Uri.h,, AC_MSG_ERROR(${URIPARSER_MISSING})) - *<b></b> - *URIPARSER_TOO_OLD=<span class="stringliteral">"uriparser 0.9.0 or later is required, your copy is too old."</span> - *AC_COMPILE_IFELSE([ - *<span class="preprocessor">\#include <uriparser/Uri.h> - *\#if (defined(URI_VER_MAJOR) && defined(URI_VER_MINOR) && defined(URI_VER_RELEASE) \\<b></b> - *&& ((URI_VER_MAJOR > 0) \\<b></b> - *|| ((URI_VER_MAJOR == 0) && (URI_VER_MINOR > 9)) \\<b></b> - *|| ((URI_VER_MAJOR == 0) && (URI_VER_MINOR == 9) && (URI_VER_RELEASE >= 0)) \\<b></b> - *))</span> - *<span class="comment"><b></b>/<b></b>* FINE *<b></b>/</span> - *<span class="preprocessor">\#else - *\# error uriparser not recent enough - *\#endif</span> - *],,AC_MSG_ERROR(${URIPARSER_TOO_OLD}))</pre></div> + * of uriparser 0.9.0 or later. + * + *<div class="fragment"><pre class="fragment">PKG_CHECK_MODULES([URIPARSER], [liburiparser >= 0.9.0], [], [])</pre></div>   */ diff --git a/include/uriparser/Uri.h b/include/uriparser/Uri.h index e822d33..44d8760 100644 --- a/include/uriparser/Uri.h +++ b/include/uriparser/Uri.h @@ -1,4 +1,4 @@ -/* 520782e6334595efe9dee874cfa720d7b49de30fa51caba8bce352e55f521ee1 (0.9.4+) +/* 6db8b5726a796167bb96b3d83ff9ac6792a01474dbe3778deb3c2a25d60b3693 (0.9.5+)   *   * uriparser - RFC 3986 URI parsing library   * diff --git a/include/uriparser/UriBase.h b/include/uriparser/UriBase.h index 4147882..565abcf 100644 --- a/include/uriparser/UriBase.h +++ b/include/uriparser/UriBase.h @@ -55,7 +55,7 @@  /* Version */  #define URI_VER_MAJOR           0  #define URI_VER_MINOR           9 -#define URI_VER_RELEASE         4 +#define URI_VER_RELEASE         5  #define URI_VER_SUFFIX_ANSI     ""  #define URI_VER_SUFFIX_UNICODE  URI_ANSI_TO_UNICODE(URI_VER_SUFFIX_ANSI) diff --git a/include/uriparser/UriDefsConfig.h b/include/uriparser/UriDefsConfig.h index 392229a..51bc93e 100644 --- a/include/uriparser/UriDefsConfig.h +++ b/include/uriparser/UriDefsConfig.h @@ -59,15 +59,15 @@  /* No encoding at all */  #  error URI_NO_ANSI and URI_NO_UNICODE cannot go together.  # else -/* Unicode only */ +/* Wide strings only */  #  define URI_ENABLE_UNICODE  1  # endif  #else  # ifdef URI_NO_UNICODE -/* ANSI only */ +/* Narrow strings only */  #  define URI_ENABLE_ANSI     1  # else -/* Both ANSI and Unicode */ +/* Both narrow and wide strings */  #  define URI_ENABLE_ANSI     1  #  define URI_ENABLE_UNICODE  1  # endif @@ -82,7 +82,7 @@  /* Intel C/C++ */  /* http://predef.sourceforge.net/precomp.html#sec20 */  /* http://www.intel.com/support/performancetools/c/windows/sb/CS-007751.htm#2 */ -# define URI_INLINE __force_inline +# define URI_INLINE __forceinline  #elif defined(_MSC_VER)  /* Microsoft Visual C++ */  /* http://predef.sourceforge.net/precomp.html#sec32 */ diff --git a/include/uriparser/UriDefsUnicode.h b/include/uriparser/UriDefsUnicode.h index 08e4728..01421f5 100644 --- a/include/uriparser/UriDefsUnicode.h +++ b/include/uriparser/UriDefsUnicode.h @@ -39,7 +39,7 @@  /**   * @file UriDefsUnicode.h - * Holds definitions for the Unicode pass. + * Holds definitions for the wide string pass.   * NOTE: This header is included N times, not once.   */ diff --git a/liburiparser.pc.in b/liburiparser.pc.in index 22c7c95..9547860 100644 --- a/liburiparser.pc.in +++ b/liburiparser.pc.in @@ -1,7 +1,7 @@  prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +exec_prefix=${prefix} +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@  Name: liburiparser  Description: URI parsing and handling library diff --git a/src/UriCommon.c b/src/UriCommon.c index 60bd319..7ba92f2 100644 --- a/src/UriCommon.c +++ b/src/UriCommon.c @@ -119,17 +119,6 @@ int URI_FUNC(CompareRange)( -/* Properly removes "." and ".." path segments */ -UriBool URI_FUNC(RemoveDotSegments)(URI_TYPE(Uri) * uri, -		UriBool relative, UriMemoryManager * memory) { -	if (uri == NULL) { -		return URI_TRUE; -	} -	return URI_FUNC(RemoveDotSegmentsEx)(uri, relative, uri->owner, memory); -} - - -  UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  		UriBool relative, UriBool pathOwned, UriMemoryManager * memory) {  	URI_TYPE(PathSegment) * walker; @@ -149,7 +138,13 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  				URI_TYPE(PathSegment) * const prev = walker->reserved;  				URI_TYPE(PathSegment) * const nextBackup = walker->next; -				/* Is this dot segment essential? */ +				/* +				 * Is this dot segment essential, +				 * i.e. is there a chance of changing semantics by dropping this dot segment? +				 * +				 * For example, changing "./http://foo" into "http://foo" would change semantics +				 * and hence the dot segment is essential to that case and cannot be removed. +				 */  				removeSegment = URI_TRUE;  				if (relative && (walker == uri->pathHead) && (walker->next != NULL)) {  					const URI_CHAR * ch = walker->next->text.first; @@ -162,16 +157,23 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  				}  				if (removeSegment) { +					/* .. then let's go remove that segment. */  					/* Last segment? */  					if (walker->next != NULL) { -						/* Not last segment */ +						/* Not last segment, i.e. first or middle segment +						 * OLD: (prev|NULL) <- walker <- next +						 * NEW: (prev|NULL) <----------- next */  						walker->next->reserved = prev;  						if (prev == NULL) { -							/* First but not last segment */ +							/* First but not last segment +							 * OLD: head -> walker -> next +							 * NEW: head -----------> next */  							uri->pathHead = walker->next;  						} else { -							/* Middle segment */ +							/* Middle segment +							 * OLD: prev -> walker -> next +							 * NEW: prev -----------> next */  							prev->next = walker->next;  						} @@ -220,11 +222,16 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  				removeSegment = URI_TRUE;  				if (relative) {  					if (prev == NULL) { +						/* We cannot remove traversal beyond because the +						 * URI is relative and may be resolved later. +						 * So we can simplify "a/../b/d" to "b/d" but +						 * we cannot simplify "../b/d" (outside of reference resolution). */  						removeSegment = URI_FALSE;  					} else if ((prev != NULL)  							&& ((prev->text.afterLast - prev->text.first) == 2)  							&& ((prev->text.first)[0] == _UT('.'))  							&& ((prev->text.first)[1] == _UT('.'))) { +						/* We need to protect against mis-simplifying "a/../../b" to "a/b". */  						removeSegment = URI_FALSE;  					}  				} @@ -234,9 +241,14 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  						/* Not first segment */  						prevPrev = prev->reserved;  						if (prevPrev != NULL) { -							/* Not even prev is the first one */ +							/* Not even prev is the first one +							 * OLD: prevPrev -> prev -> walker -> (next|NULL) +							 * NEW: prevPrev -------------------> (next|NULL) */  							prevPrev->next = walker->next;  							if (walker->next != NULL) { +								/* Update parent relationship as well +								 * OLD: prevPrev <- prev <- walker <- next +								 * NEW: prevPrev <------------------- next */  								walker->next->reserved = prevPrev;  							} else {  								/* Last segment -> insert "" segment to represent trailing slash, update tail */ @@ -302,29 +314,58 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  						}  					} else {  						URI_TYPE(PathSegment) * const anotherNextBackup = walker->next; -						/* First segment -> update head pointer */ -						uri->pathHead = walker->next; +						int freeWalker = URI_TRUE; + +						/* First segment */  						if (walker->next != NULL) { +							/* First segment of multiple -> update head +							 * OLD: head -> walker -> next +							 * NEW: head -----------> next */ +							uri->pathHead = walker->next; + +							/* Update parent link as well +							 * OLD: head <- walker <- next +							 * NEW: head <----------- next */  							walker->next->reserved = NULL;  						} else { -							/* Last segment -> update tail */ -							uri->pathTail = NULL; +							if (uri->absolutePath) { +								/* First and only segment -> update head +								 * OLD: head -> walker -> NULL +								 * NEW: head -----------> NULL */ +								uri->pathHead = NULL; + +								/* Last segment -> update tail +								 * OLD: tail -> walker +								 * NEW: tail -> NULL */ +								uri->pathTail = NULL; +							} else { +								/* Re-use segment for "" path segment to represent trailing slash, +								 * then update head and tail */ +								if (pathOwned && (walker->text.first != walker->text.afterLast)) { +									memory->free(memory, (URI_CHAR *)walker->text.first); +								} +								walker->text.first = URI_FUNC(SafeToPointTo); +								walker->text.afterLast = URI_FUNC(SafeToPointTo); +								freeWalker = URI_FALSE; +							}  						} -						if (pathOwned && (walker->text.first != walker->text.afterLast)) { -							memory->free(memory, (URI_CHAR *)walker->text.first); +						if (freeWalker) { +							if (pathOwned && (walker->text.first != walker->text.afterLast)) { +								memory->free(memory, (URI_CHAR *)walker->text.first); +							} +							memory->free(memory, walker);  						} -						memory->free(memory, walker);  						walker = anotherNextBackup;  					}  				}  			}  			break; - -		} +		} /* end of switch */  		if (!removeSegment) { +			/* .. then let's move to the next element, and start again. */  			if (walker->next != NULL) {  				walker->next->reserved = walker;  			} else { @@ -344,7 +385,10 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri,  		UriMemoryManager * memory) {  	const UriBool ABSOLUTE = URI_FALSE; -	return URI_FUNC(RemoveDotSegments)(uri, ABSOLUTE, memory); +	if (uri == NULL) { +		return URI_TRUE; +	} +	return URI_FUNC(RemoveDotSegmentsEx)(uri, ABSOLUTE, uri->owner, memory);  } diff --git a/src/UriCommon.h b/src/UriCommon.h index 10bc250..42311dd 100644 --- a/src/UriCommon.h +++ b/src/UriCommon.h @@ -84,8 +84,6 @@ int URI_FUNC(CompareRange)(  UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri,  		UriMemoryManager * memory); -UriBool URI_FUNC(RemoveDotSegments)(URI_TYPE(Uri) * uri, UriBool relative, -		UriMemoryManager * memory);  UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  		UriBool relative, UriBool pathOwned, UriMemoryManager * memory); diff --git a/test/MemoryManagerSuite.cpp b/test/MemoryManagerSuite.cpp index 4cda664..a828d76 100644 --- a/test/MemoryManagerSuite.cpp +++ b/test/MemoryManagerSuite.cpp @@ -27,7 +27,11 @@  #include <gtest/gtest.h>  #include <uriparser/Uri.h> + +// For defaultMemoryManager +extern "C" {  #include "../src/UriMemory.h" +}  namespace { diff --git a/test/test.cpp b/test/test.cpp index 9a189f9..4b156a4 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -311,7 +311,7 @@ TEST(UriSuite, TestUri) {  		ASSERT_TRUE(0 == uriParseUriA(&stateA, "//user:pass@localhost/one/two/three"));  		uriFreeUriMembersA(&uriA); -		// ANSI and Unicode +		// Both narrow and wide string version  		ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://www.example.com/"));  		uriFreeUriMembersA(&uriA);  		ASSERT_TRUE(0 == uriParseUriW(&stateW, L"http://www.example.com/")); @@ -1098,6 +1098,19 @@ TEST(UriSuite, TestAddBase) {  		// Bug related to absolutePath flag set despite presence of host  		ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/", L"http://a/"));  		ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/g/", L"http://a/g/")); + +		// GitHub issue #92 +		EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/../d;p?q", L"../..", L"http://a/")); +		EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/../d;p?q", L"../../", L"http://a/")); + +		EXPECT_TRUE(testAddBaseHelper(L"http://a/b/../c/d;p?q", L"../..", L"http://a/")); +		EXPECT_TRUE(testAddBaseHelper(L"http://a/b/../c/d;p?q", L"../../", L"http://a/")); + +		EXPECT_TRUE(testAddBaseHelper(L"http://a/../b/c/d;p?q", L"../..", L"http://a/")); +		EXPECT_TRUE(testAddBaseHelper(L"http://a/../b/c/d;p?q", L"../../", L"http://a/")); + +		EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../..", L"http://a/")); +		EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../../", L"http://a/"));  }  namespace { @@ -1477,6 +1490,48 @@ TEST(UriSuite, TestNormalizeSyntaxComponents) {  				URI_NORMALIZE_FRAGMENT));  } +TEST(UriSuite, TestNormalizeSyntaxPath) { +	// These are from GitHub issue #92 +	EXPECT_TRUE(testNormalizeSyntaxHelper( +			L"http://a/b/c/../../..", +			L"http://a/", +			URI_NORMALIZE_PATH)); +	EXPECT_TRUE(testNormalizeSyntaxHelper( +			L"http://a/b/../c/../..", +			L"http://a/", +			URI_NORMALIZE_PATH)); +	EXPECT_TRUE(testNormalizeSyntaxHelper( +			L"http://a/b/c/../../..", +			L"http://a/", +			URI_NORMALIZE_PATH)); + +	// .. and these are related +	EXPECT_TRUE(testNormalizeSyntaxHelper( +			L"http://a/..", +			L"http://a/", +			URI_NORMALIZE_PATH)); +	EXPECT_TRUE(testNormalizeSyntaxHelper( +			L"/..", +			L"/", +			URI_NORMALIZE_PATH)); +	EXPECT_TRUE(testNormalizeSyntaxHelper( +			L"http://a/..///", +			L"http://a///", +			URI_NORMALIZE_PATH)); +	EXPECT_TRUE(testNormalizeSyntaxHelper( +			L"http://a/..///..", +			L"http://a//", +			URI_NORMALIZE_PATH)); +	EXPECT_TRUE(testNormalizeSyntaxHelper( +			L"a/b/c/../../..", +			L"", +			URI_NORMALIZE_PATH)); +	EXPECT_TRUE(testNormalizeSyntaxHelper( +			L"a/b/../../c/..", +			L"", +			URI_NORMALIZE_PATH)); +} +  TEST(UriSuite, TestNormalizeCrashBug20080224) {  		UriParserStateW stateW;  		int res;  | 
