Bug Summary

File:libs/apr/strings/apr_strings.c
Location:line 159, column 17
Description:Assigned value is garbage or undefined

Annotated Source Code

1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16/*
17 * Copyright (c) 1990, 1993
18 * The Regents of the University of California. All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * 3. All advertising materials mentioning features or use of this software
29 * must display the following acknowledgement:
30 * This product includes software developed by the University of
31 * California, Berkeley and its contributors.
32 * 4. Neither the name of the University nor the names of its contributors
33 * may be used to endorse or promote products derived from this software
34 * without specific prior written permission.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
37 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
40 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
42 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
47 */
48
49#include "apr.h"
50#include "apr_strings.h"
51#include "apr_general.h"
52#include "apr_private.h"
53#include "apr_lib.h"
54#define APR_WANT_STDIO
55#define APR_WANT_STRFUNC
56#include "apr_want.h"
57
58#ifdef HAVE_STDDEF_H1
59#include <stddef.h> /* NULL */
60#endif
61
62#ifdef HAVE_STDLIB_H1
63#include <stdlib.h> /* strtol and strtoll */
64#endif
65
66/** this is used to cache lengths in apr_pstrcat */
67#define MAX_SAVED_LENGTHS6 6
68
69APR_DECLARE(char *)char * apr_pstrdup(apr_pool_t *a, const char *s)
70{
71 char *res;
72 apr_size_t len;
73
74 if (s == NULL((void*)0)) {
75 return NULL((void*)0);
76 }
77 len = strlen(s) + 1;
78 res = apr_palloc(a, len);
79 memcpy(res, s, len);
80 return res;
81}
82
83APR_DECLARE(char *)char * apr_pstrndup(apr_pool_t *a, const char *s, apr_size_t n)
84{
85 char *res;
86 const char *end;
87
88 if (s == NULL((void*)0)) {
89 return NULL((void*)0);
90 }
91 end = memchr(s, '\0', n);
92 if (end != NULL((void*)0))
93 n = end - s;
94 res = apr_palloc(a, n + 1);
95 memcpy(res, s, n);
96 res[n] = '\0';
97 return res;
98}
99
100APR_DECLARE(char *)char * apr_pstrmemdup(apr_pool_t *a, const char *s, apr_size_t n)
101{
102 char *res;
103
104 if (s == NULL((void*)0)) {
105 return NULL((void*)0);
106 }
107 res = apr_palloc(a, n + 1);
108 memcpy(res, s, n);
109 res[n] = '\0';
110 return res;
111}
112
113APR_DECLARE(void *)void * apr_pmemdup(apr_pool_t *a, const void *m, apr_size_t n)
114{
115 void *res;
116
117 if (m == NULL((void*)0))
118 return NULL((void*)0);
119 res = apr_palloc(a, n);
120 memcpy(res, m, n);
121 return res;
122}
123
124APR_DECLARE_NONSTD(char *)char * apr_pstrcat(apr_pool_t *a, ...)
125{
126 char *cp, *argp, *res;
127 apr_size_t saved_lengths[MAX_SAVED_LENGTHS6];
128 int nargs = 0;
129
130 /* Pass one --- find length of required string */
131
132 apr_size_t len = 0;
133 va_list adummy;
134
135 va_start(adummy, a)__builtin_va_start(adummy, a);
136
137 while ((cp = va_arg(adummy, char *)__builtin_va_arg(adummy, char *)) != NULL((void*)0)) {
1
Loop condition is false. Execution continues on line 145
138 apr_size_t cplen = strlen(cp);
139 if (nargs < MAX_SAVED_LENGTHS6) {
140 saved_lengths[nargs++] = cplen;
141 }
142 len += cplen;
143 }
144
145 va_end(adummy)__builtin_va_end(adummy);
146
147 /* Allocate the required string */
148
149 res = (char *) apr_palloc(a, len + 1);
150 cp = res;
151
152 /* Pass two --- copy the argument strings into the result space */
153
154 va_start(adummy, a)__builtin_va_start(adummy, a);
155
156 nargs = 0;
157 while ((argp = va_arg(adummy, char *)__builtin_va_arg(adummy, char *)) != NULL((void*)0)) {
2
Loop condition is true. Entering loop body
158 if (nargs < MAX_SAVED_LENGTHS6) {
3
Taking true branch
159 len = saved_lengths[nargs++];
4
Assigned value is garbage or undefined
160 }
161 else {
162 len = strlen(argp);
163 }
164
165 memcpy(cp, argp, len);
166 cp += len;
167 }
168
169 va_end(adummy)__builtin_va_end(adummy);
170
171 /* Return the result string */
172
173 *cp = '\0';
174
175 return res;
176}
177
178APR_DECLARE(char *)char * apr_pstrcatv(apr_pool_t *a, const struct iovec *vec,
179 apr_size_t nvec, apr_size_t *nbytes)
180{
181 apr_size_t i;
182 apr_size_t len;
183 const struct iovec *src;
184 char *res;
185 char *dst;
186
187 /* Pass one --- find length of required string */
188 len = 0;
189 src = vec;
190 for (i = nvec; i; i--) {
191 len += src->iov_len;
192 src++;
193 }
194 if (nbytes) {
195 *nbytes = len;
196 }
197
198 /* Allocate the required string */
199 res = (char *) apr_palloc(a, len + 1);
200
201 /* Pass two --- copy the argument strings into the result space */
202 src = vec;
203 dst = res;
204 for (i = nvec; i; i--) {
205 memcpy(dst, src->iov_base, src->iov_len);
206 dst += src->iov_len;
207 src++;
208 }
209
210 /* Return the result string */
211 *dst = '\0';
212
213 return res;
214}
215
216#if (!APR_HAVE_MEMCHR1)
217void *memchr(const void *s, int c, size_t n)
218{
219 const char *cp;
220
221 for (cp = s; n > 0; n--, cp++) {
222 if (*cp == c)
223 return (char *) cp; /* Casting away the const here */
224 }
225
226 return NULL((void*)0);
227}
228#endif
229
230#ifndef INT64_MAX(9223372036854775807L)
231#define INT64_MAX(9223372036854775807L) APR_INT64_C(0x7fffffffffffffff)0x7fffffffffffffffL
232#endif
233#ifndef INT64_MIN(-9223372036854775807L -1)
234#define INT64_MIN(-9223372036854775807L -1) (-APR_INT64_C(0x7fffffffffffffff)0x7fffffffffffffffL - APR_INT64_C(1)1L)
235#endif
236
237APR_DECLARE(apr_status_t)apr_status_t apr_strtoff(apr_off_t *offset, const char *nptr,
238 char **endptr, int base)
239{
240 errno(*__errno_location ()) = 0;
241 *offset = APR_OFF_T_STRFNstrtol(nptr, endptr, base);
242 return APR_FROM_OS_ERROR(errno)((*__errno_location ()));
243}
244
245APR_DECLARE(apr_int64_t)apr_int64_t apr_strtoi64(const char *nptr, char **endptr, int base)
246{
247#ifdef APR_INT64_STRFNstrtol
248 return APR_INT64_STRFNstrtol(nptr, endptr, base);
249#else
250 const char *s;
251 apr_int64_t acc;
252 apr_int64_t val;
253 int neg, any;
254 char c;
255
256 /*
257 * Skip white space and pick up leading +/- sign if any.
258 * If base is 0, allow 0x for hex and 0 for octal, else
259 * assume decimal; if base is already 16, allow 0x.
260 */
261 s = nptr;
262 do {
263 c = *s++;
264 } while (apr_isspace(c)(((*__ctype_b_loc ())[(int) ((((unsigned char)(c))))] & (
unsigned short int) _ISspace))
);
265 if (c == '-') {
266 neg = 1;
267 c = *s++;
268 } else {
269 neg = 0;
270 if (c == '+')
271 c = *s++;
272 }
273 if ((base == 0 || base == 16) &&
274 c == '0' && (*s == 'x' || *s == 'X')) {
275 c = s[1];
276 s += 2;
277 base = 16;
278 }
279 if (base == 0)
280 base = c == '0' ? 8 : 10;
281 acc = any = 0;
282 if (base < 2 || base > 36) {
283 errno(*__errno_location ()) = EINVAL22;
284 if (endptr != NULL((void*)0))
285 *endptr = (char *)(any ? s - 1 : nptr);
286 return acc;
287 }
288
289 /* The classic bsd implementation requires div/mod operators
290 * to compute a cutoff. Benchmarking proves that is very, very
291 * evil to some 32 bit processors. Instead, look for underflow
292 * in both the mult and add/sub operation. Unlike the bsd impl,
293 * we also work strictly in a signed int64 word as we haven't
294 * implemented the unsigned type in win32.
295 *
296 * Set 'any' if any `digits' consumed; make it negative to indicate
297 * overflow.
298 */
299 val = 0;
300 for ( ; ; c = *s++) {
301 if (c >= '0' && c <= '9')
302 c -= '0';
303#if (('Z' - 'A') == 25)
304 else if (c >= 'A' && c <= 'Z')
305 c -= 'A' - 10;
306 else if (c >= 'a' && c <= 'z')
307 c -= 'a' - 10;
308#elif APR_CHARSET_EBCDIC0
309 else if (c >= 'A' && c <= 'I')
310 c -= 'A' - 10;
311 else if (c >= 'J' && c <= 'R')
312 c -= 'J' - 19;
313 else if (c >= 'S' && c <= 'Z')
314 c -= 'S' - 28;
315 else if (c >= 'a' && c <= 'i')
316 c -= 'a' - 10;
317 else if (c >= 'j' && c <= 'r')
318 c -= 'j' - 19;
319 else if (c >= 's' && c <= 'z')
320 c -= 'z' - 28;
321#else
322#error "CANNOT COMPILE apr_strtoi64(), only ASCII and EBCDIC supported"
323#endif
324 else
325 break;
326 if (c >= base)
327 break;
328 val *= base;
329 if ( (any < 0) /* already noted an over/under flow - short circuit */
330 || (neg && (val > acc || (val -= c) > acc)) /* underflow */
331 || (!neg && (val < acc || (val += c) < acc))) { /* overflow */
332 any = -1; /* once noted, over/underflows never go away */
333#ifdef APR_STRTOI64_OVERFLOW_IS_BAD_CHAR
334 break;
335#endif
336 } else {
337 acc = val;
338 any = 1;
339 }
340 }
341
342 if (any < 0) {
343 acc = neg ? INT64_MIN(-9223372036854775807L -1) : INT64_MAX(9223372036854775807L);
344 errno(*__errno_location ()) = ERANGE34;
345 } else if (!any) {
346 errno(*__errno_location ()) = EINVAL22;
347 }
348 if (endptr != NULL((void*)0))
349 *endptr = (char *)(any ? s - 1 : nptr);
350 return (acc);
351#endif
352}
353
354APR_DECLARE(apr_int64_t)apr_int64_t apr_atoi64(const char *buf)
355{
356 return apr_strtoi64(buf, NULL((void*)0), 10);
357}
358
359APR_DECLARE(char *)char * apr_itoa(apr_pool_t *p, int n)
360{
361 const int BUFFER_SIZE = sizeof(int) * 3 + 2;
362 char *buf = apr_palloc(p, BUFFER_SIZE);
363 char *start = buf + BUFFER_SIZE - 1;
364 int negative;
365 if (n < 0) {
366 negative = 1;
367 n = -n;
368 }
369 else {
370 negative = 0;
371 }
372 *start = 0;
373 do {
374 *--start = '0' + (n % 10);
375 n /= 10;
376 } while (n);
377 if (negative) {
378 *--start = '-';
379 }
380 return start;
381}
382
383APR_DECLARE(char *)char * apr_ltoa(apr_pool_t *p, long n)
384{
385 const int BUFFER_SIZE = sizeof(long) * 3 + 2;
386 char *buf = apr_palloc(p, BUFFER_SIZE);
387 char *start = buf + BUFFER_SIZE - 1;
388 int negative;
389 if (n < 0) {
390 negative = 1;
391 n = -n;
392 }
393 else {
394 negative = 0;
395 }
396 *start = 0;
397 do {
398 *--start = (char)('0' + (n % 10));
399 n /= 10;
400 } while (n);
401 if (negative) {
402 *--start = '-';
403 }
404 return start;
405}
406
407APR_DECLARE(char *)char * apr_off_t_toa(apr_pool_t *p, apr_off_t n)
408{
409 const int BUFFER_SIZE = sizeof(apr_off_t) * 3 + 2;
410 char *buf = apr_palloc(p, BUFFER_SIZE);
411 char *start = buf + BUFFER_SIZE - 1;
412 int negative;
413 if (n < 0) {
414 negative = 1;
415 n = -n;
416 }
417 else {
418 negative = 0;
419 }
420 *start = 0;
421 do {
422 *--start = '0' + (char)(n % 10);
423 n /= 10;
424 } while (n);
425 if (negative) {
426 *--start = '-';
427 }
428 return start;
429}
430
431APR_DECLARE(char *)char * apr_strfsize(apr_off_t size, char *buf)
432{
433 const char ord[] = "KMGTPE";
434 const char *o = ord;
435 int remain;
436
437 if (size < 0) {
438 return strcpy(buf, " - ");
439 }
440 if (size < 973) {
441 if (apr_snprintf(buf, 5, "%3d ", (int) size) < 0)
442 return strcpy(buf, "****");
443 return buf;
444 }
445 do {
446 remain = (int)(size & 1023);
447 size >>= 10;
448 if (size >= 973) {
449 ++o;
450 continue;
451 }
452 if (size < 9 || (size == 9 && remain < 973)) {
453 if ((remain = ((remain * 5) + 256) / 512) >= 10)
454 ++size, remain = 0;
455 if (apr_snprintf(buf, 5, "%d.%d%c", (int) size, remain, *o) < 0)
456 return strcpy(buf, "****");
457 return buf;
458 }
459 if (remain >= 512)
460 ++size;
461 if (apr_snprintf(buf, 5, "%3d%c", (int) size, *o) < 0)
462 return strcpy(buf, "****");
463 return buf;
464 } while (1);
465}
466