xref: /redis-3.2.3/src/util.c (revision 3064e9bd)
1 /*
2  * Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *   * Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *   * Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *   * Neither the name of Redis nor the names of its contributors may be used
14  *     to endorse or promote products derived from this software without
15  *     specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "fmacros.h"
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <limits.h>
36 #include <math.h>
37 #include <unistd.h>
38 #include <sys/time.h>
39 #include <float.h>
40 #include <stdint.h>
41 
42 #include "util.h"
43 
44 /* Glob-style pattern matching. */
45 int stringmatchlen(const char *pattern, int patternLen,
46         const char *string, int stringLen, int nocase)
47 {
48     while(patternLen) {
49         switch(pattern[0]) {
50         case '*':
51             while (pattern[1] == '*') {
52                 pattern++;
53                 patternLen--;
54             }
55             if (patternLen == 1)
56                 return 1; /* match */
57             while(stringLen) {
58                 if (stringmatchlen(pattern+1, patternLen-1,
59                             string, stringLen, nocase))
60                     return 1; /* match */
61                 string++;
62                 stringLen--;
63             }
64             return 0; /* no match */
65             break;
66         case '?':
67             if (stringLen == 0)
68                 return 0; /* no match */
69             string++;
70             stringLen--;
71             break;
72         case '[':
73         {
74             int not, match;
75 
76             pattern++;
77             patternLen--;
78             not = pattern[0] == '^';
79             if (not) {
80                 pattern++;
81                 patternLen--;
82             }
83             match = 0;
84             while(1) {
85                 if (pattern[0] == '\\') {
86                     pattern++;
87                     patternLen--;
88                     if (pattern[0] == string[0])
89                         match = 1;
90                 } else if (pattern[0] == ']') {
91                     break;
92                 } else if (patternLen == 0) {
93                     pattern--;
94                     patternLen++;
95                     break;
96                 } else if (pattern[1] == '-' && patternLen >= 3) {
97                     int start = pattern[0];
98                     int end = pattern[2];
99                     int c = string[0];
100                     if (start > end) {
101                         int t = start;
102                         start = end;
103                         end = t;
104                     }
105                     if (nocase) {
106                         start = tolower(start);
107                         end = tolower(end);
108                         c = tolower(c);
109                     }
110                     pattern += 2;
111                     patternLen -= 2;
112                     if (c >= start && c <= end)
113                         match = 1;
114                 } else {
115                     if (!nocase) {
116                         if (pattern[0] == string[0])
117                             match = 1;
118                     } else {
119                         if (tolower((int)pattern[0]) == tolower((int)string[0]))
120                             match = 1;
121                     }
122                 }
123                 pattern++;
124                 patternLen--;
125             }
126             if (not)
127                 match = !match;
128             if (!match)
129                 return 0; /* no match */
130             string++;
131             stringLen--;
132             break;
133         }
134         case '\\':
135             if (patternLen >= 2) {
136                 pattern++;
137                 patternLen--;
138             }
139             /* fall through */
140         default:
141             if (!nocase) {
142                 if (pattern[0] != string[0])
143                     return 0; /* no match */
144             } else {
145                 if (tolower((int)pattern[0]) != tolower((int)string[0]))
146                     return 0; /* no match */
147             }
148             string++;
149             stringLen--;
150             break;
151         }
152         pattern++;
153         patternLen--;
154         if (stringLen == 0) {
155             while(*pattern == '*') {
156                 pattern++;
157                 patternLen--;
158             }
159             break;
160         }
161     }
162     if (patternLen == 0 && stringLen == 0)
163         return 1;
164     return 0;
165 }
166 
167 int stringmatch(const char *pattern, const char *string, int nocase) {
168     return stringmatchlen(pattern,strlen(pattern),string,strlen(string),nocase);
169 }
170 
171 /* Convert a string representing an amount of memory into the number of
172  * bytes, so for instance memtoll("1Gi") will return 1073741824 that is
173  * (1024*1024*1024).
174  *
175  * On parsing error, if *err is not NULL, it's set to 1, otherwise it's
176  * set to 0 */
177 long long memtoll(const char *p, int *err) {
178     const char *u;
179     char buf[128];
180     long mul; /* unit multiplier */
181     long long val;
182     unsigned int digits;
183 
184     if (err) *err = 0;
185     /* Search the first non digit character. */
186     u = p;
187     if (*u == '-') u++;
188     while(*u && isdigit(*u)) u++;
189     if (*u == '\0' || !strcasecmp(u,"b")) {
190         mul = 1;
191     } else if (!strcasecmp(u,"k")) {
192         mul = 1000;
193     } else if (!strcasecmp(u,"kb")) {
194         mul = 1024;
195     } else if (!strcasecmp(u,"m")) {
196         mul = 1000*1000;
197     } else if (!strcasecmp(u,"mb")) {
198         mul = 1024*1024;
199     } else if (!strcasecmp(u,"g")) {
200         mul = 1000L*1000*1000;
201     } else if (!strcasecmp(u,"gb")) {
202         mul = 1024L*1024*1024;
203     } else {
204         if (err) *err = 1;
205         mul = 1;
206     }
207     digits = u-p;
208     if (digits >= sizeof(buf)) {
209         if (err) *err = 1;
210         return LLONG_MAX;
211     }
212     memcpy(buf,p,digits);
213     buf[digits] = '\0';
214     val = strtoll(buf,NULL,10);
215     return val*mul;
216 }
217 
218 /* Return the number of digits of 'v' when converted to string in radix 10.
219  * See ll2string() for more information. */
220 uint32_t digits10(uint64_t v) {
221     if (v < 10) return 1;
222     if (v < 100) return 2;
223     if (v < 1000) return 3;
224     if (v < 1000000000000UL) {
225         if (v < 100000000UL) {
226             if (v < 1000000) {
227                 if (v < 10000) return 4;
228                 return 5 + (v >= 100000);
229             }
230             return 7 + (v >= 10000000UL);
231         }
232         if (v < 10000000000UL) {
233             return 9 + (v >= 1000000000UL);
234         }
235         return 11 + (v >= 100000000000UL);
236     }
237     return 12 + digits10(v / 1000000000000UL);
238 }
239 
240 /* Convert a long long into a string. Returns the number of
241  * characters needed to represent the number.
242  * If the buffer is not big enough to store the string, 0 is returned.
243  *
244  * Based on the following article (that apparently does not provide a
245  * novel approach but only publicizes an already used technique):
246  *
247  * https://www.facebook.com/notes/facebook-engineering/three-optimization-tips-for-c/10151361643253920
248  *
249  * Modified in order to handle signed integers since the original code was
250  * designed for unsigned integers. */
251 int ll2string(char* dst, size_t dstlen, long long svalue) {
252     static const char digits[201] =
253         "0001020304050607080910111213141516171819"
254         "2021222324252627282930313233343536373839"
255         "4041424344454647484950515253545556575859"
256         "6061626364656667686970717273747576777879"
257         "8081828384858687888990919293949596979899";
258     int negative;
259     unsigned long long value;
260 
261     /* The main loop works with 64bit unsigned integers for simplicity, so
262      * we convert the number here and remember if it is negative. */
263     if (svalue < 0) {
264         if (svalue != LLONG_MIN) {
265             value = -svalue;
266         } else {
267             value = ((unsigned long long) LLONG_MAX)+1;
268         }
269         negative = 1;
270     } else {
271         value = svalue;
272         negative = 0;
273     }
274 
275     /* Check length. */
276     uint32_t const length = digits10(value)+negative;
277     if (length >= dstlen) return 0;
278 
279     /* Null term. */
280     uint32_t next = length;
281     dst[next] = '\0';
282     next--;
283     while (value >= 100) {
284         int const i = (value % 100) * 2;
285         value /= 100;
286         dst[next] = digits[i + 1];
287         dst[next - 1] = digits[i];
288         next -= 2;
289     }
290 
291     /* Handle last 1-2 digits. */
292     if (value < 10) {
293         dst[next] = '0' + (uint32_t) value;
294     } else {
295         int i = (uint32_t) value * 2;
296         dst[next] = digits[i + 1];
297         dst[next - 1] = digits[i];
298     }
299 
300     /* Add sign. */
301     if (negative) dst[0] = '-';
302     return length;
303 }
304 
305 /* Convert a string into a long long. Returns 1 if the string could be parsed
306  * into a (non-overflowing) long long, 0 otherwise. The value will be set to
307  * the parsed value when appropriate. */
308 int string2ll(const char *s, size_t slen, long long *value) {
309     const char *p = s;
310     size_t plen = 0;
311     int negative = 0;
312     unsigned long long v;
313 
314     if (plen == slen)
315         return 0;
316 
317     /* Special case: first and only digit is 0. */
318     if (slen == 1 && p[0] == '0') {
319         if (value != NULL) *value = 0;
320         return 1;
321     }
322 
323     if (p[0] == '-') {
324         negative = 1;
325         p++; plen++;
326 
327         /* Abort on only a negative sign. */
328         if (plen == slen)
329             return 0;
330     }
331 
332     /* First digit should be 1-9, otherwise the string should just be 0. */
333     if (p[0] >= '1' && p[0] <= '9') {
334         v = p[0]-'0';
335         p++; plen++;
336     } else if (p[0] == '0' && slen == 1) {
337         *value = 0;
338         return 1;
339     } else {
340         return 0;
341     }
342 
343     while (plen < slen && p[0] >= '0' && p[0] <= '9') {
344         if (v > (ULLONG_MAX / 10)) /* Overflow. */
345             return 0;
346         v *= 10;
347 
348         if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */
349             return 0;
350         v += p[0]-'0';
351 
352         p++; plen++;
353     }
354 
355     /* Return if not all bytes were used. */
356     if (plen < slen)
357         return 0;
358 
359     if (negative) {
360         if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */
361             return 0;
362         if (value != NULL) *value = -v;
363     } else {
364         if (v > LLONG_MAX) /* Overflow. */
365             return 0;
366         if (value != NULL) *value = v;
367     }
368     return 1;
369 }
370 
371 /* Convert a string into a long. Returns 1 if the string could be parsed into a
372  * (non-overflowing) long, 0 otherwise. The value will be set to the parsed
373  * value when appropriate. */
374 int string2l(const char *s, size_t slen, long *lval) {
375     long long llval;
376 
377     if (!string2ll(s,slen,&llval))
378         return 0;
379 
380     if (llval < LONG_MIN || llval > LONG_MAX)
381         return 0;
382 
383     *lval = (long)llval;
384     return 1;
385 }
386 
387 /* Convert a double to a string representation. Returns the number of bytes
388  * required. The representation should always be parsable by stdtod(3). */
389 int d2string(char *buf, size_t len, double value) {
390     if (isnan(value)) {
391         len = snprintf(buf,len,"nan");
392     } else if (isinf(value)) {
393         if (value < 0)
394             len = snprintf(buf,len,"-inf");
395         else
396             len = snprintf(buf,len,"inf");
397     } else if (value == 0) {
398         /* See: http://en.wikipedia.org/wiki/Signed_zero, "Comparisons". */
399         if (1.0/value < 0)
400             len = snprintf(buf,len,"-0");
401         else
402             len = snprintf(buf,len,"0");
403     } else {
404 #if (DBL_MANT_DIG >= 52) && (LLONG_MAX == 0x7fffffffffffffffLL)
405         /* Check if the float is in a safe range to be casted into a
406          * long long. We are assuming that long long is 64 bit here.
407          * Also we are assuming that there are no implementations around where
408          * double has precision < 52 bit.
409          *
410          * Under this assumptions we test if a double is inside an interval
411          * where casting to long long is safe. Then using two castings we
412          * make sure the decimal part is zero. If all this is true we use
413          * integer printing function that is much faster. */
414         double min = -4503599627370495; /* (2^52)-1 */
415         double max = 4503599627370496; /* -(2^52) */
416         if (value > min && value < max && value == ((double)((long long)value)))
417             len = ll2string(buf,len,(long long)value);
418         else
419 #endif
420             len = snprintf(buf,len,"%.17g",value);
421     }
422 
423     return len;
424 }
425 
426 /* Generate the Redis "Run ID", a SHA1-sized random number that identifies a
427  * given execution of Redis, so that if you are talking with an instance
428  * having run_id == A, and you reconnect and it has run_id == B, you can be
429  * sure that it is either a different instance or it was restarted. */
430 void getRandomHexChars(char *p, unsigned int len) {
431     FILE *fp = fopen("/dev/urandom","r");
432     char *charset = "0123456789abcdef";
433     unsigned int j;
434 
435     if (fp == NULL || fread(p,len,1,fp) == 0) {
436         /* If we can't read from /dev/urandom, do some reasonable effort
437          * in order to create some entropy, since this function is used to
438          * generate run_id and cluster instance IDs */
439         char *x = p;
440         unsigned int l = len;
441         struct timeval tv;
442         pid_t pid = getpid();
443 
444         /* Use time and PID to fill the initial array. */
445         gettimeofday(&tv,NULL);
446         if (l >= sizeof(tv.tv_usec)) {
447             memcpy(x,&tv.tv_usec,sizeof(tv.tv_usec));
448             l -= sizeof(tv.tv_usec);
449             x += sizeof(tv.tv_usec);
450         }
451         if (l >= sizeof(tv.tv_sec)) {
452             memcpy(x,&tv.tv_sec,sizeof(tv.tv_sec));
453             l -= sizeof(tv.tv_sec);
454             x += sizeof(tv.tv_sec);
455         }
456         if (l >= sizeof(pid)) {
457             memcpy(x,&pid,sizeof(pid));
458             l -= sizeof(pid);
459             x += sizeof(pid);
460         }
461         /* Finally xor it with rand() output, that was already seeded with
462          * time() at startup. */
463         for (j = 0; j < len; j++)
464             p[j] ^= rand();
465     }
466     /* Turn it into hex digits taking just 4 bits out of 8 for every byte. */
467     for (j = 0; j < len; j++)
468         p[j] = charset[p[j] & 0x0F];
469     if (fp) fclose(fp);
470 }
471 
472 /* Given the filename, return the absolute path as an SDS string, or NULL
473  * if it fails for some reason. Note that "filename" may be an absolute path
474  * already, this will be detected and handled correctly.
475  *
476  * The function does not try to normalize everything, but only the obvious
477  * case of one or more "../" appearning at the start of "filename"
478  * relative path. */
479 sds getAbsolutePath(char *filename) {
480     char cwd[1024];
481     sds abspath;
482     sds relpath = sdsnew(filename);
483 
484     relpath = sdstrim(relpath," \r\n\t");
485     if (relpath[0] == '/') return relpath; /* Path is already absolute. */
486 
487     /* If path is relative, join cwd and relative path. */
488     if (getcwd(cwd,sizeof(cwd)) == NULL) {
489         sdsfree(relpath);
490         return NULL;
491     }
492     abspath = sdsnew(cwd);
493     if (sdslen(abspath) && abspath[sdslen(abspath)-1] != '/')
494         abspath = sdscat(abspath,"/");
495 
496     /* At this point we have the current path always ending with "/", and
497      * the trimmed relative path. Try to normalize the obvious case of
498      * trailing ../ elements at the start of the path.
499      *
500      * For every "../" we find in the filename, we remove it and also remove
501      * the last element of the cwd, unless the current cwd is "/". */
502     while (sdslen(relpath) >= 3 &&
503            relpath[0] == '.' && relpath[1] == '.' && relpath[2] == '/')
504     {
505         sdsrange(relpath,3,-1);
506         if (sdslen(abspath) > 1) {
507             char *p = abspath + sdslen(abspath)-2;
508             int trimlen = 1;
509 
510             while(*p != '/') {
511                 p--;
512                 trimlen++;
513             }
514             sdsrange(abspath,0,-(trimlen+1));
515         }
516     }
517 
518     /* Finally glue the two parts together. */
519     abspath = sdscatsds(abspath,relpath);
520     sdsfree(relpath);
521     return abspath;
522 }
523 
524 /* Return true if the specified path is just a file basename without any
525  * relative or absolute path. This function just checks that no / or \
526  * character exists inside the specified path, that's enough in the
527  * environments where Redis runs. */
528 int pathIsBaseName(char *path) {
529     return strchr(path,'/') == NULL && strchr(path,'\\') == NULL;
530 }
531 
532 #ifdef UTIL_TEST_MAIN
533 #include <assert.h>
534 
535 void test_string2ll(void) {
536     char buf[32];
537     long long v;
538 
539     /* May not start with +. */
540     strcpy(buf,"+1");
541     assert(string2ll(buf,strlen(buf),&v) == 0);
542 
543     /* Leading space. */
544     strcpy(buf," 1");
545     assert(string2ll(buf,strlen(buf),&v) == 0);
546 
547     /* Trailing space. */
548     strcpy(buf,"1 ");
549     assert(string2ll(buf,strlen(buf),&v) == 0);
550 
551     /* May not start with 0. */
552     strcpy(buf,"01");
553     assert(string2ll(buf,strlen(buf),&v) == 0);
554 
555     strcpy(buf,"-1");
556     assert(string2ll(buf,strlen(buf),&v) == 1);
557     assert(v == -1);
558 
559     strcpy(buf,"0");
560     assert(string2ll(buf,strlen(buf),&v) == 1);
561     assert(v == 0);
562 
563     strcpy(buf,"1");
564     assert(string2ll(buf,strlen(buf),&v) == 1);
565     assert(v == 1);
566 
567     strcpy(buf,"99");
568     assert(string2ll(buf,strlen(buf),&v) == 1);
569     assert(v == 99);
570 
571     strcpy(buf,"-99");
572     assert(string2ll(buf,strlen(buf),&v) == 1);
573     assert(v == -99);
574 
575     strcpy(buf,"-9223372036854775808");
576     assert(string2ll(buf,strlen(buf),&v) == 1);
577     assert(v == LLONG_MIN);
578 
579     strcpy(buf,"-9223372036854775809"); /* overflow */
580     assert(string2ll(buf,strlen(buf),&v) == 0);
581 
582     strcpy(buf,"9223372036854775807");
583     assert(string2ll(buf,strlen(buf),&v) == 1);
584     assert(v == LLONG_MAX);
585 
586     strcpy(buf,"9223372036854775808"); /* overflow */
587     assert(string2ll(buf,strlen(buf),&v) == 0);
588 }
589 
590 void test_string2l(void) {
591     char buf[32];
592     long v;
593 
594     /* May not start with +. */
595     strcpy(buf,"+1");
596     assert(string2l(buf,strlen(buf),&v) == 0);
597 
598     /* May not start with 0. */
599     strcpy(buf,"01");
600     assert(string2l(buf,strlen(buf),&v) == 0);
601 
602     strcpy(buf,"-1");
603     assert(string2l(buf,strlen(buf),&v) == 1);
604     assert(v == -1);
605 
606     strcpy(buf,"0");
607     assert(string2l(buf,strlen(buf),&v) == 1);
608     assert(v == 0);
609 
610     strcpy(buf,"1");
611     assert(string2l(buf,strlen(buf),&v) == 1);
612     assert(v == 1);
613 
614     strcpy(buf,"99");
615     assert(string2l(buf,strlen(buf),&v) == 1);
616     assert(v == 99);
617 
618     strcpy(buf,"-99");
619     assert(string2l(buf,strlen(buf),&v) == 1);
620     assert(v == -99);
621 
622 #if LONG_MAX != LLONG_MAX
623     strcpy(buf,"-2147483648");
624     assert(string2l(buf,strlen(buf),&v) == 1);
625     assert(v == LONG_MIN);
626 
627     strcpy(buf,"-2147483649"); /* overflow */
628     assert(string2l(buf,strlen(buf),&v) == 0);
629 
630     strcpy(buf,"2147483647");
631     assert(string2l(buf,strlen(buf),&v) == 1);
632     assert(v == LONG_MAX);
633 
634     strcpy(buf,"2147483648"); /* overflow */
635     assert(string2l(buf,strlen(buf),&v) == 0);
636 #endif
637 }
638 
639 int main(int argc, char **argv) {
640     test_string2ll();
641     test_string2l();
642     return 0;
643 }
644 #endif
645