1 /* MIT License 2 * 3 * Copyright (c) 2023 Brad House 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * of this software and associated documentation files (the "Software"), to deal 7 * in the Software without restriction, including without limitation the rights 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 * copies of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 * SPDX-License-Identifier: MIT 25 */ 26 #ifndef __ARES__BUF_H 27 #define __ARES__BUF_H 28 29 #include "ares.h" 30 #include "ares_array.h" 31 32 /*! \addtogroup ares_buf Safe Data Builder and buffer 33 * 34 * This is a buffer building and parsing framework with a focus on security over 35 * performance. All data to be read from the buffer will perform explicit length 36 * validation and return a success/fail result. There are also various helpers 37 * for writing data to the buffer which dynamically grows. 38 * 39 * All operations that fetch or consume data from the buffer will move forward 40 * the internal pointer, thus marking the data as processed which may no longer 41 * be accessible after certain operations (such as append). 42 * 43 * The helpers for this object are meant to be added as needed. If you can't 44 * find it, write it! 45 * 46 * @{ 47 */ 48 struct ares_buf; 49 50 /*! Opaque data type for generic hash table implementation */ 51 typedef struct ares_buf ares_buf_t; 52 53 /*! Create a new buffer object that dynamically allocates buffers for data. 54 * 55 * \return initialized buffer object or NULL if out of memory. 56 */ 57 CARES_EXTERN ares_buf_t *ares_buf_create(void); 58 59 /*! Create a new buffer object that uses a user-provided data pointer. The 60 * data provided will not be manipulated, and cannot be appended to. This 61 * is strictly used for parsing. 62 * 63 * \param[in] data Data to provide to buffer, must not be NULL. 64 * \param[in] data_len Size of buffer provided, must be > 0 65 * 66 * \return initialized buffer object or NULL if out of memory or misuse. 67 */ 68 CARES_EXTERN ares_buf_t *ares_buf_create_const(const unsigned char *data, 69 size_t data_len); 70 71 72 /*! Destroy an initialized buffer object. 73 * 74 * \param[in] buf Initialized buf object 75 */ 76 CARES_EXTERN void ares_buf_destroy(ares_buf_t *buf); 77 78 79 /*! Append multiple bytes to a dynamic buffer object 80 * 81 * \param[in] buf Initialized buffer object 82 * \param[in] data Data to copy to buffer object 83 * \param[in] data_len Length of data to copy to buffer object. 84 * \return ARES_SUCCESS or one of the c-ares error codes 85 */ 86 CARES_EXTERN ares_status_t ares_buf_append(ares_buf_t *buf, 87 const unsigned char *data, 88 size_t data_len); 89 90 /*! Append a single byte to the dynamic buffer object 91 * 92 * \param[in] buf Initialized buffer object 93 * \param[in] b Single byte to append to buffer object. 94 * \return ARES_SUCCESS or one of the c-ares error codes 95 */ 96 CARES_EXTERN ares_status_t ares_buf_append_byte(ares_buf_t *buf, 97 unsigned char b); 98 99 /*! Append a null-terminated string to the dynamic buffer object 100 * 101 * \param[in] buf Initialized buffer object 102 * \param[in] str String to append to buffer object. 103 * \return ARES_SUCCESS or one of the c-ares error codes 104 */ 105 CARES_EXTERN ares_status_t ares_buf_append_str(ares_buf_t *buf, 106 const char *str); 107 108 /*! Append a 16bit Big Endian number to the buffer. 109 * 110 * \param[in] buf Initialized buffer object 111 * \param[out] u16 16bit integer 112 * \return ARES_SUCCESS or one of the c-ares error codes 113 */ 114 CARES_EXTERN ares_status_t ares_buf_append_be16(ares_buf_t *buf, 115 unsigned short u16); 116 117 /*! Append a 32bit Big Endian number to the buffer. 118 * 119 * \param[in] buf Initialized buffer object 120 * \param[out] u32 32bit integer 121 * \return ARES_SUCCESS or one of the c-ares error codes 122 */ 123 CARES_EXTERN ares_status_t ares_buf_append_be32(ares_buf_t *buf, 124 unsigned int u32); 125 126 /*! Append a number in ASCII decimal form. 127 * 128 * \param[in] buf Initialized buffer object 129 * \param[in] num Number to print 130 * \param[in] len Length to output, use 0 for no padding 131 * \return ARES_SUCCESS on success 132 */ 133 CARES_EXTERN ares_status_t ares_buf_append_num_dec(ares_buf_t *buf, size_t num, 134 size_t len); 135 136 /*! Append a number in ASCII hexadecimal form. 137 * 138 * \param[in] buf Initialized buffer object 139 * \param[in] num Number to print 140 * \param[in] len Length to output, use 0 for no padding 141 * \return ARES_SUCCESS on success 142 */ 143 CARES_EXTERN ares_status_t ares_buf_append_num_hex(ares_buf_t *buf, size_t num, 144 size_t len); 145 146 /*! Sets the current buffer length. This *may* be used if there is a need to 147 * override a prior position in the buffer, such as if there is a length 148 * prefix that isn't easily predictable, and you must go back and overwrite 149 * that position. 150 * 151 * Only valid on non-const buffers. Length provided must not exceed current 152 * allocated buffer size, but otherwise there are very few protections on 153 * this function. Use cautiously. 154 * 155 * \param[in] buf Initialized buffer object 156 * \param[in] len Length to set 157 * \return ARES_SUCCESS or one of the c-ares error codes 158 */ 159 CARES_EXTERN ares_status_t ares_buf_set_length(ares_buf_t *buf, size_t len); 160 161 162 /*! Start a dynamic append operation that returns a buffer suitable for 163 * writing. A desired minimum length is passed in, and the actual allocated 164 * buffer size is returned which may be greater than the requested size. 165 * No operation other than ares_buf_append_finish() is allowed on the 166 * buffer after this request. 167 * 168 * \param[in] buf Initialized buffer object 169 * \param[in,out] len Desired non-zero length passed in, actual buffer size 170 * returned. 171 * \return Pointer to writable buffer or NULL on failure (usage, out of mem) 172 */ 173 CARES_EXTERN unsigned char *ares_buf_append_start(ares_buf_t *buf, size_t *len); 174 175 /*! Finish a dynamic append operation. Called after 176 * ares_buf_append_start() once desired data is written. 177 * 178 * \param[in] buf Initialized buffer object. 179 * \param[in] len Length of data written. May be zero to terminate 180 * operation. Must not be greater than returned from 181 * ares_buf_append_start(). 182 */ 183 CARES_EXTERN void ares_buf_append_finish(ares_buf_t *buf, size_t len); 184 185 /*! Write the data provided to the buffer in a hexdump format. 186 * 187 * \param[in] buf Initialized buffer object. 188 * \param[in] data Data to hex dump 189 * \param[in] len Length of data to hexdump 190 * \return ARES_SUCCESS on success. 191 */ 192 CARES_EXTERN ares_status_t ares_buf_hexdump(ares_buf_t *buf, 193 const unsigned char *data, 194 size_t len); 195 196 /*! Clean up ares_buf_t and return allocated pointer to unprocessed data. It 197 * is the responsibility of the caller to ares_free() the returned buffer. 198 * The passed in buf parameter is invalidated by this call. 199 * 200 * \param[in] buf Initialized buffer object. Can not be a "const" buffer. 201 * \param[out] len Length of data returned 202 * \return pointer to unprocessed data (may be zero length) or NULL on error. 203 */ 204 CARES_EXTERN unsigned char *ares_buf_finish_bin(ares_buf_t *buf, size_t *len); 205 206 /*! Clean up ares_buf_t and return allocated pointer to unprocessed data and 207 * return it as a string (null terminated). It is the responsibility of the 208 * caller to ares_free() the returned buffer. The passed in buf parameter is 209 * invalidated by this call. 210 * 211 * This function in no way validates the data in this buffer is actually 212 * a string, that characters are printable, or that there aren't multiple 213 * NULL terminators. It is assumed that the caller will either validate that 214 * themselves or has built this buffer with only a valid character set. 215 * 216 * \param[in] buf Initialized buffer object. Can not be a "const" buffer. 217 * \param[out] len Optional. Length of data returned, or NULL if not needed. 218 * \return pointer to unprocessed data or NULL on error. 219 */ 220 CARES_EXTERN char *ares_buf_finish_str(ares_buf_t *buf, size_t *len); 221 222 /*! Replace the given search byte sequence with the replacement byte sequence. 223 * This is only valid for allocated buffers, not const buffers. Will replace 224 * all byte sequences starting at the current offset to the end of the buffer. 225 * 226 * \param[in] buf Initialized buffer object. Can not be a "const" buffer. 227 * \param[in] srch Search byte sequence, must not be NULL. 228 * \param[in] srch_size Size of byte sequence, must not be zero. 229 * \param[in] rplc Byte sequence to use as replacement. May be NULL if 230 * rplc_size is zero. 231 * \param[in] rplc_size Size of replacement byte sequence, may be 0. 232 * \return ARES_SUCCESS on success, otherwise on may return failure only on 233 * memory allocation failure or misuse. Will not return indication 234 * if any replacements occurred 235 */ 236 CARES_EXTERN ares_status_t ares_buf_replace(ares_buf_t *buf, 237 const unsigned char *srch, 238 size_t srch_size, 239 const unsigned char *rplc, 240 size_t rplc_size); 241 242 /*! Tag a position to save in the buffer in case parsing needs to rollback, 243 * such as if insufficient data is available, but more data may be added in 244 * the future. Only a single tag can be set per buffer object. Setting a 245 * tag will override any pre-existing tag. 246 * 247 * \param[in] buf Initialized buffer object 248 */ 249 CARES_EXTERN void ares_buf_tag(ares_buf_t *buf); 250 251 /*! Rollback to a tagged position. Will automatically clear the tag. 252 * 253 * \param[in] buf Initialized buffer object 254 * \return ARES_SUCCESS or one of the c-ares error codes 255 */ 256 CARES_EXTERN ares_status_t ares_buf_tag_rollback(ares_buf_t *buf); 257 258 /*! Clear the tagged position without rolling back. You should do this any 259 * time a tag is no longer needed as future append operations can reclaim 260 * buffer space. 261 * 262 * \param[in] buf Initialized buffer object 263 * \return ARES_SUCCESS or one of the c-ares error codes 264 */ 265 CARES_EXTERN ares_status_t ares_buf_tag_clear(ares_buf_t *buf); 266 267 /*! Fetch the buffer and length of data starting from the tagged position up 268 * to the _current_ position. It will not unset the tagged position. The 269 * data may be invalidated by any future ares_buf_*() calls. 270 * 271 * \param[in] buf Initialized buffer object 272 * \param[out] len Length between tag and current offset in buffer 273 * \return NULL on failure (such as no tag), otherwise pointer to start of 274 * buffer 275 */ 276 CARES_EXTERN const unsigned char *ares_buf_tag_fetch(const ares_buf_t *buf, 277 size_t *len); 278 279 /*! Get the length of the current tag offset to the current position. 280 * 281 * \param[in] buf Initialized buffer object 282 * \return length 283 */ 284 CARES_EXTERN size_t ares_buf_tag_length(const ares_buf_t *buf); 285 286 /*! Fetch the bytes starting from the tagged position up to the _current_ 287 * position using the provided buffer. It will not unset the tagged position. 288 * 289 * \param[in] buf Initialized buffer object 290 * \param[in,out] bytes Buffer to hold data 291 * \param[in,out] len On input, buffer size, on output, bytes place in 292 * buffer. 293 * \return ARES_SUCCESS if fetched, ARES_EFORMERR if insufficient buffer size 294 */ 295 CARES_EXTERN ares_status_t ares_buf_tag_fetch_bytes(const ares_buf_t *buf, 296 unsigned char *bytes, 297 size_t *len); 298 299 /*! Fetch the bytes starting from the tagged position up to the _current_ 300 * position as a NULL-terminated string using the provided buffer. The data 301 * is validated to be ASCII-printable data. It will not unset the tagged 302 * position. 303 * 304 * \param[in] buf Initialized buffer object 305 * \param[in,out] str Buffer to hold data 306 * \param[in] len buffer size 307 * \return ARES_SUCCESS if fetched, ARES_EFORMERR if insufficient buffer size, 308 * ARES_EBADSTR if not printable ASCII 309 */ 310 CARES_EXTERN ares_status_t ares_buf_tag_fetch_string(const ares_buf_t *buf, 311 char *str, size_t len); 312 313 /*! Fetch the bytes starting from the tagged position up to the _current_ 314 * position as a NULL-terminated string and placed into a newly allocated 315 * buffer. The data is validated to be ASCII-printable data. It will not 316 * unset the tagged position. 317 * 318 * \param[in] buf Initialized buffer object 319 * \param[out] str New buffer to hold output, free with ares_free() 320 * 321 * \return ARES_SUCCESS if fetched, ARES_EFORMERR if insufficient buffer size, 322 * ARES_EBADSTR if not printable ASCII 323 */ 324 CARES_EXTERN ares_status_t ares_buf_tag_fetch_strdup(const ares_buf_t *buf, 325 char **str); 326 327 /*! Fetch the bytes starting from the tagged position up to the _current_ 328 * position as const buffer. Care must be taken to not append or destroy the 329 * passed in buffer until the newly fetched buffer is no longer needed since 330 * it points to memory inside the passed in buffer which could be invalidated. 331 * 332 * \param[in] buf Initialized buffer object 333 * \param[out] newbuf New const buffer object, must be destroyed when done. 334 335 * \return ARES_SUCCESS if fetched 336 */ 337 CARES_EXTERN ares_status_t ares_buf_tag_fetch_constbuf(const ares_buf_t *buf, 338 ares_buf_t **newbuf); 339 340 /*! Consume the given number of bytes without reading them. 341 * 342 * \param[in] buf Initialized buffer object 343 * \param[in] len Length to consume 344 * \return ARES_SUCCESS or one of the c-ares error codes 345 */ 346 CARES_EXTERN ares_status_t ares_buf_consume(ares_buf_t *buf, size_t len); 347 348 /*! Fetch a 16bit Big Endian number from the buffer. 349 * 350 * \param[in] buf Initialized buffer object 351 * \param[out] u16 Buffer to hold 16bit integer 352 * \return ARES_SUCCESS or one of the c-ares error codes 353 */ 354 CARES_EXTERN ares_status_t ares_buf_fetch_be16(ares_buf_t *buf, 355 unsigned short *u16); 356 357 /*! Fetch a 32bit Big Endian number from the buffer. 358 * 359 * \param[in] buf Initialized buffer object 360 * \param[out] u32 Buffer to hold 32bit integer 361 * \return ARES_SUCCESS or one of the c-ares error codes 362 */ 363 CARES_EXTERN ares_status_t ares_buf_fetch_be32(ares_buf_t *buf, 364 unsigned int *u32); 365 366 367 /*! Fetch the requested number of bytes into the provided buffer 368 * 369 * \param[in] buf Initialized buffer object 370 * \param[out] bytes Buffer to hold data 371 * \param[in] len Requested number of bytes (must be > 0) 372 * \return ARES_SUCCESS or one of the c-ares error codes 373 */ 374 CARES_EXTERN ares_status_t ares_buf_fetch_bytes(ares_buf_t *buf, 375 unsigned char *bytes, 376 size_t len); 377 378 379 /*! Fetch the requested number of bytes and return a new buffer that must be 380 * ares_free()'d by the caller. 381 * 382 * \param[in] buf Initialized buffer object 383 * \param[in] len Requested number of bytes (must be > 0) 384 * \param[in] null_term Even though this is considered binary data, the user 385 * knows it may be a vald string, so add a null 386 * terminator. 387 * \param[out] bytes Pointer passed by reference. Will be allocated. 388 * \return ARES_SUCCESS or one of the c-ares error codes 389 */ 390 CARES_EXTERN ares_status_t ares_buf_fetch_bytes_dup(ares_buf_t *buf, size_t len, 391 ares_bool_t null_term, 392 unsigned char **bytes); 393 394 /*! Fetch the requested number of bytes and place them into the provided 395 * dest buffer object. 396 * 397 * \param[in] buf Initialized buffer object 398 * \param[out] dest Buffer object to append bytes. 399 * \param[in] len Requested number of bytes (must be > 0) 400 * \return ARES_SUCCESS or one of the c-ares error codes 401 */ 402 CARES_EXTERN ares_status_t ares_buf_fetch_bytes_into_buf(ares_buf_t *buf, 403 ares_buf_t *dest, 404 size_t len); 405 406 /*! Fetch the requested number of bytes and return a new buffer that must be 407 * ares_free()'d by the caller. The returned buffer is a null terminated 408 * string. The data is validated to be ASCII-printable. 409 * 410 * \param[in] buf Initialized buffer object 411 * \param[in] len Requested number of bytes (must be > 0) 412 * \param[out] str Pointer passed by reference. Will be allocated. 413 * \return ARES_SUCCESS or one of the c-ares error codes 414 */ 415 CARES_EXTERN ares_status_t ares_buf_fetch_str_dup(ares_buf_t *buf, size_t len, 416 char **str); 417 418 /*! Consume whitespace characters (0x09, 0x0B, 0x0C, 0x0D, 0x20, and optionally 419 * 0x0A). 420 * 421 * \param[in] buf Initialized buffer object 422 * \param[in] include_linefeed ARES_TRUE to include consuming 0x0A, 423 * ARES_FALSE otherwise. 424 * \return number of whitespace characters consumed 425 */ 426 CARES_EXTERN size_t ares_buf_consume_whitespace(ares_buf_t *buf, 427 ares_bool_t include_linefeed); 428 429 430 /*! Consume any non-whitespace character (anything other than 0x09, 0x0B, 0x0C, 431 * 0x0D, 0x20, and 0x0A). 432 * 433 * \param[in] buf Initialized buffer object 434 * \return number of characters consumed 435 */ 436 CARES_EXTERN size_t ares_buf_consume_nonwhitespace(ares_buf_t *buf); 437 438 439 /*! Consume until a character in the character set provided is reached. Does 440 * not include the character from the charset at the end. 441 * 442 * \param[in] buf Initialized buffer object 443 * \param[in] charset character set 444 * \param[in] len length of character set 445 * \param[in] require_charset require we find a character from the charset. 446 * if ARES_FALSE it will simply consume the 447 * rest of the buffer. If ARES_TRUE will return 448 * SIZE_MAX if not found. 449 * \return number of characters consumed 450 */ 451 CARES_EXTERN size_t ares_buf_consume_until_charset(ares_buf_t *buf, 452 const unsigned char *charset, 453 size_t len, 454 ares_bool_t require_charset); 455 456 457 /*! Consume until a sequence of bytes is encountered. Does not include the 458 * sequence of characters itself. 459 * 460 * \param[in] buf Initialized buffer object 461 * \param[in] seq sequence of bytes 462 * \param[in] len length of sequence 463 * \param[in] require_charset require we find the sequence. 464 * if ARES_FALSE it will simply consume the 465 * rest of the buffer. If ARES_TRUE will return 466 * SIZE_MAX if not found. 467 * \return number of characters consumed 468 */ 469 CARES_EXTERN size_t ares_buf_consume_until_seq(ares_buf_t *buf, 470 const unsigned char *seq, 471 size_t len, 472 ares_bool_t require_seq); 473 474 /*! Consume while the characters match the characters in the provided set. 475 * 476 * \param[in] buf Initialized buffer object 477 * \param[in] charset character set 478 * \param[in] len length of character set 479 * \return number of characters consumed 480 */ 481 CARES_EXTERN size_t ares_buf_consume_charset(ares_buf_t *buf, 482 const unsigned char *charset, 483 size_t len); 484 485 486 /*! Consume from the current position until the end of the line, and optionally 487 * the end of line character (0x0A) itself. 488 * 489 * \param[in] buf Initialized buffer object 490 * \param[in] include_linefeed ARES_TRUE to include consuming 0x0A, 491 * ARES_FALSE otherwise. 492 * \return number of characters consumed 493 */ 494 CARES_EXTERN size_t ares_buf_consume_line(ares_buf_t *buf, 495 ares_bool_t include_linefeed); 496 497 typedef enum { 498 /*! No flags */ 499 ARES_BUF_SPLIT_NONE = 0, 500 /*! The delimiter will be the first character in the buffer, except the 501 * first buffer since the start doesn't have a delimiter. This option is 502 * incompatible with ARES_BUF_SPLIT_LTRIM since the delimiter is always 503 * the first character. 504 */ 505 ARES_BUF_SPLIT_KEEP_DELIMS = 1 << 0, 506 /*! Allow blank sections, by default blank sections are not emitted. If using 507 * ARES_BUF_SPLIT_KEEP_DELIMS, the delimiter is not counted as part 508 * of the section */ 509 ARES_BUF_SPLIT_ALLOW_BLANK = 1 << 1, 510 /*! Remove duplicate entries */ 511 ARES_BUF_SPLIT_NO_DUPLICATES = 1 << 2, 512 /*! Perform case-insensitive matching when comparing values */ 513 ARES_BUF_SPLIT_CASE_INSENSITIVE = 1 << 3, 514 /*! Trim leading whitespace from buffer */ 515 ARES_BUF_SPLIT_LTRIM = 1 << 4, 516 /*! Trim trailing whitespace from buffer */ 517 ARES_BUF_SPLIT_RTRIM = 1 << 5, 518 /*! Trim leading and trailing whitespace from buffer */ 519 ARES_BUF_SPLIT_TRIM = (ARES_BUF_SPLIT_LTRIM | ARES_BUF_SPLIT_RTRIM) 520 } ares_buf_split_t; 521 522 /*! Split the provided buffer into multiple sub-buffers stored in the variable 523 * pointed to by the linked list. The sub buffers are const buffers pointing 524 * into the buf provided. 525 * 526 * \param[in] buf Initialized buffer object 527 * \param[in] delims Possible delimiters 528 * \param[in] delims_len Length of possible delimiters 529 * \param[in] flags One more more flags 530 * \param[in] max_sections Maximum number of sections. Use 0 for 531 * unlimited. Useful for splitting key/value 532 * pairs where the delimiter may be a valid 533 * character in the value. A value of 1 would 534 * have little usefulness and would effectively 535 * ignore the delimiter itself. 536 * \param[out] arr Result. Depending on flags, this may be a 537 * valid array with no elements. Use 538 * ares_array_destroy() to free the memory which 539 * will also free the contained ares_buf_t * 540 * objects. Each buf object returned by 541 * ares_array_at() or similar is a pointer to 542 * an ares_buf_t * object, meaning you need to 543 * accept it as "ares_buf_t **" then dereference. 544 * \return ARES_SUCCESS on success, or error like ARES_ENOMEM. 545 */ 546 CARES_EXTERN ares_status_t ares_buf_split( 547 ares_buf_t *buf, const unsigned char *delims, size_t delims_len, 548 ares_buf_split_t flags, size_t max_sections, ares_array_t **arr); 549 550 /*! Split the provided buffer into an ares_array_t of C strings. 551 * 552 * \param[in] buf Initialized buffer object 553 * \param[in] delims Possible delimiters 554 * \param[in] delims_len Length of possible delimiters 555 * \param[in] flags One more more flags 556 * \param[in] max_sections Maximum number of sections. Use 0 for 557 * unlimited. Useful for splitting key/value 558 * pairs where the delimiter may be a valid 559 * character in the value. A value of 1 would 560 * have little usefulness and would effectively 561 * ignore the delimiter itself. 562 * \param[out] arr Array of strings. Free using 563 * ares_array_destroy(). 564 * \return ARES_SUCCESS on success, or error like ARES_ENOMEM. 565 */ 566 CARES_EXTERN ares_status_t ares_buf_split_str_array( 567 ares_buf_t *buf, const unsigned char *delims, size_t delims_len, 568 ares_buf_split_t flags, size_t max_sections, ares_array_t **arr); 569 570 /*! Split the provided buffer into a C array of C strings. 571 * 572 * \param[in] buf Initialized buffer object 573 * \param[in] delims Possible delimiters 574 * \param[in] delims_len Length of possible delimiters 575 * \param[in] flags One more more flags 576 * \param[in] max_sections Maximum number of sections. Use 0 for 577 * unlimited. Useful for splitting key/value 578 * pairs where the delimiter may be a valid 579 * character in the value. A value of 1 would 580 * have little usefulness and would effectively 581 * ignore the delimiter itself. 582 * \param[out] strs Array of strings. Free using 583 * ares_free_array(strs, nstrs, ares_free) 584 * \param[out] nstrs Number of elements in the array. 585 * \return ARES_SUCCESS on success, or error like ARES_ENOMEM. 586 */ 587 CARES_EXTERN ares_status_t ares_buf_split_str( 588 ares_buf_t *buf, const unsigned char *delims, size_t delims_len, 589 ares_buf_split_t flags, size_t max_sections, char ***strs, size_t *nstrs); 590 591 /*! Check the unprocessed buffer to see if it begins with the sequence of 592 * characters provided. 593 * 594 * \param[in] buf Initialized buffer object 595 * \param[in] data Bytes of data to compare. 596 * \param[in] data_len Length of data to compare. 597 * \return ARES_TRUE on match, ARES_FALSE otherwise. 598 */ 599 CARES_EXTERN ares_bool_t ares_buf_begins_with(const ares_buf_t *buf, 600 const unsigned char *data, 601 size_t data_len); 602 603 604 /*! Size of unprocessed remaining data length 605 * 606 * \param[in] buf Initialized buffer object 607 * \return length remaining 608 */ 609 CARES_EXTERN size_t ares_buf_len(const ares_buf_t *buf); 610 611 /*! Retrieve a pointer to the currently unprocessed data. Generally this isn't 612 * recommended to be used in practice. The returned pointer may be invalidated 613 * by any future ares_buf_*() calls. 614 * 615 * \param[in] buf Initialized buffer object 616 * \param[out] len Length of available data 617 * \return Pointer to buffer of unprocessed data 618 */ 619 CARES_EXTERN const unsigned char *ares_buf_peek(const ares_buf_t *buf, 620 size_t *len); 621 622 /*! Retrieve the next byte in the buffer without moving forward. 623 * 624 * \param[in] buf Initialized buffer object 625 * \param[out] b Single byte 626 * \return \return ARES_SUCCESS on success, or error 627 */ 628 CARES_EXTERN ares_status_t ares_buf_peek_byte(const ares_buf_t *buf, 629 unsigned char *b); 630 631 /*! Wipe any processed data from the beginning of the buffer. This will 632 * move any remaining data to the front of the internally allocated buffer. 633 * 634 * Can not be used on const buffer objects. 635 * 636 * Typically not needed to call, as any new append operation will automatically 637 * call this function if there is insufficient space to append the data in 638 * order to try to avoid another memory allocation. 639 * 640 * It may be useful to call in order to ensure the current message being 641 * processed is in the beginning of the buffer if there is an intent to use 642 * ares_buf_set_position() and ares_buf_get_position() as may be necessary 643 * when processing DNS compressed names. 644 * 645 * If there is an active tag, it will NOT clear the tag, it will use the tag 646 * as the start of the unprocessed data rather than the current offset. If 647 * a prior tag is no longer needed, may be wise to call ares_buf_tag_clear(). 648 * 649 * \param[in] buf Initialized buffer object 650 */ 651 CARES_EXTERN void ares_buf_reclaim(ares_buf_t *buf); 652 653 /*! Set the current offset within the internal buffer. 654 * 655 * Typically this should not be used, if possible, use the ares_buf_tag*() 656 * operations instead. 657 * 658 * One exception is DNS name compression which may backwards reference to 659 * an index in the message. It may be necessary in such a case to call 660 * ares_buf_reclaim() if using a dynamic (non-const) buffer before processing 661 * such a message. 662 * 663 * \param[in] buf Initialized buffer object 664 * \param[in] idx Index to set position 665 * \return ARES_SUCCESS if valid index 666 */ 667 CARES_EXTERN ares_status_t ares_buf_set_position(ares_buf_t *buf, size_t idx); 668 669 /*! Get the current offset within the internal buffer. 670 * 671 * Typically this should not be used, if possible, use the ares_buf_tag*() 672 * operations instead. 673 * 674 * This can be used to get the current position, useful for saving if a 675 * jump via ares_buf_set_position() is performed and need to restore the 676 * current position for future operations. 677 * 678 * \param[in] buf Initialized buffer object 679 * \return index of current position 680 */ 681 CARES_EXTERN size_t ares_buf_get_position(const ares_buf_t *buf); 682 683 /*! Parse a character-string as defined in RFC1035, as a null-terminated 684 * string. 685 * 686 * \param[in] buf initialized buffer object 687 * \param[in] remaining_len maximum length that should be used for parsing 688 * the string, this is often less than the remaining 689 * buffer and is based on the RR record length. 690 * \param[out] name Pointer passed by reference to be filled in with 691 * allocated string of the parsed that must be 692 * ares_free()'d by the caller. 693 * \return ARES_SUCCESS on success 694 */ 695 CARES_EXTERN ares_status_t ares_buf_parse_dns_str(ares_buf_t *buf, 696 size_t remaining_len, 697 char **name); 698 699 /*! Parse a character-string as defined in RFC1035, as binary, however for 700 * convenience this does guarantee a NULL terminator (that is not included 701 * in the returned length). 702 * 703 * \param[in] buf initialized buffer object 704 * \param[in] remaining_len maximum length that should be used for parsing 705 * the string, this is often less than the remaining 706 * buffer and is based on the RR record length. 707 * \param[out] bin Pointer passed by reference to be filled in with 708 * allocated string of the parsed that must be 709 * ares_free()'d by the caller. 710 * \param[out] bin_len Length of returned string. 711 * \return ARES_SUCCESS on success 712 */ 713 CARES_EXTERN ares_status_t ares_buf_parse_dns_binstr(ares_buf_t *buf, 714 size_t remaining_len, 715 unsigned char **bin, 716 size_t *bin_len); 717 718 /*! Load data from specified file path into provided buffer. The entire file 719 * is loaded into memory. 720 * 721 * \param[in] filename complete path to file 722 * \param[in,out] buf Initialized (non-const) buffer object to load data 723 * into 724 * \return ARES_ENOTFOUND if file not found, ARES_EFILE if issues reading 725 * file, ARES_ENOMEM if out of memory, ARES_SUCCESS on success. 726 */ 727 CARES_EXTERN ares_status_t ares_buf_load_file(const char *filename, 728 ares_buf_t *buf); 729 730 /*! @} */ 731 732 #endif /* __ARES__BUF_H */ 733