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 */