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