1 /*************************************************************************** 2 * Copyright (c) 2009-2010 Open Information Security Foundation 3 * Copyright (c) 2010-2013 Qualys, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * - Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 17 * - Neither the name of the Qualys, Inc. nor the names of its 18 * contributors may be used to endorse or promote products derived from 19 * this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 ***************************************************************************/ 33 34 /** 35 * @file 36 * @author Ivan Ristic <ivanr@webkreator.com> 37 */ 38 39 #ifndef _BSTR_H 40 #define _BSTR_H 41 42 #ifdef __cplusplus 43 extern "C" { 44 #endif 45 46 typedef struct bstr_t bstr; 47 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <stdint.h> 51 #include <string.h> 52 53 #include "bstr_builder.h" 54 55 // Data structures 56 57 struct bstr_t { 58 /** The length of the string stored in the buffer. */ 59 size_t len; 60 61 /** The current size of the buffer. If there is extra room in the 62 * buffer the string will be able to expand without reallocation. 63 */ 64 size_t size; 65 66 /** Optional buffer pointer. If this pointer is NULL the string buffer 67 * will immediately follow this structure. If the pointer is not NUL, 68 * it points to the actual buffer used, and there's no data following 69 * this structure. 70 */ 71 unsigned char *realptr; 72 }; 73 74 75 // Defines 76 77 #define bstr_len(X) ((*(X)).len) 78 #define bstr_size(X) ((*(X)).size) 79 #define bstr_ptr(X) ( ((*(X)).realptr == NULL) ? ((unsigned char *)(X) + sizeof(bstr)) : (unsigned char *)(*(X)).realptr ) 80 #define bstr_realptr(X) ((*(X)).realptr) 81 82 83 // Functions 84 85 /** 86 * Append source bstring to destination bstring, growing destination if 87 * necessary. If the destination bstring is expanded, the pointer will change. 88 * You must replace the original destination pointer with the returned one. 89 * Destination is not changed on memory allocation failure. 90 * 91 * @param[in] bdestination 92 * @param[in] bsource 93 * @return Updated bstring, or NULL on memory allocation failure. 94 */ 95 bstr *bstr_add(bstr *bdestination, const bstr *bsource); 96 97 /** 98 * Append a NUL-terminated source to destination, growing destination if 99 * necessary. If the string is expanded, the pointer will change. You must 100 * replace the original destination pointer with the returned one. Destination 101 * is not changed on memory allocation failure. 102 * 103 * @param[in] b 104 * @param[in] cstr 105 * @return Updated bstring, or NULL on memory allocation failure. 106 */ 107 bstr *bstr_add_c(bstr *b, const char *cstr); 108 109 /** 110 * Append as many bytes from the source to destination bstring. The 111 * destination storage will not be expanded if there is not enough space in it 112 * already to accommodate all of the data. 113 * 114 * @param[in] b 115 * @param[in] cstr 116 * @return The destination bstring. 117 */ 118 bstr *bstr_add_c_noex(bstr *b, const char *cstr); 119 120 /** 121 * Append a memory region to destination, growing destination if necessary. If 122 * the string is expanded, the pointer will change. You must replace the 123 * original destination pointer with the returned one. Destination is not 124 * changed on memory allocation failure. 125 * 126 * @param[in] b 127 * @param[in] data 128 * @param[in] len 129 * @return Updated bstring, or NULL on memory allocation failure. 130 */ 131 bstr *bstr_add_mem(bstr *b, const void *data, size_t len); 132 133 /** 134 * Append as many bytes from the source to destination bstring. The 135 * destination storage will not be expanded if there is not enough space in it 136 * already to accommodate all of the data. 137 * 138 * @param[in] b 139 * @param[in] data 140 * @param[in] len 141 * @return The destination bstring. 142 */ 143 bstr *bstr_add_mem_noex(bstr *b, const void *data, size_t len); 144 145 /** 146 * Append as many bytes from the source bstring to destination bstring. The 147 * destination storage will not be expanded if there is not enough space in it 148 * already to accommodate all of the data. 149 * 150 * @param[in] bdestination 151 * @param[in] bsource 152 * @return The destination bstring. 153 */ 154 bstr *bstr_add_noex(bstr *bdestination, const bstr *bsource); 155 156 /** 157 * Adjust bstring length. You will need to use this method whenever 158 * you work directly with the string contents, and end up changing 159 * its length by direct structure manipulation. 160 * 161 * @param[in] b 162 * @param[in] newlen 163 */ 164 void bstr_adjust_len(bstr *b, size_t newlen); 165 166 /** 167 * Change the external pointer used by bstring. You will need to use this 168 * function only if you're messing with bstr internals. Use with caution. 169 * 170 * @param[in] b 171 * @param[in] newrealptr 172 */ 173 void bstr_adjust_realptr(bstr *b, void *newrealptr); 174 175 /** 176 * Adjust bstring size. This does not change the size of the storage behind 177 * the bstring, just changes the field that keeps track of how many bytes 178 * there are in the storage. You will need to use this function only if 179 * you're messing with bstr internals. Use with caution. 180 * 181 * @param[in] b 182 * @param[in] newsize 183 */ 184 void bstr_adjust_size(bstr *b, size_t newsize); 185 186 /** 187 * Allocate a zero-length bstring, reserving space for at least size bytes. 188 * 189 * @param[in] size 190 * @return New string instance 191 */ 192 bstr *bstr_alloc(size_t size); 193 194 /** 195 * Checks whether bstring begins with another bstring. Case sensitive. 196 * 197 * @param[in] bhaystack 198 * @param[in] bneedle 199 * @return 1 if true, otherwise 0. 200 */ 201 int bstr_begins_with(const bstr *bhaystack, const bstr *bneedle); 202 203 /** 204 * Checks whether bstring begins with NUL-terminated string. Case sensitive. 205 * 206 * @param[in] bhaystack 207 * @param[in] cneedle 208 * @return 1 if true, otherwise 0. 209 */ 210 int bstr_begins_with_c(const bstr *bhaystack, const char *cneedle); 211 212 /** 213 * Checks whether bstring begins with NUL-terminated string. Case insensitive. 214 * 215 * @param[in] bhaystack 216 * @param[in] cneedle 217 * @return 1 if true, otherwise 0. 218 */ 219 int bstr_begins_with_c_nocase(const bstr *bhaystack, const char *cneedle); 220 221 /** 222 * Checks whether the bstring begins with the given memory block. Case sensitive. 223 * 224 * @param[in] bhaystack 225 * @param[in] data 226 * @param[in] len 227 * @return 1 if true, otherwise 0. 228 */ 229 int bstr_begins_with_mem(const bstr *bhaystack, const void *data, size_t len); 230 231 /** 232 * Checks whether bstring begins with memory block. Case insensitive. 233 * 234 * @param[in] bhaystack 235 * @param[in] data 236 * @param[in] len 237 * @return 1 if true, otherwise 0. 238 */ 239 int bstr_begins_with_mem_nocase(const bstr *bhaystack, const void *data, size_t len); 240 241 /** 242 * Checks whether bstring begins with another bstring. Case insensitive. 243 * 244 * @param[in] bhaystack 245 * @param[in] cneedle 246 * @return 1 if true, otherwise 0. 247 */ 248 int bstr_begins_with_nocase(const bstr *bhaystack, const bstr *cneedle); 249 250 /** 251 * Return the byte at the given position. 252 * 253 * @param[in] b 254 * @param[in] pos 255 * @return The byte at the given location, or -1 if the position is out of range. 256 */ 257 int bstr_char_at(const bstr *b, size_t pos); 258 259 /** 260 * Return the byte at the given position, counting from the end of the string (e.g., 261 * byte at position 0 is the last byte in the string.) 262 * 263 * @param[in] b 264 * @param[in] pos 265 * @return The byte at the given location, or -1 if the position is out of range. 266 */ 267 int bstr_char_at_end(const bstr *b, size_t pos); 268 269 /** 270 * Remove the last byte from bstring, assuming it contains at least one byte. This 271 * function will not reduce the storage that backs the string, only the amount 272 * of data used. 273 * 274 * @param[in] b 275 */ 276 void bstr_chop(bstr *b); 277 278 /** 279 * Return the first position of the provided byte. 280 * 281 * @param[in] b 282 * @param[in] c 283 * @return The first position of the byte, or -1 if it could not be found 284 */ 285 int bstr_chr(const bstr *b, int c); 286 287 /** 288 * Case-sensitive comparison of two bstrings. 289 * 290 * @param[in] b1 291 * @param[in] b2 292 * @return Zero on string match, 1 if b1 is greater than b2, and -1 if b2 is 293 * greater than b1. 294 */ 295 int bstr_cmp(const bstr *b1, const bstr *b2); 296 297 /** 298 * Case-sensitive comparison of a bstring and a NUL-terminated string. 299 * 300 * @param[in] b 301 * @param[in] cstr 302 * @return Zero on string match, 1 if b is greater than cstr, and -1 if cstr is 303 * greater than b. 304 */ 305 int bstr_cmp_c(const bstr *b, const char *cstr); 306 307 /** 308 * Case-insensitive comparison of a bstring with a NUL-terminated string. 309 * 310 * @param[in] b 311 * @param[in] cstr 312 * @return Zero on string match, 1 if b is greater than cstr, and -1 if cstr is greater than b. 313 */ 314 int bstr_cmp_c_nocase(const bstr *b, const char *cstr); 315 316 /** 317 * Case-insensitive zero-skipping comparison of a bstring with a NUL-terminated string. 318 * 319 * @param[in] b 320 * @param[in] cstr 321 * @return Zero on string match, 1 if b is greater than cstr, and -1 if cstr is greater than b. 322 */ 323 int bstr_cmp_c_nocasenorzero(const bstr *b, const char *cstr); 324 325 /** 326 * Performs a case-sensitive comparison of a bstring with a memory region. 327 * 328 * @param[in] b 329 * @param[in] data 330 * @param[in] len 331 * @return Zero ona match, 1 if b is greater than data, and -1 if data is greater than b. 332 */ 333 int bstr_cmp_mem(const bstr *b, const void *data, size_t len); 334 335 /** 336 * Performs a case-insensitive comparison of a bstring with a memory region. 337 * 338 * @param[in] b 339 * @param[in] data 340 * @param[in] len 341 * @return Zero ona match, 1 if b is greater than data, and -1 if data is greater than b. 342 */ 343 int bstr_cmp_mem_nocase(const bstr *b, const void *data, size_t len); 344 345 /** 346 * Case-insensitive comparison two bstrings. 347 * 348 * @param[in] b1 349 * @param[in] b2 350 * @return Zero on string match, 1 if b1 is greater than b2, and -1 if b2 is 351 * greater than b1. 352 */ 353 int bstr_cmp_nocase(const bstr *b1, const bstr *b2); 354 355 /** 356 * Case-insensitive and zero skipping comparison two bstrings. 357 * 358 * @param[in] b1 359 * @param[in] b2 360 * @return Zero on string match, 1 if b1 is greater than b2, and -1 if b2 is 361 * greater than b1. 362 */ 363 int bstr_cmp_nocasenorzero(const bstr *b1, const bstr *b2); 364 365 /** 366 * Create a new bstring by copying the provided bstring. 367 * 368 * @param[in] b 369 * @return New bstring, or NULL if memory allocation failed. 370 */ 371 bstr *bstr_dup(const bstr *b); 372 373 /** 374 * Create a new bstring by copying the provided NUL-terminated string. 375 * 376 * @param[in] cstr 377 * @return New bstring, or NULL if memory allocation failed. 378 */ 379 bstr *bstr_dup_c(const char *cstr); 380 381 /** 382 * Create a new bstring by copying a part of the provided bstring. 383 * 384 * @param[in] b 385 * @param[in] offset 386 * @param[in] len 387 * @return New bstring, or NULL if memory allocation failed. 388 */ 389 bstr *bstr_dup_ex(const bstr *b, size_t offset, size_t len); 390 391 /** 392 * Create a copy of the provided bstring, then convert it to lowercase. 393 * 394 * @param[in] b 395 * @return New bstring, or NULL if memory allocation failed 396 */ 397 bstr *bstr_dup_lower(const bstr *b); 398 399 /** 400 * Create a new bstring by copying the provided memory region. 401 * 402 * @param[in] data 403 * @param[in] len 404 * @return New bstring, or NULL if memory allocation failed 405 */ 406 bstr *bstr_dup_mem(const void *data, size_t len); 407 408 /** 409 * Expand internal bstring storage to support at least newsize bytes. The storage 410 * is not expanded if the current size is equal or greater to newsize. Because 411 * realloc is used underneath, the old pointer to bstring may no longer be valid 412 * after this function completes successfully. 413 * 414 * @param[in] b 415 * @param[in] newsize 416 * @return Updated string instance, or NULL if memory allocation failed or if 417 * attempt was made to "expand" the bstring to a smaller size. 418 */ 419 bstr *bstr_expand(bstr *b, size_t newsize); 420 421 /** 422 * Deallocate the supplied bstring instance and set it to NULL. Allows NULL on 423 * input. 424 * 425 * @param[in] b 426 */ 427 void bstr_free(bstr *b); 428 429 /** 430 * Find the needle in the haystack. 431 * 432 * @param[in] bhaystack 433 * @param[in] bneedle 434 * @return Position of the match, or -1 if the needle could not be found. 435 */ 436 int bstr_index_of(const bstr *bhaystack, const bstr *bneedle); 437 438 /** 439 * Find the needle in the haystack, ignoring case differences. 440 * 441 * @param[in] bhaystack 442 * @param[in] bneedle 443 * @return Position of the match, or -1 if the needle could not be found. 444 */ 445 int bstr_index_of_nocase(const bstr *bhaystack, const bstr *bneedle); 446 447 /** 448 * Find the needle in the haystack, with the needle being a NUL-terminated 449 * string. 450 * 451 * @param[in] bhaystack 452 * @param[in] cneedle 453 * @return Position of the match, or -1 if the needle could not be found. 454 */ 455 int bstr_index_of_c(const bstr *bhaystack, const char *cneedle); 456 457 /** 458 * Find the needle in the haystack, with the needle being a NUL-terminated 459 * string. Ignore case differences. 460 * 461 * @param[in] bhaystack 462 * @param[in] cneedle 463 * @return Position of the match, or -1 if the needle could not be found. 464 */ 465 int bstr_index_of_c_nocase(const bstr *bhaystack, const char *cneedle); 466 467 /** 468 * Find the needle in the haystack, with the needle being a NUL-terminated 469 * string. Ignore case differences. Skip zeroes in haystack 470 * 471 * @param[in] bhaystack 472 * @param[in] cneedle 473 * @return Position of the match, or -1 if the needle could not be found. 474 */ 475 int bstr_index_of_c_nocasenorzero(const bstr *bhaystack, const char *cneedle); 476 477 /** 478 * Find the needle in the haystack, with the needle being a memory region. 479 * 480 * @param[in] bhaystack 481 * @param[in] data 482 * @param[in] len 483 * @return Position of the match, or -1 if the needle could not be found. 484 */ 485 int bstr_index_of_mem(const bstr *bhaystack, const void *data, size_t len); 486 487 /** 488 * Find the needle in the haystack, with the needle being a memory region. 489 * Ignore case differences. 490 * 491 * @param[in] bhaystack 492 * @param[in] data 493 * @param[in] len 494 * @return Position of the match, or -1 if the needle could not be found. 495 */ 496 int bstr_index_of_mem_nocase(const bstr *bhaystack, const void *data, size_t len); 497 498 /** 499 * Return the last position of a character (byte). 500 * 501 * @param[in] b 502 * @param[in] c 503 * @return The last position of the character, or -1 if it could not be found. 504 */ 505 int bstr_rchr(const bstr *b, int c); 506 507 /** 508 * Convert bstring to lowercase. This function converts the supplied string, 509 * it does not create a new string. 510 * 511 * @param[in] b 512 * @return The same bstring received on input 513 */ 514 bstr *bstr_to_lowercase(bstr *b); 515 516 /** 517 * Case-sensitive comparison of two memory regions. 518 * 519 * @param[in] data1 520 * @param[in] len1 521 * @param[in] data2 522 * @param[in] len2 523 * @return Zero if the memory regions are identical, 1 if data1 is greater than 524 * data2, and -1 if data2 is greater than data1. 525 */ 526 int bstr_util_cmp_mem(const void *data1, size_t len1, const void *data2, size_t len2); 527 528 /** 529 * Case-insensitive comparison of two memory regions. 530 * 531 * @param[in] data1 532 * @param[in] len1 533 * @param[in] data2 534 * @param[in] len2 535 * @return Zero if the memory regions are identical, 1 if data1 is greater than 536 * data2, and -1 if data2 is greater than data1. 537 */ 538 int bstr_util_cmp_mem_nocase(const void *data1, size_t len1, const void *data2, size_t len2); 539 540 /** 541 * Case-insensitive zero-skipping comparison of two memory regions. 542 * 543 * @param[in] data1 544 * @param[in] len1 545 * @param[in] data2 546 * @param[in] len2 547 * @return Zero if the memory regions are identical, 1 if data1 is greater than 548 * data2, and -1 if data2 is greater than data1. 549 */ 550 int bstr_util_cmp_mem_nocasenorzero(const void *data1, size_t len1, const void *data2, size_t len2); 551 552 /** 553 * Convert contents of a memory region to a positive integer. 554 * 555 * @param[in] data 556 * @param[in] len 557 * @param[in] base The desired number base. 558 * @param[in] lastlen Points to the first unused byte in the region 559 * @return If the conversion was successful, this function returns the 560 * number. When the conversion fails, -1 will be returned when not 561 * one valid digit was found, and -2 will be returned if an overflow 562 * occurred. 563 */ 564 int64_t bstr_util_mem_to_pint(const void *data, size_t len, int base, size_t *lastlen); 565 566 /** 567 * Searches a memory block for the given NUL-terminated string. Case sensitive. 568 * 569 * @param[in] data 570 * @param[in] len 571 * @param[in] cstr 572 * @return Index of the first location of the needle on success, or -1 if the needle was not found. 573 */ 574 int bstr_util_mem_index_of_c(const void *data, size_t len, const char *cstr); 575 576 /** 577 * Searches a memory block for the given NUL-terminated string. Case insensitive. 578 * 579 * @param[in] data 580 * @param[in] len 581 * @param[in] cstr 582 * @return Index of the first location of the needle on success, or -1 if the needle was not found. 583 */ 584 int bstr_util_mem_index_of_c_nocase(const void *data, size_t len, const char *cstr); 585 586 /** 587 * Searches the haystack memory block for the needle memory block. Case sensitive. 588 * 589 * @param data1 590 * @param len1 591 * @param data2 592 * @param len2 593 * @return Index of the first location of the needle on success, or -1 if the needle was not found. 594 */ 595 int bstr_util_mem_index_of_mem(const void *data1, size_t len1, const void *data2, size_t len2); 596 597 /** 598 * Searches the haystack memory block for the needle memory block. Case sensitive. 599 * 600 * @param data1 601 * @param len1 602 * @param data2 603 * @param len2 604 * @return Index of the first location of the needle on success, or -1 if the needle was not found. 605 */ 606 int bstr_util_mem_index_of_mem_nocase(const void *data1, size_t len1, const void *data2, size_t len2); 607 608 /** 609 * Searches the haystack memory block for the needle memory block. Case sensitive. Skips zeroes in data1 610 * 611 * @param data1 612 * @param len1 613 * @param data2 614 * @param len2 615 * @return Index of the first location of the needle on success, or -1 if the needle was not found. 616 */ 617 int bstr_util_mem_index_of_mem_nocasenorzero(const void *data1, size_t len1, const void *data2, size_t len2); 618 619 /** 620 * Removes whitespace from the beginning and the end of a memory region. The data 621 * itself is not modified; this function only adjusts the provided pointers. 622 * 623 * @param[in,out] data 624 * @param[in,out] len 625 */ 626 void bstr_util_mem_trim(unsigned char **data, size_t *len); 627 628 /** 629 * Take the provided memory region, allocate a new memory buffer, and construct 630 * a NUL-terminated string, replacing each NUL byte with "\0" (two bytes). The 631 * caller is responsible to keep track of the allocated memory area and free 632 * it once it is no longer needed. 633 * 634 * @param[in] data 635 * @param[in] len 636 * @return The newly created NUL-terminated string, or NULL in case of memory 637 * allocation failure. 638 */ 639 char *bstr_util_memdup_to_c(const void *data, size_t len); 640 641 /** 642 * Create a new NUL-terminated string out of the provided bstring. If NUL bytes 643 * are contained in the bstring, each will be replaced with "\0" (two characters). 644 * The caller is responsible to keep track of the allocated memory area and free 645 * it once it is no longer needed. 646 * 647 * @param[in] b 648 * @return The newly created NUL-terminated string, or NULL in case of memory 649 * allocation failure. 650 */ 651 char *bstr_util_strdup_to_c(const bstr *b); 652 653 /** 654 * Create a new bstring from the provided NUL-terminated string and without 655 * copying the data. The caller must ensure that the input string continues 656 * to point to a valid memory location for as long as the bstring is used. 657 * 658 * @param[in] cstr 659 * @return New bstring, or NULL on memory allocation failure. 660 */ 661 bstr *bstr_wrap_c(const char *cstr); 662 663 /** 664 * Create a new bstring from the provided memory buffer without 665 * copying the data. The caller must ensure that the buffer remains 666 * valid for as long as the bstring is used. 667 * 668 * @param[in] data 669 * @param[in] len 670 * @return New bstring, or NULL on memory allocation failure. 671 */ 672 bstr *bstr_wrap_mem(const void *data, size_t len); 673 674 #ifdef __cplusplus 675 } 676 #endif 677 678 #endif /* _BSTR_H */ 679