xref: /PHP-7.4/ext/xmlrpc/libxmlrpc/simplestring.c (revision 29eb3561)
1 /*
2   This file is part of libXMLRPC - a C library for xml-encoded function calls.
3 
4   Author: Dan Libby (dan@libby.com)
5   Epinions.com may be contacted at feedback@epinions-inc.com
6 */
7 
8 /*
9   Copyright 2000 Epinions, Inc.
10 
11   Subject to the following 3 conditions, Epinions, Inc.  permits you, free
12   of charge, to (a) use, copy, distribute, modify, perform and display this
13   software and associated documentation files (the "Software"), and (b)
14   permit others to whom the Software is furnished to do so as well.
15 
16   1) The above copyright notice and this permission notice shall be included
17   without modification in all copies or substantial portions of the
18   Software.
19 
20   2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF
21   ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY
22   IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR
23   PURPOSE OR NONINFRINGEMENT.
24 
25   3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
26   SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
27   OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING
28   NEGLIGENCE), EVEN IF EPINIONS, INC.  IS AWARE OF THE POSSIBILITY OF SUCH
29   DAMAGES.
30 
31 */
32 
33 #include <php.h>
34 
35 
36 #define SIMPLESTRING_INCR 32
37 
38 /****h* ABOUT/simplestring
39  * NAME
40  *   simplestring
41  * AUTHOR
42  *   Dan Libby, aka danda  (dan@libby.com)
43  * CREATION DATE
44  *   06/2000
45  * HISTORY
46  *   $Log$
47  *   Revision 1.3  2002/08/22 01:25:50  sniper
48  *   kill some compile warnings
49  *
50  *   Revision 1.2  2002/07/05 04:43:53  danda
51  *   merged in updates from SF project.  bring php repository up to date with xmlrpc-epi version 0.51
52  *
53  *   Revision 1.4  2002/02/13 20:58:50  danda
54  *   patch to make source more windows friendly, contributed by Jeff Lawson
55  *
56  *   Revision 1.3  2001/09/29 21:58:05  danda
57  *   adding cvs log to history section
58  *
59  *   10/15/2000 -- danda -- adding robodoc documentation
60  * PORTABILITY
61  *   Coded on RedHat Linux 6.2.  Builds on Solaris x86.  Should build on just
62  *   about anything with minor mods.
63  * NOTES
64  *   This code was written primarily for xmlrpc, but has found some other uses.
65  *
66  *   simplestring is, as the name implies, a simple API for dealing with C strings.
67  *   Why would I write yet another string API?  Because I couldn't find any that were
68  *   a) free / GPL, b) simple/lightweight, c) fast, not doing unnecessary strlens all
69  *   over the place.  So.  It is simple, and it seems to work, and it is pretty fast.
70  *
71  *   Oh, and it is also binary safe, ie it can handle strings with embedded NULLs,
72  *   so long as the real length is passed in.
73  *
74  *   And the masses rejoiced.
75  *
76  * BUGS
77  *   there must be some.
78  ******/
79 
80 #include <stdlib.h>
81 #include <string.h>
82 #include <limits.h>
83 #include "simplestring.h"
84 
85 #define my_free(thing)  if(thing) {efree(thing); thing = 0;}
86 
87 /*----------------------**
88 * Begin String Functions *
89 *-----------------------*/
90 
91 /****f* FUNC/simplestring_init
92  * NAME
93  *   simplestring_init
94  * SYNOPSIS
95  *   void simplestring_init(simplestring* string)
96  * FUNCTION
97  *   initialize string
98  * INPUTS
99  *   string - pointer to a simplestring struct that will be initialized
100  * RESULT
101  *   void
102  * NOTES
103  * SEE ALSO
104  *   simplestring_free ()
105  *   simplestring_clear ()
106  * SOURCE
107  */
simplestring_init(simplestring * string)108 void simplestring_init(simplestring* string) {
109    memset(string, 0, sizeof(simplestring));
110 }
111 /******/
112 
simplestring_init_str(simplestring * string)113 static void simplestring_init_str(simplestring* string) {
114    string->str = (char*)emalloc(SIMPLESTRING_INCR);
115    if(string->str) {
116       string->str[0] = 0;
117       string->len = 0;
118       string->size = SIMPLESTRING_INCR;
119    }
120    else {
121       string->size = 0;
122    }
123 }
124 
125 /****f* FUNC/simplestring_clear
126  * NAME
127  *   simplestring_clear
128  * SYNOPSIS
129  *   void simplestring_clear(simplestring* string)
130  * FUNCTION
131  *   clears contents of a string
132  * INPUTS
133  *   string - the string value to clear
134  * RESULT
135  *   void
136  * NOTES
137  *   This function is very fast as it does not de-allocate any memory.
138  * SEE ALSO
139  *
140  * SOURCE
141  */
simplestring_clear(simplestring * string)142 void simplestring_clear(simplestring* string) {
143    if(string->str) {
144       string->str[0] = 0;
145    }
146    string->len = 0;
147 }
148 /******/
149 
150 /****f* FUNC/simplestring_free
151  * NAME
152  *   simplestring_free
153  * SYNOPSIS
154  *   void simplestring_free(simplestring* string)
155  * FUNCTION
156  *   frees contents of a string, if any. Does *not* free the simplestring struct itself.
157  * INPUTS
158  *   string - value containing string to be free'd
159  * RESULT
160  *   void
161  * NOTES
162  *   caller is responsible for allocating and freeing simplestring* struct itself.
163  * SEE ALSO
164  *   simplestring_init ()
165  * SOURCE
166  */
simplestring_free(simplestring * string)167 void simplestring_free(simplestring* string) {
168    if(string && string->str) {
169       my_free(string->str);
170       string->len = 0;
171    }
172 }
173 /******/
174 
175 #ifndef SIZE_MAX
176 #define SIZE_MAX ((size_t)-1)
177 #endif
178 /****f* FUNC/simplestring_addn
179  * NAME
180  *   simplestring_addn
181  * SYNOPSIS
182  *   void simplestring_addn(simplestring* string, const char* add, int add_len)
183  * FUNCTION
184  *   copies n characters from source to target string
185  * INPUTS
186  *   target  - target string
187  *   source  - source string
188  *   add_len - number of characters to copy
189  * RESULT
190  *   void
191  * NOTES
192  * SEE ALSO
193  *   simplestring_add ()
194  * SOURCE
195  */
simplestring_addn(simplestring * target,const char * source,size_t add_len)196 void simplestring_addn(simplestring* target, const char* source, size_t add_len) {
197    size_t newsize = target->size, incr = 0;
198    if(target && source) {
199       if(!target->str) {
200          simplestring_init_str(target);
201       }
202 
203       if((SIZE_MAX - add_len) < target->len || (SIZE_MAX - add_len - 1) < target->len) {
204     	  /* check for overflows, if there's a potential overflow do nothing */
205     	  return;
206       }
207 
208       if(target->len + add_len + 1 > target->size) {
209          /* newsize is current length + new length */
210          newsize = target->len + add_len + 1;
211          incr = target->size * 2;
212 
213          /* align to SIMPLESTRING_INCR increments */
214          if (incr) {
215             newsize = newsize - (newsize % incr) + incr;
216          }
217          if(newsize < (target->len + add_len + 1)) {
218         	 /* some kind of overflow happened */
219         	 return;
220          }
221          target->str = (char*)erealloc(target->str, newsize);
222 
223          target->size = target->str ? newsize : 0;
224       }
225 
226       if(target->str) {
227          if(add_len) {
228             memcpy(target->str + target->len, source, add_len);
229          }
230          target->len += add_len;
231          target->str[target->len] = 0; /* null terminate */
232       }
233    }
234 }
235 /******/
236 
237 /****f* FUNC/simplestring_add
238  * NAME
239  *   simplestring_add
240  * SYNOPSIS
241  *   void simplestring_add(simplestring* string, const char* add)
242  * FUNCTION
243  *   appends a string of unknown length from source to target
244  * INPUTS
245  *   target - the target string to append to
246  *   source - the source string of unknown length
247  * RESULT
248  *   void
249  * NOTES
250  * SEE ALSO
251  *   simplestring_addn ()
252  * SOURCE
253  */
simplestring_add(simplestring * target,const char * source)254 void simplestring_add(simplestring* target, const char* source) {
255    if(target && source) {
256       simplestring_addn(target, source, strlen(source));
257    }
258 }
259 /******/
260 
261 
262 /*----------------------
263 * End String Functions *
264 *--------------------**/
265