0.00% Lines (0/22)
0.00% Functions (0/2)
| TLA | Baseline | Branch | ||||||
|---|---|---|---|---|---|---|---|---|
| Line | Hits | Code | Line | Hits | Code | |||
| 1 | // | 1 | // | |||||
| 2 | // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com) | 2 | // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com) | |||||
| 3 | // | 3 | // | |||||
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |||||
| 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |||||
| 6 | // | 6 | // | |||||
| 7 | // Official repository: https://github.com/cppalliance/http | 7 | // Official repository: https://github.com/cppalliance/http | |||||
| 8 | // | 8 | // | |||||
| 9 | 9 | |||||||
| 10 | #include <boost/http/server/encode_url.hpp> | 10 | #include <boost/http/server/encode_url.hpp> | |||||
| 11 | 11 | |||||||
| 12 | namespace boost { | 12 | namespace boost { | |||||
| 13 | namespace http { | 13 | namespace http { | |||||
| 14 | 14 | |||||||
| 15 | namespace { | 15 | namespace { | |||||
| 16 | 16 | |||||||
| 17 | // Check if character needs encoding | 17 | // Check if character needs encoding | |||||
| 18 | // Unreserved + reserved chars that are allowed in URLs | 18 | // Unreserved + reserved chars that are allowed in URLs | |||||
| 19 | bool | 19 | bool | |||||
| MISUBC | 20 | ✗ | is_safe( char c ) noexcept | 20 | ✗ | is_safe( char c ) noexcept | ||
| 21 | { | 21 | { | |||||
| 22 | // Unreserved: A-Z a-z 0-9 - _ . ~ | 22 | // Unreserved: A-Z a-z 0-9 - _ . ~ | |||||
| MISUBC | 23 | ✗ | if( ( c >= 'A' && c <= 'Z' ) || | 23 | ✗ | if( ( c >= 'A' && c <= 'Z' ) || | ||
| MISUBC | 24 | ✗ | ( c >= 'a' && c <= 'z' ) || | 24 | ✗ | ( c >= 'a' && c <= 'z' ) || | ||
| MISUBC | 25 | ✗ | ( c >= '0' && c <= '9' ) || | 25 | ✗ | ( c >= '0' && c <= '9' ) || | ||
| MISUBC | 26 | ✗ | c == '-' || c == '_' || c == '.' || c == '~' ) | 26 | ✗ | c == '-' || c == '_' || c == '.' || c == '~' ) | ||
| MISUBC | 27 | ✗ | return true; | 27 | ✗ | return true; | ||
| 28 | 28 | |||||||
| 29 | // Reserved chars allowed in URLs: ! # $ & ' ( ) * + , / : ; = ? @ | 29 | // Reserved chars allowed in URLs: ! # $ & ' ( ) * + , / : ; = ? @ | |||||
| MISUBC | 30 | ✗ | switch( c ) | 30 | ✗ | switch( c ) | ||
| 31 | { | 31 | { | |||||
| MISUBC | 32 | ✗ | case '!': | 32 | ✗ | case '!': | ||
| 33 | case '#': | 33 | case '#': | |||||
| 34 | case '$': | 34 | case '$': | |||||
| 35 | case '&': | 35 | case '&': | |||||
| 36 | case '\'': | 36 | case '\'': | |||||
| 37 | case '(': | 37 | case '(': | |||||
| 38 | case ')': | 38 | case ')': | |||||
| 39 | case '*': | 39 | case '*': | |||||
| 40 | case '+': | 40 | case '+': | |||||
| 41 | case ',': | 41 | case ',': | |||||
| 42 | case '/': | 42 | case '/': | |||||
| 43 | case ':': | 43 | case ':': | |||||
| 44 | case ';': | 44 | case ';': | |||||
| 45 | case '=': | 45 | case '=': | |||||
| 46 | case '?': | 46 | case '?': | |||||
| 47 | case '@': | 47 | case '@': | |||||
| MISUBC | 48 | ✗ | return true; | 48 | ✗ | return true; | ||
| MISUBC | 49 | ✗ | default: | 49 | ✗ | default: | ||
| MISUBC | 50 | ✗ | return false; | 50 | ✗ | return false; | ||
| 51 | } | 51 | } | |||||
| 52 | } | 52 | } | |||||
| 53 | 53 | |||||||
| 54 | constexpr char hex_chars[] = "0123456789ABCDEF"; | 54 | constexpr char hex_chars[] = "0123456789ABCDEF"; | |||||
| 55 | 55 | |||||||
| 56 | } // (anon) | 56 | } // (anon) | |||||
| 57 | 57 | |||||||
| 58 | std::string | 58 | std::string | |||||
| MISUBC | 59 | ✗ | encode_url( core::string_view url ) | 59 | ✗ | encode_url( core::string_view url ) | ||
| 60 | { | 60 | { | |||||
| MISUBC | 61 | ✗ | std::string result; | 61 | ✗ | std::string result; | ||
| MISUBC | 62 | ✗ | result.reserve( url.size() ); | 62 | ✗ | result.reserve( url.size() ); | ||
| 63 | 63 | |||||||
| MISUBC | 64 | ✗ | for( unsigned char c : url ) | 64 | ✗ | for( unsigned char c : url ) | ||
| 65 | { | 65 | { | |||||
| MISUBC | 66 | ✗ | if( is_safe( static_cast<char>( c ) ) ) | 66 | ✗ | if( is_safe( static_cast<char>( c ) ) ) | ||
| 67 | { | 67 | { | |||||
| MISUBC | 68 | ✗ | result.push_back( static_cast<char>( c ) ); | 68 | ✗ | result.push_back( static_cast<char>( c ) ); | ||
| 69 | } | 69 | } | |||||
| 70 | else | 70 | else | |||||
| 71 | { | 71 | { | |||||
| MISUBC | 72 | ✗ | result.push_back( '%' ); | 72 | ✗ | result.push_back( '%' ); | ||
| MISUBC | 73 | ✗ | result.push_back( hex_chars[c >> 4] ); | 73 | ✗ | result.push_back( hex_chars[c >> 4] ); | ||
| MISUBC | 74 | ✗ | result.push_back( hex_chars[c & 0x0F] ); | 74 | ✗ | result.push_back( hex_chars[c & 0x0F] ); | ||
| 75 | } | 75 | } | |||||
| 76 | } | 76 | } | |||||
| 77 | 77 | |||||||
| MISUBC | 78 | ✗ | return result; | 78 | ✗ | return result; | ||
| MISUBC | 79 | ✗ | } | 79 | ✗ | } | ||
| 80 | 80 | |||||||
| 81 | } // http | 81 | } // http | |||||
| 82 | } // boost | 82 | } // boost | |||||