:hocho: Strictly RFC 3986 compliant URI parsing and handling library written in C89; moved from SourceForge to GitHub

Overview

Travis CI Build Status AppVeyor Build Status

uriparser

uriparser is a strictly RFC 3986 compliant URI parsing and handling library written in C89 ("ANSI C"). uriparser is cross-platform, fast, supports Unicode, and is licensed under the New BSD license.

To learn more about uriparser, please check out https://uriparser.github.io/.

Example use from an existing CMake project

project(hello VERSION 1.0)

find_package(uriparser 0.9.2 CONFIG REQUIRED char wchar_t)

add_executable(hello
    hello.c
)

target_link_libraries(hello PUBLIC uriparser::uriparser)

Compilation

Compilation (standalone, GNU make, Linux)

# mkdir build
# cd build
# cmake -DCMAKE_BUILD_TYPE=Release ..  # see CMakeLists.txt for options
# make
# make test
# make install

Available CMake options (and defaults)

# rm -f CMakeCache.txt ; cmake -LH . | grep -B1 ':.*=' | sed 's,--,,'
// Build shared libraries (rather than static ones)
BUILD_SHARED_LIBS:BOOL=ON

// Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel ...
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

// Build code supporting data type 'char'
URIPARSER_BUILD_CHAR:BOOL=ON

// Build API documentation (requires Doxygen, Graphviz, and (optional) Qt's qhelpgenerator)
URIPARSER_BUILD_DOCS:BOOL=ON

// Build test suite (requires GTest >=1.8.0)
URIPARSER_BUILD_TESTS:BOOL=ON

// Build tools (e.g. CLI "uriparse")
URIPARSER_BUILD_TOOLS:BOOL=ON

// Build code supporting data type 'wchar_t'
URIPARSER_BUILD_WCHAR_T:BOOL=ON

// Enable installation of uriparser
URIPARSER_ENABLE_INSTALL:BOOL=ON

// Use of specific runtime library (/MT /MTd /MD /MDd) with MSVC
URIPARSER_MSVC_RUNTIME:STRING=
Comments
  • Replace GNU Autotools build system by CMake >=3

    Replace GNU Autotools build system by CMake >=3

    There are multiple W.I.P. migrations to CMake around. I figured, if CMake is going to be the main and only build system for uriparser at some point, I need to learn CMake myself anyway. Also, since I'm rather picky at code review, we can maybe turn things around: Now you get to be as picky as you like and I'll be the one fixing as we go. So review is welcome, tear it apart! :smiley:

    Acceptance criteria to merge:

    • [x] Use CMake >=3 <=3.9.2 to support Ubuntu trusty (ends 2019-04)
    • [x] Library, CLI tool, and headers at built and installed
    • [x] Test suite built (but not installed)
    • [x] Documentation built and installed
    • [x] GNUInstallDirs is used
    • [x] soversion matches that of Autotools build system
    • [x] configure.ac checks are done as well
      • [x] C functions
      • [x] doxygen
      • [x] graphviz
      • [x] qhelpgenerator (optional)
      • [x] AC_SEARCH_LIBS([inet_ntop],[socket network]) for Haiku (see #45)
    • [x] configure.ac build time toggles are provided as well
      • [x] char toggle
      • [x] wchar_t toggle
      • [x] test suite toggle
      • [x] documentation toggle
    • [x] provide CMake config module for other users' CMake to find uriparser in the future
    • [x] Make equivalent to Autotools make dist (and make distcheck) work — better ideas than …
      • extensive CPACK_SOURCE_IGNORE_FILES or
      • plain git-archive?
    • [x] Provide and install a pkg-config file on Unix/Linux (using ECMGeneratePkgConfigFile.cmake?)
    • [x] Adapt Travis CI
    • [x] Delete remaining Autotools files
    • [x] Adjust .gitignore

    Later:

    • Fix symbol exports for Windows
    • Leverage CMake to feed AppVeyor CI for Windows coverage
    • support/handle use via add_subdirectory
      • Point to https://wiki.gentoo.org/wiki/Why_not_bundle_dependencies unless warning bypassed, explicitly

    CC: @KangLin @markand @computerquip-streamlabs @jibsen @madmongo1

    enhancement 
    opened by hartwork 38
  • Add CMAKE_CURRENT_SOURCE_DIR prefix to sources

    Add CMAKE_CURRENT_SOURCE_DIR prefix to sources

    When the prefix is missing, installing uriparser from dependent projects causes issues as the files before relative to the parent directories.

    This should fix that by using absolute paths from the prefix.

    bug compilation 
    opened by shehzan10 16
  • uriAddBaseUri seen omitting trailing slash

    uriAddBaseUri seen omitting trailing slash

    Hi - I came across some failing tests in code of mine that uses uriparser, so I reduced them to tests I could add to uriparser's test/test.cpp. I'm probably just not understanding what should be happening according to the spec, but I thought I would ask here.

    At lines 1067 and 1068, https://github.com/uriparser/uriparser/blob/1bd8ae2b8b47d3155765c1ea282a8f9812d3853e/test/test.cpp#L1067-L1068 you see two tests from the spec where the relative uris "../.." and "../../" are added to the base uri. In both cases, the resolved uri should have a final "/", whether or not the relative uri does.

    The following test statements I wrote show that if you add a "." segment within the base uri, then the relative uri still has a final "/" in both cases:

        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"../../", L"http://a/"));
    

    However, the following statements show that if you add a ".." segment within the base uri, then the resolved uri seems to be missing the final "/" if the relative uri does:

        ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/../d;p?q", L"../..", L"http://a/")); // FAILS
        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"../..", L"http://a/")); // FAILS
        ASSERT_TRUE(testAddBaseHelper(L"http://a/b/../c/d;p?q", L"../../", L"http://a/"));
    

    Also note that if the ".." segment is close enough to the authority segment, then the final "/" reappears:

        ASSERT_TRUE(testAddBaseHelper(L"http://a/../b/c/d;p?q", L"../..", L"http://a/")); // SUCCEEDS
        ASSERT_TRUE(testAddBaseHelper(L"http://a/../b/c/d;p?q", L"../../", L"http://a/"));
    

    Am I just doing something wrong here? thanks

    bug 
    opened by danpape 14
  • Integer underflow on

    Integer underflow on "uriToStringCharsRequired()"

    While we are testing libxspf application, we found crash-inducing input and it turned out that the cause may arise from uriparser library. Please check the below report.

    libxspf (1.2.0) and uriparser

    Vulntype: Interger underflow

    Affected component(s)

    uriparser project (uriToStringCharsRequiredA function)

    and then it affects

    libxspf project(makeUriString function),

    Attack vector(s)

    Adversary sends crafted movie playlist file and victim opens it with media player which is using libxspf library (such as VLC player).

    Suggested description of the vulnerability for use in the CVE

    makeUriString() function from Xspf class trusts the return values (i.e., int* charsRequired) from uriparser library; thus assumes positive value.

    However, "uriparser" library's uriToStringCharsRequired() functions returns negative value on crafted URI string such as "http://example.co@" (actually the function should return NULL).

    Due to this integer underflow, the code meets crash with heap alloction failure.

    • libxspf
        XML_Char * makeUriString(UriUri const & uri) {
                XML_Char * uriString;
                int charsRequired;            
                if (uriToStringCharsRequired(&uri, &charsRequired) != URI_SUCCESS) {
                        // the uriparse should have return NULL!
                        return NULL;
                }
                charsRequired++;
                // negative value are inserted to charsRequired (e.g., 0xffffffffff9e5331)
                // allocator error here!
                uriString = new XML_Char[charsRequired];  
                if (uriToString(uriString, &uri, charsRequired, NULL) != URI_SUCCESS) {
                        delete [] uriString;
                        return NULL;
                }
                return uriString;
        }
    

    Discoverer

    Jinho Jung ([email protected], Georgia Institute of Technology)

    Reference

    N/A

    Additional Information

    1. PoC: https://ffs.gtisc.gatech.edu/download/ca3502e783138c47/#WQ_4uRrb_CSkyHvA5fpJMg

    2. How to reproduce

    we use example application from libxspf

    1. find read.cpp file and modify the file name to PoC's
    2. compile and run the read program
    1. Another reproduce
    1. provide bad uri "http://example.co@" to uriToStringCharsRequired()
    2. the function should not return URI_SUCCESS ==> but it assigns negative value on charsRequired
    question 
    opened by jinhojun 13
  • Unit test failure, Child aborted

    Unit test failure, Child aborted

    When I try to run the test suite, it immediately crashes:

    $ make test
    Running tests...
    /Users/Adam/spack/opt/spack/darwin-mojave-x86_64/clang-10.0.1-apple/cmake-3.15.1-2pyamocwigucvikvjvtuonstdv3zdadd/bin/ctest --force-new-ctest-process 
    Test project /private/var/folders/21/hwq39zyj4g36x6zjfyl5l8080000gn/T/pytest-of-Adam/pytest-12/mock-stage0/uriparser-0.9.3-ukpixytfp2y2g4jlwl6gmqdrm5mkyk4c/spack-build
        Start 1: test
    1/1 Test #1: test .............................Child aborted***Exception:   0.01 sec
    
    0% tests passed, 1 tests failed out of 1
    
    Total Test time (real) =   0.02 sec
    
    The following tests FAILED:
    	  1 - test (Child aborted)
    Errors while running CTest
    make: *** [test] Error 8
    

    This is with uriparser 0.9.3, CMake 3.15.1, and Clang 10.0.1 on macOS 10.14.6. Let me know if I can provide you with any more debug info.

    opened by adamjstewart 13
  • [CVE-2021-46141] .hostText memory is not properly duped/freed in uriNormalizeSyntax*, uriMakeOwner*, uriFreeUriMembers* for some URIs

    [CVE-2021-46141] .hostText memory is not properly duped/freed in uriNormalizeSyntax*, uriMakeOwner*, uriFreeUriMembers* for some URIs

    A bug was found within the uriparser. Though it might not be an intended use of the relevant API, the bug can still produce critical issues within a program using uriparser. It would be best if the affected logic is checked beforehand. The bug was found with a fuzzer based on the test-code"TestNormalizeSyntaxMaskRequired"

    _crash log

    ==2151==ERROR: AddressSanitizer: SEGV on unknown address 0x0000004d9be0 (pc 0x00000041ca94 bp 0x000000000000 sp 0x7fff34437d00 T0)
    ==2151==The signal is caused by a WRITE memory access.
        #0 0x41ca94 in __asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType)
        #1 0x493d41 in free 
        #2 0x4c6892 in (anonymous namespace)::countingFree(UriMemoryManagerStruct*, void*)
        #3 0x7fca1c05a4b2 in uriNormalizeSyntaxExMmA_ 
    

    Steps to reproduce:

    1. git clone https://github.com/uriparser/uriparser.git
    2. cd uriparser & mkdir build & cd build
    3. Build cmake -DCMAKE_BUILD_TYPE=Release -DURIPARSER_BUILD_DOCS:BOOL=OFF -DBUILD_SHARED_LIBS:BOOL=ON .. make -j8
    4. Download the attached file(1.cpp)
    5. Build TEST CODE (1.cpp) clang++ -g -fsanitize=address,fuzzer-no-link -o 1 1.cpp -I uriparser/include/ -Luriparser/build -luriparser
    6. Run LD_LIBRARY_PATH=uriparser/build/ ./1

    OS:ubuntu 18.04 uriparser_poc1.tar.gz

    bug security 
    opened by autofuzzoss 11
  • Include google test using CMake integration

    Include google test using CMake integration

    Currently, google test is acquired using the travis build environment. This means that the source component cannot be transparently incorporated into other source builds. The gtest team recommends the following integration method, which removes this issue: Incorporating Gtest Into An Existing CMake Project.

    Would it be possible to use this mechanism in uriparser ?

    enhancement question 
    opened by jgsuess 10
  • Symbol visibility

    Symbol visibility

    Regarding the work-in-progress aspect / current CI failure: https://github.com/google/sanitizers/wiki/AddressSanitizerOneDefinitionRuleViolation

    @myd7349 @KangLin review and testing very welcome, thank you!

    opened by hartwork 8
  • cmake: fix static lib name for MinGW

    cmake: fix static lib name for MinGW

    https://github.com/uriparser/uriparser/pull/64 changed not only dll name but also name of static lib, which lead to wrong extension. This PR fixes extension for static lib with MinGW, while keeping version suffix in dll name.

    bug 
    opened by SpaceIm 7
  • Backport NDEBUG fix to 0.9.3

    Backport NDEBUG fix to 0.9.3

    The NDEBUG issue is breaking for me, as I'm trying to update uriparser on Homebrew, but I do not want to disable tests. Could this be backported to a new tag so I can still work off of releases? If not, when would 0.9.4 be coming?

    opened by jdemilledt 7
  • macOS: Configure does not work on Android with NDK 16 (clang)

    macOS: Configure does not work on Android with NDK 16 (clang)

    I tried to run configure for cross compiling on Android and i get the following:

    checking for a BSD-compatible install... /usr/local/bin/ginstall -c checking whether build environment is sane... yes checking for armv7a-linux-android-strip... no checking for strip... strip checking for a thread-safe mkdir -p... /usr/local/bin/gmkdir -p checking for gawk... no checking for mawk... no checking for nawk... no checking for awk... awk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for armv7a-linux-android-gcc... NDK_ROOT/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang checking whether the C compiler works... no configure: error: in .../openFrameworks/scripts/apothecary/apothecary/build/uriparser': configure: error: C compiler cannot create executables Seeconfig.log' for more details

    The problem is that when checking the compiler, configure tries to pass the CFLAGS to the linker and the "--sysroot" argument is not accepted by clang when linking:

    configure:3253: checking whether the C compiler works configure:3275: NDK_ROOT/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang -nostdlib --sysroot=NDK_ROOT/sysroot -fno-short-enums .... >&5 ld: unknown option: --sysroot=NDK_ROOT/sysroot clang: error: linker command failed with exit code 1 (use -v to see invocation)

    question 
    opened by martinell 7
  • Build shared and static libraries

    Build shared and static libraries

    Hello Sebastian,

    for some reasons we need shared and static libraries (See [1]).

    Can you please implement this?

    CU Jörg

    [1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=996253

    question 
    opened by JoergFF 1
  • Escape URI

    Escape URI

    I need to parse an url before encoding each part separately, since apparently encoding the whole url gives wrong output (http:// is escaped for example). (note I have a Linux based implementation)

    So I first execute uriParseSingleUriA, then execute uriEscapeExA on each URI part (except scheme and host that cannot (should not?) contain escaped characters) If my input url contains a path with spaces (file name with spaces for example) uriParseSingleUriA replies with a syntax errors, pointing to the first space encountered.

    How can I pct-encode that URL if the characters that need to be escaped creates an issue with uriParseSingleUriA?

    In the other hand, if I provide a pct-encoded URL to uriParseSingleUriA, the parsing is OK but escaping the URI parts using uriEscapeExA, it encodes the already encoded parts while I expected the lib would avoid the double escaping. example: http://localhost:8080/resources/file%20with%20space%201kb.bin becomes http://localhost:8080/resources/file%2520with%2520space%25201kb.bin

    I probably lack some advice, please help, thanks!

    question 
    opened by aphasix 1
  • Move -DURI_NO_ANSI and -DURI_NO_UNICODE to config.h?

    Move -DURI_NO_ANSI and -DURI_NO_UNICODE to config.h?

    Related to #47

    Potentially, we could use two files:

    • a private own for things like HAVE_REALLOC that matter during compilation
    • a public one that gets install that has things like URI_NO_ANSI that matter during and after compilation
    enhancement 
    opened by hartwork 0
  • Extended-Length Path In Windows Encoded Differently Than Windows Path

    Extended-Length Path In Windows Encoded Differently Than Windows Path

    An extended-length path in windows is prepended with "\\?\" (for example \\?\c:\windows). As such, uriparser doesn't seem to recognize it as a windows path. It is encoded but not in a typical Windows way.

    My current work-around is to remove "\\?\" before passing in the path to uriWindowsFilenameToUriStringA.

    enhancement windows 
    opened by git-blame 2
  • Incomplete test coverage for UriFile.c

    Incomplete test coverage for UriFile.c

    I redid the tests for UriFile.c for my own use in GoogleTest. In doing so, I noticed that test.cpp doesn't fully cover the compilation unit. You are welcome to take any of my test code and adapt for uriparser. If you aren't interested in the coverage, feel free to close the issue.

    The checks with CheckUriUriStringToWindowsFilenameA are bit chaotic and could use some improvement. The code is only tested with ASCII input as I don't build with wchar_t support.

    I do one test file for each compilation unit rather than a catch all test.cpp.

    Code is copyright Google and donated to uriparser under the uriparser license.

    Here is what I have:

    // Test UriFile.c
    //
    // A = ASCII
    //
    // Many of these test examples show very strange behavior.
    
    #include <cstddef>
    #include <cstring>
    #include <vector>
    
    #include "gtest.h"
    #include "uriparser/Uri.h"
    #include "/uriparser/UriBase.h"
    
    namespace {
    
    TEST(UriUnixFilenameToUriStringA, Nullptr) {
      const char uri[] = "/bin/bash";
      std::vector<char> buf(10);
    
      ASSERT_EQ(URI_ERROR_NULL, uriUnixFilenameToUriStringA(nullptr, &buf[0]));
      ASSERT_EQ(URI_ERROR_NULL, uriUnixFilenameToUriStringA(uri, nullptr));
      ASSERT_EQ(URI_ERROR_NULL, uriUnixFilenameToUriStringA(nullptr, nullptr));
    }
    
    size_t UnixFilenameToUriStringSize(const char *filename) {
      // "file://" plus each character could be expanded to a 3 character percent
      // representation and finishing up with a NUL termination sentinal.
      return 7 + 3 * strlen(filename) + 1;
    }
    
    void CheckUriUnixFilenameToUriStringA(const char *filename, const char *uri) {
      std::vector<char> buf(UnixFilenameToUriStringSize(filename));
      ASSERT_EQ(URI_SUCCESS, uriUnixFilenameToUriStringA(filename, &buf[0]));
      EXPECT_STREQ(uri, &buf[0]) << "For: \"" << filename << "\"";
    }
    
    TEST(UriUnixFilenameToUriStringA, WhiteSpace) {
      CheckUriUnixFilenameToUriStringA("", "");
      CheckUriUnixFilenameToUriStringA(" ", "%20");
      CheckUriUnixFilenameToUriStringA("a b", "a%20b");
      CheckUriUnixFilenameToUriStringA("\t", "%09");
      CheckUriUnixFilenameToUriStringA("\v", "%0B");
      CheckUriUnixFilenameToUriStringA("\n", "%0A");
      CheckUriUnixFilenameToUriStringA("\r", "%0D");
      CheckUriUnixFilenameToUriStringA("\r\n", "%0D%0A");
    }
    
    TEST(UriUnixFilenameToUriStringA, Slashes) {
      CheckUriUnixFilenameToUriStringA("/", "file:///");
      CheckUriUnixFilenameToUriStringA("/a", "file:///a");
      CheckUriUnixFilenameToUriStringA("/b/", "file:///b/");
      CheckUriUnixFilenameToUriStringA("c", "c");
      CheckUriUnixFilenameToUriStringA("d/e", "d/e");
      CheckUriUnixFilenameToUriStringA("f/", "f/");
    
      CheckUriUnixFilenameToUriStringA("//", "file:////");
    
      // DOS style backslash.
      CheckUriUnixFilenameToUriStringA("\\", "%5C");
    }
    
    TEST(UriUnixFilenameToUriStringA, Dots) {
      // "." and ".." are not interpreted in any way.
      CheckUriUnixFilenameToUriStringA(".", ".");
      CheckUriUnixFilenameToUriStringA("..", "..");
      CheckUriUnixFilenameToUriStringA("...", "...");
      CheckUriUnixFilenameToUriStringA("/.", "file:///.");
      CheckUriUnixFilenameToUriStringA("/./", "file:///./");
      CheckUriUnixFilenameToUriStringA("/..", "file:///..");
      CheckUriUnixFilenameToUriStringA("/../", "file:///../");
      CheckUriUnixFilenameToUriStringA("/../a", "file:///../a");
      CheckUriUnixFilenameToUriStringA("/../.b", "file:///../.b");
      CheckUriUnixFilenameToUriStringA("../.c", "../.c");
      CheckUriUnixFilenameToUriStringA("/.././d.e", "file:///.././d.e");
    }
    
    TEST(UriUnixFilenameToUriStringA, WrongWay) {
      CheckUriUnixFilenameToUriStringA("file://", "file%3A//");
    }
    
    size_t UriStringToUnixFilenameSize(const char *uri) {
      // Skip removing the 7.
      return strlen(uri) + 1;
    }
    
    TEST(UriUriStringToUnixFilenameA, Nullptr) {
      const char uri[] = "/a/b";
      std::vector<char> buf(UriStringToUnixFilenameSize(uri));
      EXPECT_EQ(URI_ERROR_NULL, uriUriStringToUnixFilenameA(nullptr, &buf[0]));
      EXPECT_EQ(URI_ERROR_NULL, uriUriStringToUnixFilenameA(uri, nullptr));
      EXPECT_EQ(URI_ERROR_NULL, uriUriStringToUnixFilenameA(nullptr, nullptr));
    }
    
    void CheckUriUriStringToUnixFilenameA(const char *uri, const char *filename) {
      std::vector<char> buf(UriStringToUnixFilenameSize(uri));
      ASSERT_EQ(URI_SUCCESS, uriUriStringToUnixFilenameA(uri, &buf[0]));
      EXPECT_STREQ(filename, &buf[0]) << uri;
    }
    
    TEST(UriUriStringToUnixFilenameA, NoFile) {
      CheckUriUriStringToUnixFilenameA("", "");
      CheckUriUriStringToUnixFilenameA("a", "a");
      CheckUriUriStringToUnixFilenameA("%0A", "\n");
    }
    
    TEST(UriUriStringToUnixFilenameA, WithFile) {
      CheckUriUriStringToUnixFilenameA("file://", "");
      CheckUriUriStringToUnixFilenameA("file:///", "/");
      CheckUriUriStringToUnixFilenameA("file://a", "a");
      CheckUriUriStringToUnixFilenameA("file:///b", "/b");
      CheckUriUriStringToUnixFilenameA("file:///c/", "/c/");
      CheckUriUriStringToUnixFilenameA("file:///d/e", "/d/e");
    }
    
    TEST(UriUriStringToUnixFilenameA, Dots) {
      CheckUriUriStringToUnixFilenameA("file://.", ".");
      CheckUriUriStringToUnixFilenameA("file://..", "..");
      CheckUriUriStringToUnixFilenameA("file:///.", "/.");
      CheckUriUriStringToUnixFilenameA("file:///..", "/..");
    }
    
    TEST(UriWindowsFilenameToUriStringA, Nullptr) {
      const char uri[] = "c:/foo";
      std::vector<char> buf(10);
    
      ASSERT_EQ(URI_ERROR_NULL, uriWindowsFilenameToUriStringA(nullptr, &buf[0]));
      ASSERT_EQ(URI_ERROR_NULL, uriWindowsFilenameToUriStringA(uri, nullptr));
      ASSERT_EQ(URI_ERROR_NULL, uriWindowsFilenameToUriStringA(nullptr, nullptr));
    }
    
    size_t WindowsFilenameToUriStringSize(const char *filename) {
      // "file:///" plus each character could be expanded to a 3 character percent
      // representation and finishing up with a NUL termination sentinal.
      return 8 + 3 * strlen(filename) + 1;
    }
    
    void CheckUriWindowsFilenameToUriStringA(const char *filename,
                                             const char *uri) {
      std::vector<char> buf(WindowsFilenameToUriStringSize(filename));
      ASSERT_EQ(URI_SUCCESS, uriWindowsFilenameToUriStringA(filename, &buf[0]));
      EXPECT_STREQ(uri, &buf[0]) << "For: \"" << filename << "\"";
    }
    
    TEST(UriWindowsFilenameToUriStringA, WhiteSpace) {
      CheckUriWindowsFilenameToUriStringA("", "");
      CheckUriWindowsFilenameToUriStringA(" ", "%20");
      CheckUriWindowsFilenameToUriStringA("a b", "a%20b");
      CheckUriWindowsFilenameToUriStringA("\t", "%09");
      CheckUriWindowsFilenameToUriStringA("\v", "%0B");
      CheckUriWindowsFilenameToUriStringA("\n", "%0A");
      CheckUriWindowsFilenameToUriStringA("\r", "%0D");
      CheckUriWindowsFilenameToUriStringA("\r\n", "%0D%0A");
    }
    
    TEST(UriWindowsFilenameToUriStringA, Slashes) {
      // DOS style backslash.
      CheckUriWindowsFilenameToUriStringA("\\", "/");
      CheckUriWindowsFilenameToUriStringA("\\\\", "file://");  // ?
      CheckUriWindowsFilenameToUriStringA("a:\\", "file:///a:/");
      CheckUriWindowsFilenameToUriStringA("b:\\c", "file:///b:/c");
    
      CheckUriWindowsFilenameToUriStringA("a:\\\\", "file:///a://");
    
      // Unix
      CheckUriWindowsFilenameToUriStringA("/", "%2F");
      CheckUriWindowsFilenameToUriStringA("/a", "%2Fa");
      CheckUriWindowsFilenameToUriStringA("/b/", "%2Fb%2F");
      CheckUriWindowsFilenameToUriStringA("c", "c");
      CheckUriWindowsFilenameToUriStringA("d/e", "d%2Fe");
      CheckUriWindowsFilenameToUriStringA("f/", "f%2F");
    }
    
    size_t UriStringToWindowsFilenameSize(const char *uri) {
      // Skip removing the 5.
      return strlen(uri) + 1;
    }
    
    TEST(UriUriStringToWindowsFilenameA, Nullptr) {
      const char uri[] = "/a/b";
      std::vector<char> buf(UriStringToWindowsFilenameSize(uri));
      EXPECT_EQ(URI_ERROR_NULL, uriUriStringToWindowsFilenameA(nullptr, &buf[0]));
      EXPECT_EQ(URI_ERROR_NULL, uriUriStringToWindowsFilenameA(uri, nullptr));
      EXPECT_EQ(URI_ERROR_NULL, uriUriStringToWindowsFilenameA(nullptr, nullptr));
    }
    
    void CheckUriUriStringToWindowsFilenameA(const char *uri,
                                             const char *filename) {
      std::vector<char> buf(UriStringToWindowsFilenameSize(uri));
      ASSERT_EQ(URI_SUCCESS, uriUriStringToWindowsFilenameA(uri, &buf[0]));
      EXPECT_STREQ(filename, &buf[0]) << "For: \"" << uri << "\"";
    }
    
    TEST(UriUriStringToWindowsFilenameA, NoFile) {
      CheckUriUriStringToWindowsFilenameA("", "");
      CheckUriUriStringToWindowsFilenameA("a", "a");
      CheckUriUriStringToWindowsFilenameA("%0A", "\n");
    }
    
    TEST(UriUriStringToWindowsFilenameA, WithFile) {
      CheckUriUriStringToWindowsFilenameA("file://", "\\\\");
      CheckUriUriStringToWindowsFilenameA("file:///", "");
      CheckUriUriStringToWindowsFilenameA("file://a", "\\\\a");
      CheckUriUriStringToWindowsFilenameA("file:///b", "b");
      CheckUriUriStringToWindowsFilenameA("file:///c/", "c\\");
      CheckUriUriStringToWindowsFilenameA("file:///d/e", "d\\e");
    }
    
    TEST(UriUriStringToWindowsFilenameA, Dots) {
      CheckUriUriStringToWindowsFilenameA("file://.", "\\\\.");
      CheckUriUriStringToWindowsFilenameA("file://..", "\\\\..");
      CheckUriUriStringToWindowsFilenameA("file:///.", ".");
      CheckUriUriStringToWindowsFilenameA("file:///..", "..");
    }
    
    TEST(UriUriStringToWindowsFilenameA, Slashes) {
      // DOS style backslash.
      CheckUriUriStringToWindowsFilenameA("/", "\\");
      CheckUriUriStringToWindowsFilenameA("file://", "\\\\");
      CheckUriUriStringToWindowsFilenameA("file:///a:/", "a:\\");
      CheckUriUriStringToWindowsFilenameA("file:///b:/c", "b:\\c");
    
      CheckUriWindowsFilenameToUriStringA("file:///a://",
                                          "file%3A%2F%2F%2Fa%3A%2F%2F");
    
      // Unix
      CheckUriUriStringToWindowsFilenameA("%2F", "\\");
      CheckUriUriStringToWindowsFilenameA("%2Fa", "\\a");
      CheckUriUriStringToWindowsFilenameA("%2Fb%2F", "\\b\\");
      CheckUriUriStringToWindowsFilenameA("c", "c");
      CheckUriUriStringToWindowsFilenameA("d/e", "d\\e");
      CheckUriUriStringToWindowsFilenameA("f/", "f\\");
    }
    
    }  // namespace
    
    enhancement 
    opened by schwehr 6
Releases(uriparser-0.9.7)
Owner
uriparser
uriparser is a strictly RFC 3986 compliant URI parsing and handling library written in C
uriparser
URI Templates expansion and reverse-matching for C++

URI-template This library implements URI Template with full support up to Level 4 providing expansion and match capabilities. It requires c++17 compil

Tinkoff.ru 7 Jan 21, 2022
cpp-netlib URI

Deprecation warning This library is still missing some features (including full Unicode support), and does not work on some of the newest compiler ver

C++ Network Library 129 Dec 27, 2022
Resolvidos do URI p/ Maratonas

URI_Resolvidos Resolvidos do URI p/ Maratonas Esse repositório contém diversos exercícios do URI, em sua maioria resolvidos, podendo conter um ou outr

null 2 Sep 30, 2021
The C++ Network Library Project -- cross-platform, standards compliant networking library.

C++ Network Library Modern C++ network programming libraries. Join us on Slack: http://slack.cpp-netlib.org/ Subscribe to the mailing list: https://gr

C++ Network Library 1.9k Dec 27, 2022
Simple, secure & standards compliant web server for the most demanding of applications

Simple, secure[1] & standards compliant[2] web server for the most demanding[3] of applications. Read more... ?? Optimized security Being meticulously

uNetworking AB 15k Dec 30, 2022
hotpatching, closures, lambdas, and signal-based exception handling in GNU C

Handy Headers GCC/clang is required for all headers exception.h try/except blocks in C Works with actual signals int main(){ int e; try{ //brackets

null 5 Dec 23, 2022
A simple SIP server (proxy) for handling VoIP calls based on SIP using C++

Sip Server A simple sip server for handling VoIP calls based on sip protocol. Features Registration Of Users The server supports registration process.

null 8 Nov 3, 2022
A forward proxy module for CONNECT request handling

name This module provides support for the CONNECT method request. This method is mainly used to tunnel SSL requests through proxy servers. Table of Co

Xiaochen Wang 1.3k Jan 4, 2023
An HTML5 parsing library in pure C99

Gumbo - A pure-C HTML5 parser. Gumbo is an implementation of the HTML5 parsing algorithm implemented as a pure C99 library with no outside dependencie

Google 5.1k Dec 25, 2022
A lightweight Universal Windows proxy app based on https://github.com/eycorsican/leaf

Maple A lightweight Universal Windows proxy app based on https://github.com/eycorsican/leaf Features Configuration management Outbound network adapter

YtFlow 784 Jan 6, 2023
GTOS (Growtopia Private Server)'s latest source, everyone started selling so I decided to releasing it on github, enjoy it without spending your dls on that.

GTOSLatest GTOS (Growtopia Private Server)'s latest source, everyone started selling so we (Erben#1337 and Kaan#1337) decided to releasing it on githu

Kaan 20 Sep 9, 2022
An easy to use and powerful open source websocket library written in C.

libwebsock Easy to use C library for websockets This library allows for quick and easy development of applications that use the websocket protocol, wi

Jonathan Hall 47 Nov 13, 2022
BingBing 60 Dec 15, 2022
QuantumGate is a peer-to-peer (P2P) communications protocol, library and API written in C++.

About QuantumGate is a peer-to-peer (P2P) communications protocol, library and API. The long-term goal for QuantumGate is to become a platform for dis

Karel Donk 96 Dec 20, 2022
A network library for client/server games written in C++

yojimbo yojimbo is a network library for client/server games written in C++. It's designed around the networking requirements of competitive multiplay

The Network Protocol Company 2.2k Jan 1, 2023
A small, minimal HTTP library written in C.

trail - A small, minimal HTTP library written in C. trail is a small, minimal, and easy-to-use HTTP library written in C that supports GET and POST re

null 7 Nov 20, 2022
A Hidden and Undetectable Remote Access Tool written in C++ and Server in Python3

Spyware-RAT A Hidden and Undetectable Remote Access Tool written in C++ and Server in Python3 This program utilizes the standard winsock library for s

null 44 Dec 25, 2022
2048 written in C and compiled to WebAssembly

2048.wasm 2048 written in C and compiled to WebAssembly Play Use the arrow keys ( ᐊ ᐅ ᐃ ᐁ ) to slide the tiles. press n to play over. Usage Compile C

Nishchith Shetty 48 Nov 1, 2022