1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 // Copyright (C) 2002-2013 Sourcefire, Inc.
4 // Copyright (C) 2002 Martin Roesch <roesch@sourcefire.com>
5 //
6 // This program is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License Version 2 as published
8 // by the Free Software Foundation. You may not use, modify or distribute
9 // this program under any other version of the GNU General Public License.
10 //
11 // This program is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 //--------------------------------------------------------------------------
20
21 #ifndef UTIL_CSTRING_H
22 #define UTIL_CSTRING_H
23
24 // Utility functions and macros for interacting with and parsing C strings
25
26 #include <cctype>
27 #include <cerrno>
28 #include <cstdlib>
29
30 #include "main/snort_types.h"
31
32 namespace snort
33 {
34 #define SNORT_SNPRINTF_SUCCESS 0
35 #define SNORT_SNPRINTF_TRUNCATION 1
36 #define SNORT_SNPRINTF_ERROR (-1)
37
38 #define SNORT_STRNCPY_SUCCESS 0
39 #define SNORT_STRNCPY_TRUNCATION 1
40 #define SNORT_STRNCPY_ERROR (-1)
41 #define SNORT_STRNLEN_ERROR (-1)
42
43 SO_PUBLIC int safe_snprintf(char*, size_t, const char*, ... )
44 __attribute__((format (printf, 3, 4)));
45 // these functions are deprecated; use C++ strings instead
46 SO_PUBLIC int SnortSnprintf(char*, size_t, const char*, ...)
47 __attribute__((format (printf, 3, 4)));
48 SO_PUBLIC int SnortSnprintfAppend(char*, size_t, const char*, ...)
49 __attribute__((format (printf, 3, 4)));
50
51 SO_PUBLIC const char* SnortStrcasestr(const char* s, int slen, const char* substr);
52 SO_PUBLIC const char* SnortStrnStr(const char* s, int slen, const char* searchstr);
53 SO_PUBLIC const char* SnortStrnPbrk(const char* s, int slen, const char* accept);
54
55 SO_PUBLIC int SnortStrncpy(char*, const char*, size_t);
56 SO_PUBLIC int SnortStrnlen(const char*, int);
57
58 SO_PUBLIC int sfsnprintfappend(char* dest, int dsize, const char* format, ...)
59 __attribute__((format (printf, 3, 4)));
60
SnortStrtol(const char * nptr,char ** endptr,int base)61 inline long SnortStrtol(const char* nptr, char** endptr, int base)
62 {
63 long iRet;
64 errno = 0;
65 iRet = strtol(nptr, endptr, base);
66
67 return iRet;
68 }
69
SnortStrtoul(const char * nptr,char ** endptr,int base)70 inline unsigned long SnortStrtoul(const char* nptr, char** endptr, int base)
71 {
72 unsigned long iRet;
73 errno = 0;
74 iRet = strtoul(nptr, endptr, base);
75
76 return iRet;
77 }
78
79 // Checks to make sure we're not going to evaluate a negative number for which
80 // strtoul() gladly accepts and parses returning an underflowed wrapped unsigned
81 // long without error.
82 // Buffer passed in MUST be '\0' terminated.
83 //
84 // Returns
85 // int
86 // -1 if buffer is nothing but spaces or first non-space character is a
87 // negative sign. Also if errno is EINVAL (which may be due to a bad
88 // base) or there was nothing to convert.
89 // 0 on success
90 //
91 // Populates pointer to uint32_t value passed in which should
92 // only be used on a successful return from this function.
93 //
94 // Also will set errno to ERANGE on a value returned from strtoul that is
95 // greater than UINT32_MAX, but still return success.
96 //
SnortStrToU32(const char * buffer,char ** endptr,uint32_t * value,int base)97 inline int SnortStrToU32(const char* buffer, char** endptr,
98 uint32_t* value, int base)
99 {
100 unsigned long int tmp;
101
102 if ((buffer == nullptr) || (endptr == nullptr) || (value == nullptr))
103 return -1;
104
105 // Only positive numbers should be processed and strtoul will
106 // eat up white space and process '-' and '+' so move past
107 // white space and check for a negative sign.
108 while (isspace((int)*buffer))
109 buffer++;
110
111 // If all spaces or a negative sign is found, return error.
112 // May want to exclude '+' as well.
113 if ((*buffer == '\0') || (*buffer == '-'))
114 return -1;
115
116 tmp = SnortStrtoul(buffer, endptr, base);
117
118 // The user of the function should check for ERANGE in errno since this
119 // function can be used such that an ERANGE error is acceptable and
120 // value gets truncated to UINT32_MAX.
121 if ((errno == EINVAL) || (*endptr == buffer))
122 return -1;
123
124 // If value is greater than a UINT32_MAX set value to UINT32_MAX
125 // and errno to ERANGE
126 if (tmp > UINT32_MAX)
127 {
128 tmp = UINT32_MAX;
129 errno = ERANGE;
130 }
131
132 *value = (uint32_t)tmp;
133
134 return 0;
135 }
136 }
137 #endif
138
139