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