libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

mhd_str.h (30747B)


      1 /*
      2   This file is part of libmicrohttpd
      3   Copyright (C) 2015-2023 Karlson2k (Evgeny Grin)
      4 
      5   This library is free software; you can redistribute it and/or
      6   modify it under the terms of the GNU Lesser General Public
      7   License as published by the Free Software Foundation; either
      8   version 2.1 of the License, or (at your option) any later version.
      9 
     10   This library is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13   Lesser General Public License for more details.
     14 
     15   You should have received a copy of the GNU Lesser General Public
     16   License along with this library; if not, write to the Free Software
     17   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     18 */
     19 
     20 /**
     21  * @file microhttpd/mhd_str.h
     22  * @brief  Header for string manipulating helpers
     23  * @author Karlson2k (Evgeny Grin)
     24  */
     25 
     26 #ifndef MHD_STR_H
     27 #define MHD_STR_H 1
     28 
     29 #include "mhd_options.h"
     30 #include <stdint.h>
     31 #ifdef HAVE_STDDEF_H
     32 #include <stddef.h>
     33 #endif /* HAVE_STDDEF_H */
     34 #ifdef HAVE_SYS_TYPES_H
     35 #include <sys/types.h>
     36 #endif /* HAVE_SYS_TYPES_H */
     37 #ifdef HAVE_STDBOOL_H
     38 #include <stdbool.h>
     39 #endif /* HAVE_STDBOOL_H */
     40 
     41 #include "mhd_str_types.h"
     42 
     43 #if defined(_MSC_FULL_VER) && ! defined(_SSIZE_T_DEFINED)
     44 #define _SSIZE_T_DEFINED
     45 typedef intptr_t ssize_t;
     46 #endif /* !_SSIZE_T_DEFINED */
     47 
     48 #ifdef MHD_FAVOR_SMALL_CODE
     49 #include "mhd_limits.h"
     50 #endif /* MHD_FAVOR_SMALL_CODE */
     51 
     52 /*
     53  * Block of functions/macros that use US-ASCII charset as required by HTTP
     54  * standards. Not affected by current locale settings.
     55  */
     56 
     57 #ifndef MHD_FAVOR_SMALL_CODE
     58 /**
     59  * Check two strings for equality, ignoring case of US-ASCII letters.
     60  *
     61  * @param str1 first string to compare
     62  * @param str2 second string to compare
     63  * @return non-zero if two strings are equal, zero otherwise.
     64  */
     65 int
     66 MHD_str_equal_caseless_ (const char *str1,
     67                          const char *str2);
     68 
     69 #else  /* MHD_FAVOR_SMALL_CODE */
     70 /* Reuse MHD_str_equal_caseless_n_() to reduce size */
     71 #define MHD_str_equal_caseless_(s1,s2) MHD_str_equal_caseless_n_ ((s1),(s2), \
     72                                                                   SIZE_MAX)
     73 #endif /* MHD_FAVOR_SMALL_CODE */
     74 
     75 
     76 /**
     77  * Check two string for equality, ignoring case of US-ASCII letters and
     78  * checking not more than @a maxlen characters.
     79  * Compares up to first terminating null character, but not more than
     80  * first @a maxlen characters.
     81  * @param str1 first string to compare
     82  * @param str2 second string to compare
     83  * @param maxlen maximum number of characters to compare
     84  * @return non-zero if two strings are equal, zero otherwise.
     85  */
     86 int
     87 MHD_str_equal_caseless_n_ (const char *const str1,
     88                            const char *const str2,
     89                            size_t maxlen);
     90 
     91 
     92 /**
     93  * Check two string for equality, ignoring case of US-ASCII letters and
     94  * checking not more than @a len bytes.
     95  * Compares not more first than @a len bytes, including binary zero characters.
     96  * Comparison stops at first unmatched byte.
     97  * @param str1 first string to compare
     98  * @param str2 second string to compare
     99  * @param len number of characters to compare
    100  * @return non-zero if @a len bytes are equal, zero otherwise.
    101  */
    102 bool
    103 MHD_str_equal_caseless_bin_n_ (const char *const str1,
    104                                const char *const str2,
    105                                size_t len);
    106 
    107 
    108 /**
    109  * Check whether string is equal statically allocated another string,
    110  * ignoring case of US-ASCII letters and checking not more than @a len bytes.
    111  *
    112  * If strings have different sizes (lengths) then macro returns boolean false
    113  * without checking the content.
    114  *
    115  * Compares not more first than @a len bytes, including binary zero characters.
    116  * Comparison stops at first unmatched byte.
    117  * @param a the statically allocated string to compare
    118  * @param s the string to compare
    119  * @param len number of characters to compare
    120  * @return non-zero if @a len bytes are equal, zero otherwise.
    121  */
    122 #define MHD_str_equal_caseless_s_bin_n_(a,s,l) \
    123   ((MHD_STATICSTR_LEN_(a) == (l)) \
    124    && MHD_str_equal_caseless_bin_n_(a,s,l))
    125 
    126 /**
    127  * Check whether @a str has case-insensitive @a token.
    128  * Token could be surrounded by spaces and tabs and delimited by comma.
    129  * Match succeed if substring between start, end (of string) or comma
    130  * contains only case-insensitive token and optional spaces and tabs.
    131  * @warning token must not contain null-characters except optional
    132  *          terminating null-character.
    133  * @param str the string to check
    134  * @param token the token to find
    135  * @param token_len length of token, not including optional terminating
    136  *                  null-character.
    137  * @return non-zero if two strings are equal, zero otherwise.
    138  */
    139 bool
    140 MHD_str_has_token_caseless_ (const char *str,
    141                              const char *const token,
    142                              size_t token_len);
    143 
    144 /**
    145  * Check whether @a str has case-insensitive static @a tkn.
    146  * Token could be surrounded by spaces and tabs and delimited by comma.
    147  * Match succeed if substring between start, end of string or comma
    148  * contains only case-insensitive token and optional spaces and tabs.
    149  * @warning tkn must be static string
    150  * @param str the string to check
    151  * @param tkn the static string of token to find
    152  * @return non-zero if two strings are equal, zero otherwise.
    153  */
    154 #define MHD_str_has_s_token_caseless_(str,tkn) \
    155   MHD_str_has_token_caseless_ ((str),(tkn),MHD_STATICSTR_LEN_ (tkn))
    156 
    157 
    158 /**
    159  * Remove case-insensitive @a token from the @a str and put result
    160  * to the output @a buf.
    161  *
    162  * Tokens in @a str could be surrounded by spaces and tabs and delimited by
    163  * comma. The token match succeed if substring between start, end (of string)
    164  * or comma contains only case-insensitive token and optional spaces and tabs.
    165  * The quoted strings and comments are not supported by this function.
    166  *
    167  * The output string is normalised: empty tokens and repeated whitespaces
    168  * are removed, no whitespaces before commas, exactly one space is used after
    169  * each comma.
    170  *
    171  * @param str the string to process
    172  * @param str_len the length of the @a str, not including optional
    173  *                terminating null-character.
    174  * @param token the token to find
    175  * @param token_len the length of @a token, not including optional
    176  *                  terminating null-character.
    177  * @param[out] buf the output buffer, not null-terminated.
    178  * @param[in,out] buf_size pointer to the size variable, at input it
    179  *                         is the size of allocated buffer, at output
    180  *                         it is the size of the resulting string (can
    181  *                         be up to 50% larger than input) or negative value
    182  *                         if there is not enough space for the result
    183  * @return 'true' if token has been removed,
    184  *         'false' otherwise.
    185  */
    186 bool
    187 MHD_str_remove_token_caseless_ (const char *str,
    188                                 size_t str_len,
    189                                 const char *const token,
    190                                 const size_t token_len,
    191                                 char *buf,
    192                                 ssize_t *buf_size);
    193 
    194 
    195 /**
    196  * Perform in-place case-insensitive removal of @a tokens from the @a str.
    197  *
    198  * Token could be surrounded by spaces and tabs and delimited by comma.
    199  * The token match succeed if substring between start, end (of the string), or
    200  * comma contains only case-insensitive token and optional spaces and tabs.
    201  * The quoted strings and comments are not supported by this function.
    202  *
    203  * The input string must be normalised: empty tokens and repeated whitespaces
    204  * are removed, no whitespaces before commas, exactly one space is used after
    205  * each comma. The string is updated in-place.
    206  *
    207  * Behavior is undefined is the input string in not normalised.
    208  *
    209  * @param[in,out] str the string to update
    210  * @param[in,out] str_len the length of the @a str, not including optional
    211  *                        terminating null-character, not null-terminated
    212  * @param tokens the token to find
    213  * @param tokens_len the length of @a tokens, not including optional
    214  *                   terminating null-character.
    215  * @return 'true' if any token has been removed,
    216  *         'false' otherwise.
    217  */
    218 bool
    219 MHD_str_remove_tokens_caseless_ (char *str,
    220                                  size_t *str_len,
    221                                  const char *const tokens,
    222                                  const size_t tokens_len);
    223 
    224 
    225 #ifndef MHD_FAVOR_SMALL_CODE
    226 /* Use individual function for each case to improve speed */
    227 
    228 /**
    229  * Convert decimal US-ASCII digits in string to number in uint64_t.
    230  * Conversion stopped at first non-digit character.
    231  *
    232  * @param str string to convert
    233  * @param[out] out_val pointer to uint64_t to store result of conversion
    234  * @return non-zero number of characters processed on succeed,
    235  *         zero if no digit is found, resulting value is larger
    236  *         then possible to store in uint64_t or @a out_val is NULL
    237  */
    238 size_t
    239 MHD_str_to_uint64_ (const char *str,
    240                     uint64_t *out_val);
    241 
    242 /**
    243  * Convert not more then @a maxlen decimal US-ASCII digits in string to
    244  * number in uint64_t.
    245  * Conversion stopped at first non-digit character or after @a maxlen
    246  * digits.
    247  *
    248  * @param str string to convert
    249  * @param maxlen maximum number of characters to process
    250  * @param[out] out_val pointer to uint64_t to store result of conversion
    251  * @return non-zero number of characters processed on succeed,
    252  *         zero if no digit is found, resulting value is larger
    253  *         then possible to store in uint64_t or @a out_val is NULL
    254  */
    255 size_t
    256 MHD_str_to_uint64_n_ (const char *str,
    257                       size_t maxlen,
    258                       uint64_t *out_val);
    259 
    260 
    261 /**
    262  * Convert hexadecimal US-ASCII digits in string to number in uint32_t.
    263  * Conversion stopped at first non-digit character.
    264  *
    265  * @param str string to convert
    266  * @param[out] out_val pointer to uint32_t to store result of conversion
    267  * @return non-zero number of characters processed on succeed,
    268  *         zero if no digit is found, resulting value is larger
    269  *         then possible to store in uint32_t or @a out_val is NULL
    270  */
    271 size_t
    272 MHD_strx_to_uint32_ (const char *str,
    273                      uint32_t *out_val);
    274 
    275 
    276 /**
    277  * Convert not more then @a maxlen hexadecimal US-ASCII digits in string
    278  * to number in uint32_t.
    279  * Conversion stopped at first non-digit character or after @a maxlen
    280  * digits.
    281  *
    282  * @param str string to convert
    283  * @param maxlen maximum number of characters to process
    284  * @param[out] out_val pointer to uint32_t to store result of conversion
    285  * @return non-zero number of characters processed on succeed,
    286  *         zero if no digit is found, resulting value is larger
    287  *         then possible to store in uint32_t or @a out_val is NULL
    288  */
    289 size_t
    290 MHD_strx_to_uint32_n_ (const char *str,
    291                        size_t maxlen,
    292                        uint32_t *out_val);
    293 
    294 
    295 /**
    296  * Convert hexadecimal US-ASCII digits in string to number in uint64_t.
    297  * Conversion stopped at first non-digit character.
    298  *
    299  * @param str string to convert
    300  * @param[out] out_val pointer to uint64_t to store result of conversion
    301  * @return non-zero number of characters processed on succeed,
    302  *         zero if no digit is found, resulting value is larger
    303  *         then possible to store in uint64_t or @a out_val is NULL
    304  */
    305 size_t
    306 MHD_strx_to_uint64_ (const char *str,
    307                      uint64_t *out_val);
    308 
    309 
    310 /**
    311  * Convert not more then @a maxlen hexadecimal US-ASCII digits in string
    312  * to number in uint64_t.
    313  * Conversion stopped at first non-digit character or after @a maxlen
    314  * digits.
    315  *
    316  * @param str string to convert
    317  * @param maxlen maximum number of characters to process
    318  * @param[out] out_val pointer to uint64_t to store result of conversion
    319  * @return non-zero number of characters processed on succeed,
    320  *         zero if no digit is found, resulting value is larger
    321  *         then possible to store in uint64_t or @a out_val is NULL
    322  */
    323 size_t
    324 MHD_strx_to_uint64_n_ (const char *str,
    325                        size_t maxlen,
    326                        uint64_t *out_val);
    327 
    328 #else  /* MHD_FAVOR_SMALL_CODE */
    329 /* Use one universal function and macros to reduce size */
    330 
    331 /**
    332  * Generic function for converting not more then @a maxlen
    333  * hexadecimal or decimal US-ASCII digits in string to number.
    334  * Conversion stopped at first non-digit character or after @a maxlen
    335  * digits.
    336  * To be used only within macro.
    337  *
    338  * @param str the string to convert
    339  * @param maxlen the maximum number of characters to process
    340  * @param out_val the pointer to variable to store result of conversion
    341  * @param val_size the size of variable pointed by @a out_val, in bytes, 4 or 8
    342  * @param max_val the maximum decoded number
    343  * @param base the numeric base, 10 or 16
    344  * @return non-zero number of characters processed on succeed,
    345  *         zero if no digit is found, resulting value is larger
    346  *         then @a max_val, @a val_size is not 4/8 or @a out_val is NULL
    347  */
    348 size_t
    349 MHD_str_to_uvalue_n_ (const char *str,
    350                       size_t maxlen,
    351                       void *out_val,
    352                       size_t val_size,
    353                       uint64_t max_val,
    354                       unsigned int base);
    355 
    356 #define MHD_str_to_uint64_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
    357                                                        sizeof(uint64_t), \
    358                                                        UINT64_MAX,10)
    359 
    360 #define MHD_str_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
    361                                                             sizeof(uint64_t), \
    362                                                             UINT64_MAX,10)
    363 
    364 #define MHD_strx_to_sizet_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
    365                                                        sizeof(size_t),SIZE_MAX, \
    366                                                        16)
    367 
    368 #define MHD_strx_to_sizet_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
    369                                                             sizeof(size_t), \
    370                                                             SIZE_MAX,16)
    371 
    372 #define MHD_strx_to_uint32_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
    373                                                         sizeof(uint32_t), \
    374                                                         UINT32_MAX,16)
    375 
    376 #define MHD_strx_to_uint32_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
    377                                                              sizeof(uint32_t), \
    378                                                              UINT32_MAX,16)
    379 
    380 #define MHD_strx_to_uint64_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
    381                                                         sizeof(uint64_t), \
    382                                                         UINT64_MAX,16)
    383 
    384 #define MHD_strx_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
    385                                                              sizeof(uint64_t), \
    386                                                              UINT64_MAX,16)
    387 
    388 #endif /* MHD_FAVOR_SMALL_CODE */
    389 
    390 
    391 /**
    392  * Convert uint32_t value to hexdecimal US-ASCII string.
    393  * @note: result is NOT zero-terminated.
    394  * @param val the value to convert
    395  * @param buf the buffer to result to
    396  * @param buf_size size of the @a buffer
    397  * @return number of characters has been put to the @a buf,
    398  *         zero if buffer is too small (buffer may be modified).
    399  */
    400 size_t
    401 MHD_uint32_to_strx (uint32_t val,
    402                     char *buf,
    403                     size_t buf_size);
    404 
    405 
    406 #ifndef MHD_FAVOR_SMALL_CODE
    407 /**
    408  * Convert uint16_t value to decimal US-ASCII string.
    409  * @note: result is NOT zero-terminated.
    410  * @param val the value to convert
    411  * @param buf the buffer to result to
    412  * @param buf_size size of the @a buffer
    413  * @return number of characters has been put to the @a buf,
    414  *         zero if buffer is too small (buffer may be modified).
    415  */
    416 size_t
    417 MHD_uint16_to_str (uint16_t val,
    418                    char *buf,
    419                    size_t buf_size);
    420 
    421 #else  /* MHD_FAVOR_SMALL_CODE */
    422 #define MHD_uint16_to_str(v,b,s) MHD_uint64_to_str(v,b,s)
    423 #endif /* MHD_FAVOR_SMALL_CODE */
    424 
    425 
    426 /**
    427  * Convert uint64_t value to decimal US-ASCII string.
    428  * @note: result is NOT zero-terminated.
    429  * @param val the value to convert
    430  * @param buf the buffer to result to
    431  * @param buf_size size of the @a buffer
    432  * @return number of characters has been put to the @a buf,
    433  *         zero if buffer is too small (buffer may be modified).
    434  */
    435 size_t
    436 MHD_uint64_to_str (uint64_t val,
    437                    char *buf,
    438                    size_t buf_size);
    439 
    440 
    441 /**
    442  * Convert uint16_t value to decimal US-ASCII string padded with
    443  * zeros on the left side.
    444  *
    445  * @note: result is NOT zero-terminated.
    446  * @param val the value to convert
    447  * @param min_digits the minimal number of digits to print,
    448  *                   output padded with zeros on the left side,
    449  *                   'zero' value is interpreted as 'one',
    450  *                   valid values are 3, 2, 1, 0
    451  * @param buf the buffer to result to
    452  * @param buf_size size of the @a buffer
    453  * @return number of characters has been put to the @a buf,
    454  *         zero if buffer is too small (buffer may be modified).
    455  */
    456 size_t
    457 MHD_uint8_to_str_pad (uint8_t val,
    458                       uint8_t min_digits,
    459                       char *buf,
    460                       size_t buf_size);
    461 
    462 
    463 /**
    464  * Convert @a size bytes from input binary data to lower case
    465  * hexadecimal digits.
    466  * Result is NOT zero-terminated
    467  * @param bin the pointer to the binary data to convert
    468  * @param size the size in bytes of the binary data to convert
    469  * @param[out] hex the output buffer, should be at least 2 * @a size
    470  * @return The number of characters written to the output buffer.
    471  */
    472 size_t
    473 MHD_bin_to_hex (const void *bin,
    474                 size_t size,
    475                 char *hex);
    476 
    477 /**
    478  * Convert @a size bytes from input binary data to lower case
    479  * hexadecimal digits, zero-terminate the result.
    480  * @param bin the pointer to the binary data to convert
    481  * @param size the size in bytes of the binary data to convert
    482  * @param[out] hex the output buffer, should be at least 2 * @a size + 1
    483  * @return The number of characters written to the output buffer,
    484  *         not including terminating zero.
    485  */
    486 size_t
    487 MHD_bin_to_hex_z (const void *bin,
    488                   size_t size,
    489                   char *hex);
    490 
    491 /**
    492  * Convert hexadecimal digits to binary data.
    493  *
    494  * The input decoded byte-by-byte (each byte is two hexadecimal digits).
    495  * If length is an odd number, extra leading zero is assumed.
    496  *
    497  * @param hex the input string with hexadecimal digits
    498  * @param len the length of the input string
    499  * @param[out] bin the output buffer, must be at least len/2 bytes long (or
    500  *                 len/2 + 1 if @a len is not even number)
    501  * @return the number of bytes written to the output buffer,
    502  *         zero if found any character which is not hexadecimal digits
    503  */
    504 size_t
    505 MHD_hex_to_bin (const char *hex,
    506                 size_t len,
    507                 void *bin);
    508 
    509 /**
    510  * Decode string with percent-encoded characters as defined by
    511  * RFC 3986 #section-2.1.
    512  *
    513  * This function decode string by converting percent-encoded characters to
    514  * their decoded versions and copying all other characters without extra
    515  * processing.
    516  *
    517  * @param pct_encoded the input string to be decoded
    518  * @param pct_encoded_len the length of the @a pct_encoded
    519  * @param[out] decoded the output buffer, NOT zero-terminated, can point
    520  *                     to the same buffer as @a pct_encoded
    521  * @param buf_size the size of the output buffer
    522  * @return the number of characters written to the output buffer or
    523  *         zero if any percent-encoded characters is broken ('%' followed
    524  *         by less than two hexadecimal digits) or output buffer is too
    525  *         small to hold the result
    526  */
    527 size_t
    528 MHD_str_pct_decode_strict_n_ (const char *pct_encoded,
    529                               size_t pct_encoded_len,
    530                               char *decoded,
    531                               size_t buf_size);
    532 
    533 /**
    534  * Decode string with percent-encoded characters as defined by
    535  * RFC 3986 #section-2.1.
    536  *
    537  * This function decode string by converting percent-encoded characters to
    538  * their decoded versions and copying all other characters without extra
    539  * processing.
    540  *
    541  * Any invalid percent-encoding sequences ('%' symbol not followed by two
    542  * valid hexadecimal digits) are copied to the output string without decoding.
    543  *
    544  * @param pct_encoded the input string to be decoded
    545  * @param pct_encoded_len the length of the @a pct_encoded
    546  * @param[out] decoded the output buffer, NOT zero-terminated, can point
    547  *                     to the same buffer as @a pct_encoded
    548  * @param buf_size the size of the output buffer
    549  * @param[out] broken_encoding will be set to true if any '%' symbol is not
    550  *                             followed by two valid hexadecimal digits,
    551  *                             optional, can be NULL
    552  * @return the number of characters written to the output buffer or
    553  *         zero if output buffer is too small to hold the result
    554  */
    555 size_t
    556 MHD_str_pct_decode_lenient_n_ (const char *pct_encoded,
    557                                size_t pct_encoded_len,
    558                                char *decoded,
    559                                size_t buf_size,
    560                                bool *broken_encoding);
    561 
    562 
    563 /**
    564  * Decode string in-place with percent-encoded characters as defined by
    565  * RFC 3986 #section-2.1.
    566  *
    567  * This function decode string by converting percent-encoded characters to
    568  * their decoded versions and copying back all other characters without extra
    569  * processing.
    570  *
    571  * @param[in,out] str the string to be updated in-place, must be zero-terminated
    572  *                    on input, the output is zero-terminated; the string is
    573  *                    truncated to zero length if broken encoding is found
    574  * @return the number of character in decoded string
    575  */
    576 size_t
    577 MHD_str_pct_decode_in_place_strict_ (char *str);
    578 
    579 
    580 /**
    581  * Decode string in-place with percent-encoded characters as defined by
    582  * RFC 3986 #section-2.1.
    583  *
    584  * This function decode string by converting percent-encoded characters to
    585  * their decoded versions and copying back all other characters without extra
    586  * processing.
    587  *
    588  * Any invalid percent-encoding sequences ('%' symbol not followed by two
    589  * valid hexadecimal digits) are copied to the output string without decoding.
    590  *
    591  * @param[in,out] str the string to be updated in-place, must be zero-terminated
    592  *                    on input, the output is zero-terminated
    593  * @param[out] broken_encoding will be set to true if any '%' symbol is not
    594  *                             followed by two valid hexadecimal digits,
    595  *                             optional, can be NULL
    596  * @return the number of character in decoded string
    597  */
    598 size_t
    599 MHD_str_pct_decode_in_place_lenient_ (char *str,
    600                                       bool *broken_encoding);
    601 
    602 #ifdef DAUTH_SUPPORT
    603 /**
    604  * Check two strings for equality, "unquoting" the first string from quoted
    605  * form as specified by RFC7230#section-3.2.6 and RFC7694#quoted.strings.
    606  *
    607  * Null-termination for input strings is not required, binary zeros compared
    608  * like other characters.
    609  *
    610  * @param quoted the quoted string to compare, must NOT include leading and
    611  *               closing DQUOTE chars, does not need to be zero-terminated
    612  * @param quoted_len the length in chars of the @a quoted string
    613  * @param unquoted the unquoted string to compare, does not need to be
    614  *                 zero-terminated
    615  * @param unquoted_len the length in chars of the @a unquoted string
    616  * @return zero if quoted form is broken (no character after the last escaping
    617  *         backslash), zero if strings are not equal after unquoting of the
    618  *         first string,
    619  *         non-zero if two strings are equal after unquoting of the
    620  *         first string.
    621  */
    622 bool
    623 MHD_str_equal_quoted_bin_n (const char *quoted,
    624                             size_t quoted_len,
    625                             const char *unquoted,
    626                             size_t unquoted_len);
    627 
    628 /**
    629  * Check whether the string after "unquoting" equals static string.
    630  *
    631  * Null-termination for input string is not required, binary zeros compared
    632  * like other characters.
    633  *
    634  * @param q the quoted string to compare, must NOT include leading and
    635  *          closing DQUOTE chars, does not need to be zero-terminated
    636  * @param l the length in chars of the @a q string
    637  * @param u the unquoted static string to compare
    638  * @return zero if quoted form is broken (no character after the last escaping
    639  *         backslash), zero if strings are not equal after unquoting of the
    640  *         first string,
    641  *         non-zero if two strings are equal after unquoting of the
    642  *         first string.
    643  */
    644 #define MHD_str_equal_quoted_s_bin_n(q,l,u) \
    645     MHD_str_equal_quoted_bin_n(q,l,u,MHD_STATICSTR_LEN_(u))
    646 
    647 /**
    648  * Check two strings for equality, "unquoting" the first string from quoted
    649  * form as specified by RFC7230#section-3.2.6 and RFC7694#quoted.strings and
    650  * ignoring case of US-ASCII letters.
    651  *
    652  * Null-termination for input strings is not required, binary zeros compared
    653  * like other characters.
    654  *
    655  * @param quoted the quoted string to compare, must NOT include leading and
    656  *               closing DQUOTE chars, does not need to be zero-terminated
    657  * @param quoted_len the length in chars of the @a quoted string
    658  * @param unquoted the unquoted string to compare, does not need to be
    659  *                 zero-terminated
    660  * @param unquoted_len the length in chars of the @a unquoted string
    661  * @return zero if quoted form is broken (no character after the last escaping
    662  *         backslash), zero if strings are not equal after unquoting of the
    663  *         first string,
    664  *         non-zero if two strings are caseless equal after unquoting of the
    665  *         first string.
    666  */
    667 bool
    668 MHD_str_equal_caseless_quoted_bin_n (const char *quoted,
    669                                      size_t quoted_len,
    670                                      const char *unquoted,
    671                                      size_t unquoted_len);
    672 
    673 /**
    674  * Check whether the string after "unquoting" equals static string, ignoring
    675  * case of US-ASCII letters.
    676  *
    677  * Null-termination for input string is not required, binary zeros compared
    678  * like other characters.
    679  *
    680  * @param q the quoted string to compare, must NOT include leading and
    681  *          closing DQUOTE chars, does not need to be zero-terminated
    682  * @param l the length in chars of the @a q string
    683  * @param u the unquoted static string to compare
    684  * @return zero if quoted form is broken (no character after the last escaping
    685  *         backslash), zero if strings are not equal after unquoting of the
    686  *         first string,
    687  *         non-zero if two strings are caseless equal after unquoting of the
    688  *         first string.
    689  */
    690 #define MHD_str_equal_caseless_quoted_s_bin_n(q,l,u) \
    691     MHD_str_equal_caseless_quoted_bin_n(q,l,u,MHD_STATICSTR_LEN_(u))
    692 
    693 /**
    694  * Convert string from quoted to unquoted form as specified by
    695  * RFC7230#section-3.2.6 and RFC7694#quoted.strings.
    696  *
    697  * @param quoted the quoted string, must NOT include leading and closing
    698  *               DQUOTE chars, does not need to be zero-terminated
    699  * @param quoted_len the length in chars of the @a quoted string
    700  * @param[out] result the pointer to the buffer to put the result, must
    701  *                    be at least @a size character long. May be modified even
    702  *                    if @a quoted is invalid sequence. The result is NOT
    703  *                    zero-terminated.
    704  * @return The number of characters written to the output buffer,
    705  *         zero if last backslash is not followed by any character (or
    706  *         @a quoted_len is zero).
    707  */
    708 size_t
    709 MHD_str_unquote (const char *quoted,
    710                  size_t quoted_len,
    711                  char *result);
    712 
    713 #endif /* DAUTH_SUPPORT */
    714 
    715 #if defined(DAUTH_SUPPORT) || defined(BAUTH_SUPPORT)
    716 
    717 /**
    718  * Convert string from unquoted to quoted form as specified by
    719  * RFC7230#section-3.2.6 and RFC7694#quoted.strings.
    720  *
    721  * @param unquoted the unquoted string, does not need to be zero-terminated
    722  * @param unquoted_len the length in chars of the @a unquoted string
    723  * @param[out] result the pointer to the buffer to put the result. May be
    724  *                    modified even if function failed due to insufficient
    725  *                    space. The result is NOT zero-terminated and does not
    726  *                    have opening and closing DQUOTE chars.
    727  * @param buf_size the size of the allocated memory for @a result
    728  * @return The number of copied characters, can be up to two times more than
    729  *         @a unquoted_len, zero if @a unquoted_len is zero or if quoted
    730  *         string is larger than @a buf_size.
    731  */
    732 size_t
    733 MHD_str_quote (const char *unquoted,
    734                size_t unquoted_len,
    735                char *result,
    736                size_t buf_size);
    737 
    738 #endif /* DAUTH_SUPPORT || BAUTH_SUPPORT */
    739 
    740 #ifdef BAUTH_SUPPORT
    741 
    742 /**
    743  * Returns the maximum possible size of the Base64 decoded data.
    744  * The real recoded size could be up to two bytes smaller.
    745  * @param enc_size the size of encoded data, in characters
    746  * @return the maximum possible size of the decoded data, in bytes, if
    747  *         @a enc_size is valid (properly padded),
    748  *         undefined value smaller then @a enc_size if @a enc_size is not valid
    749  */
    750 #define MHD_base64_max_dec_size_(enc_size) (((enc_size) / 4) * 3)
    751 
    752 /**
    753  * Convert Base64 encoded string to binary data.
    754  * @param base64 the input string with Base64 encoded data, could be NOT zero
    755  *               terminated
    756  * @param base64_len the number of characters to decode in @a base64 string,
    757  *                   valid number must be a multiple of four
    758  * @param[out] bin the pointer to the output buffer, the buffer may be altered
    759  *                 even if decoding failed
    760  * @param bin_size the size of the @a bin buffer in bytes, if the size is
    761  *                 at least @a base64_len / 4 * 3 then result will always
    762  *                 fit, regardless of the amount of the padding characters
    763  * @return 0 if @a base64_len is zero, or input string has wrong data (not
    764  *         valid Base64 sequence), or @a bin_size is too small;
    765  *         non-zero number of bytes written to the @a bin, the number must be
    766  *         (base64_len / 4 * 3 - 2), (base64_len / 4 * 3 - 1) or
    767  *         (base64_len / 4 * 3), depending on the number of padding characters.
    768  */
    769 size_t
    770 MHD_base64_to_bin_n (const char *base64,
    771                      size_t base64_len,
    772                      void *bin,
    773                      size_t bin_size);
    774 
    775 #endif /* BAUTH_SUPPORT */
    776 
    777 #endif /* MHD_STR_H */