xref: /redis-3.2.3/src/util.c (revision d5ba544e)
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 #include "sha1.h"
44 
45 /* Glob-style pattern matching. */
46 int stringmatchlen(const char *pattern, int patternLen,
47         const char *string, int stringLen, int nocase)
48 {
49     while(patternLen) {
50         switch(pattern[0]) {
51         case '*':
52             while (pattern[1] == '*') {
53                 pattern++;
54                 patternLen--;
55             }
56             if (patternLen == 1)
57                 return 1; /* match */
58             while(stringLen) {
59                 if (stringmatchlen(pattern+1, patternLen-1,
60                             string, stringLen, nocase))
61                     return 1; /* match */
62                 string++;
63                 stringLen--;
64             }
65             return 0; /* no match */
66             break;
67         case '?':
68             if (stringLen == 0)
69                 return 0; /* no match */
70             string++;
71             stringLen--;
72             break;
73         case '[':
74         {
75             int not, match;
76 
77             pattern++;
78             patternLen--;
79             not = pattern[0] == '^';
80             if (not) {
81                 pattern++;
82                 patternLen--;
83             }
84             match = 0;
85             while(1) {
86                 if (pattern[0] == '\\') {
87                     pattern++;
88                     patternLen--;
89                     if (pattern[0] == string[0])
90                         match = 1;
91                 } else if (pattern[0] == ']') {
92                     break;
93                 } else if (patternLen == 0) {
94                     pattern--;
95                     patternLen++;
96                     break;
97                 } else if (pattern[1] == '-' && patternLen >= 3) {
98                     int start = pattern[0];
99                     int end = pattern[2];
100                     int c = string[0];
101                     if (start > end) {
102                         int t = start;
103                         start = end;
104                         end = t;
105                     }
106                     if (nocase) {
107                         start = tolower(start);
108                         end = tolower(end);
109                         c = tolower(c);
110                     }
111                     pattern += 2;
112                     patternLen -= 2;
113                     if (c >= start && c <= end)
114                         match = 1;
115                 } else {
116                     if (!nocase) {
117                         if (pattern[0] == string[0])
118                             match = 1;
119                     } else {
120                         if (tolower((int)pattern[0]) == tolower((int)string[0]))
121                             match = 1;
122                     }
123                 }
124                 pattern++;
125                 patternLen--;
126             }
127             if (not)
128                 match = !match;
129             if (!match)
130                 return 0; /* no match */
131             string++;
132             stringLen--;
133             break;
134         }
135         case '\\':
136             if (patternLen >= 2) {
137                 pattern++;
138                 patternLen--;
139             }
140             /* fall through */
141         default:
142             if (!nocase) {
143                 if (pattern[0] != string[0])
144                     return 0; /* no match */
145             } else {
146                 if (tolower((int)pattern[0]) != tolower((int)string[0]))
147                     return 0; /* no match */
148             }
149             string++;
150             stringLen--;
151             break;
152         }
153         pattern++;
154         patternLen--;
155         if (stringLen == 0) {
156             while(*pattern == '*') {
157                 pattern++;
158                 patternLen--;
159             }
160             break;
161         }
162     }
163     if (patternLen == 0 && stringLen == 0)
164         return 1;
165     return 0;
166 }
167 
168 int stringmatch(const char *pattern, const char *string, int nocase) {
169     return stringmatchlen(pattern,strlen(pattern),string,strlen(string),nocase);
170 }
171 
172 /* Convert a string representing an amount of memory into the number of
173  * bytes, so for instance memtoll("1Gi") will return 1073741824 that is
174  * (1024*1024*1024).
175  *
176  * On parsing error, if *err is not NULL, it's set to 1, otherwise it's
177  * set to 0 */
178 long long memtoll(const char *p, int *err) {
179     const char *u;
180     char buf[128];
181     long mul; /* unit multiplier */
182     long long val;
183     unsigned int digits;
184 
185     if (err) *err = 0;
186     /* Search the first non digit character. */
187     u = p;
188     if (*u == '-') u++;
189     while(*u && isdigit(*u)) u++;
190     if (*u == '\0' || !strcasecmp(u,"b")) {
191         mul = 1;
192     } else if (!strcasecmp(u,"k")) {
193         mul = 1000;
194     } else if (!strcasecmp(u,"kb")) {
195         mul = 1024;
196     } else if (!strcasecmp(u,"m")) {
197         mul = 1000*1000;
198     } else if (!strcasecmp(u,"mb")) {
199         mul = 1024*1024;
200     } else if (!strcasecmp(u,"g")) {
201         mul = 1000L*1000*1000;
202     } else if (!strcasecmp(u,"gb")) {
203         mul = 1024L*1024*1024;
204     } else {
205         if (err) *err = 1;
206         mul = 1;
207     }
208     digits = u-p;
209     if (digits >= sizeof(buf)) {
210         if (err) *err = 1;
211         return LLONG_MAX;
212     }
213     memcpy(buf,p,digits);
214     buf[digits] = '\0';
215     val = strtoll(buf,NULL,10);
216     return val*mul;
217 }
218 
219 /* Return the number of digits of 'v' when converted to string in radix 10.
220  * See ll2string() for more information. */
221 uint32_t digits10(uint64_t v) {
222     if (v < 10) return 1;
223     if (v < 100) return 2;
224     if (v < 1000) return 3;
225     if (v < 1000000000000UL) {
226         if (v < 100000000UL) {
227             if (v < 1000000) {
228                 if (v < 10000) return 4;
229                 return 5 + (v >= 100000);
230             }
231             return 7 + (v >= 10000000UL);
232         }
233         if (v < 10000000000UL) {
234             return 9 + (v >= 1000000000UL);
235         }
236         return 11 + (v >= 100000000000UL);
237     }
238     return 12 + digits10(v / 1000000000000UL);
239 }
240 
241 /* Convert a long long into a string. Returns the number of
242  * characters needed to represent the number.
243  * If the buffer is not big enough to store the string, 0 is returned.
244  *
245  * Based on the following article (that apparently does not provide a
246  * novel approach but only publicizes an already used technique):
247  *
248  * https://www.facebook.com/notes/facebook-engineering/three-optimization-tips-for-c/10151361643253920
249  *
250  * Modified in order to handle signed integers since the original code was
251  * designed for unsigned integers. */
252 int ll2string(char* dst, size_t dstlen, long long svalue) {
253     static const char digits[201] =
254         "0001020304050607080910111213141516171819"
255         "2021222324252627282930313233343536373839"
256         "4041424344454647484950515253545556575859"
257         "6061626364656667686970717273747576777879"
258         "8081828384858687888990919293949596979899";
259     int negative;
260     unsigned long long value;
261 
262     /* The main loop works with 64bit unsigned integers for simplicity, so
263      * we convert the number here and remember if it is negative. */
264     if (svalue < 0) {
265         if (svalue != LLONG_MIN) {
266             value = -svalue;
267         } else {
268             value = ((unsigned long long) LLONG_MAX)+1;
269         }
270         negative = 1;
271     } else {
272         value = svalue;
273         negative = 0;
274     }
275 
276     /* Check length. */
277     uint32_t const length = digits10(value)+negative;
278     if (length >= dstlen) return 0;
279 
280     /* Null term. */
281     uint32_t next = length;
282     dst[next] = '\0';
283     next--;
284     while (value >= 100) {
285         int const i = (value % 100) * 2;
286         value /= 100;
287         dst[next] = digits[i + 1];
288         dst[next - 1] = digits[i];
289         next -= 2;
290     }
291 
292     /* Handle last 1-2 digits. */
293     if (value < 10) {
294         dst[next] = '0' + (uint32_t) value;
295     } else {
296         int i = (uint32_t) value * 2;
297         dst[next] = digits[i + 1];
298         dst[next - 1] = digits[i];
299     }
300 
301     /* Add sign. */
302     if (negative) dst[0] = '-';
303     return length;
304 }
305 
306 /* Convert a string into a long long. Returns 1 if the string could be parsed
307  * into a (non-overflowing) long long, 0 otherwise. The value will be set to
308  * the parsed value when appropriate. */
309 int string2ll(const char *s, size_t slen, long long *value) {
310     const char *p = s;
311     size_t plen = 0;
312     int negative = 0;
313     unsigned long long v;
314 
315     if (plen == slen)
316         return 0;
317 
318     /* Special case: first and only digit is 0. */
319     if (slen == 1 && p[0] == '0') {
320         if (value != NULL) *value = 0;
321         return 1;
322     }
323 
324     if (p[0] == '-') {
325         negative = 1;
326         p++; plen++;
327 
328         /* Abort on only a negative sign. */
329         if (plen == slen)
330             return 0;
331     }
332 
333     /* First digit should be 1-9, otherwise the string should just be 0. */
334     if (p[0] >= '1' && p[0] <= '9') {
335         v = p[0]-'0';
336         p++; plen++;
337     } else if (p[0] == '0' && slen == 1) {
338         *value = 0;
339         return 1;
340     } else {
341         return 0;
342     }
343 
344     while (plen < slen && p[0] >= '0' && p[0] <= '9') {
345         if (v > (ULLONG_MAX / 10)) /* Overflow. */
346             return 0;
347         v *= 10;
348 
349         if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */
350             return 0;
351         v += p[0]-'0';
352 
353         p++; plen++;
354     }
355 
356     /* Return if not all bytes were used. */
357     if (plen < slen)
358         return 0;
359 
360     if (negative) {
361         if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */
362             return 0;
363         if (value != NULL) *value = -v;
364     } else {
365         if (v > LLONG_MAX) /* Overflow. */
366             return 0;
367         if (value != NULL) *value = v;
368     }
369     return 1;
370 }
371 
372 /* Convert a string into a long. Returns 1 if the string could be parsed into a
373  * (non-overflowing) long, 0 otherwise. The value will be set to the parsed
374  * value when appropriate. */
375 int string2l(const char *s, size_t slen, long *lval) {
376     long long llval;
377 
378     if (!string2ll(s,slen,&llval))
379         return 0;
380 
381     if (llval < LONG_MIN || llval > LONG_MAX)
382         return 0;
383 
384     *lval = (long)llval;
385     return 1;
386 }
387 
388 /* Convert a double to a string representation. Returns the number of bytes
389  * required. The representation should always be parsable by strtod(3). */
390 int d2string(char *buf, size_t len, double value) {
391     if (isnan(value)) {
392         len = snprintf(buf,len,"nan");
393     } else if (isinf(value)) {
394         if (value < 0)
395             len = snprintf(buf,len,"-inf");
396         else
397             len = snprintf(buf,len,"inf");
398     } else if (value == 0) {
399         /* See: http://en.wikipedia.org/wiki/Signed_zero, "Comparisons". */
400         if (1.0/value < 0)
401             len = snprintf(buf,len,"-0");
402         else
403             len = snprintf(buf,len,"0");
404     } else {
405 #if (DBL_MANT_DIG >= 52) && (LLONG_MAX == 0x7fffffffffffffffLL)
406         /* Check if the float is in a safe range to be casted into a
407          * long long. We are assuming that long long is 64 bit here.
408          * Also we are assuming that there are no implementations around where
409          * double has precision < 52 bit.
410          *
411          * Under this assumptions we test if a double is inside an interval
412          * where casting to long long is safe. Then using two castings we
413          * make sure the decimal part is zero. If all this is true we use
414          * integer printing function that is much faster. */
415         double min = -4503599627370495; /* (2^52)-1 */
416         double max = 4503599627370496; /* -(2^52) */
417         if (value > min && value < max && value == ((double)((long long)value)))
418             len = ll2string(buf,len,(long long)value);
419         else
420 #endif
421             len = snprintf(buf,len,"%.17g",value);
422     }
423 
424     return len;
425 }
426 
427 /* Generate the Redis "Run ID", a SHA1-sized random number that identifies a
428  * given execution of Redis, so that if you are talking with an instance
429  * having run_id == A, and you reconnect and it has run_id == B, you can be
430  * sure that it is either a different instance or it was restarted. */
431 void getRandomHexChars(char *p, unsigned int len) {
432     char *charset = "0123456789abcdef";
433     unsigned int j;
434 
435     /* Global state. */
436     static int seed_initialized = 0;
437     static unsigned char seed[20]; /* The SHA1 seed, from /dev/urandom. */
438     static uint64_t counter = 0; /* The counter we hash with the seed. */
439 
440     if (!seed_initialized) {
441         /* Initialize a seed and use SHA1 in counter mode, where we hash
442          * the same seed with a progressive counter. For the goals of this
443          * function we just need non-colliding strings, there are no
444          * cryptographic security needs. */
445         FILE *fp = fopen("/dev/urandom","r");
446         if (fp && fread(seed,sizeof(seed),1,fp) == 1)
447             seed_initialized = 1;
448         if (fp) fclose(fp);
449     }
450 
451     if (seed_initialized) {
452         while(len) {
453             unsigned char digest[20];
454             SHA1_CTX ctx;
455             unsigned int copylen = len > 20 ? 20 : len;
456 
457             SHA1Init(&ctx);
458             SHA1Update(&ctx, seed, sizeof(seed));
459             SHA1Update(&ctx, (unsigned char*)&counter,sizeof(counter));
460             SHA1Final(digest, &ctx);
461             counter++;
462 
463             memcpy(p,digest,copylen);
464             /* Convert to hex digits. */
465             for (j = 0; j < copylen; j++) p[j] = charset[p[j] & 0x0F];
466             len -= copylen;
467             p += copylen;
468         }
469     } else {
470         /* If we can't read from /dev/urandom, do some reasonable effort
471          * in order to create some entropy, since this function is used to
472          * generate run_id and cluster instance IDs */
473         char *x = p;
474         unsigned int l = len;
475         struct timeval tv;
476         pid_t pid = getpid();
477 
478         /* Use time and PID to fill the initial array. */
479         gettimeofday(&tv,NULL);
480         if (l >= sizeof(tv.tv_usec)) {
481             memcpy(x,&tv.tv_usec,sizeof(tv.tv_usec));
482             l -= sizeof(tv.tv_usec);
483             x += sizeof(tv.tv_usec);
484         }
485         if (l >= sizeof(tv.tv_sec)) {
486             memcpy(x,&tv.tv_sec,sizeof(tv.tv_sec));
487             l -= sizeof(tv.tv_sec);
488             x += sizeof(tv.tv_sec);
489         }
490         if (l >= sizeof(pid)) {
491             memcpy(x,&pid,sizeof(pid));
492             l -= sizeof(pid);
493             x += sizeof(pid);
494         }
495         /* Finally xor it with rand() output, that was already seeded with
496          * time() at startup, and convert to hex digits. */
497         for (j = 0; j < len; j++) {
498             p[j] ^= rand();
499             p[j] = charset[p[j] & 0x0F];
500         }
501     }
502 }
503 
504 /* Given the filename, return the absolute path as an SDS string, or NULL
505  * if it fails for some reason. Note that "filename" may be an absolute path
506  * already, this will be detected and handled correctly.
507  *
508  * The function does not try to normalize everything, but only the obvious
509  * case of one or more "../" appearning at the start of "filename"
510  * relative path. */
511 sds getAbsolutePath(char *filename) {
512     char cwd[1024];
513     sds abspath;
514     sds relpath = sdsnew(filename);
515 
516     relpath = sdstrim(relpath," \r\n\t");
517     if (relpath[0] == '/') return relpath; /* Path is already absolute. */
518 
519     /* If path is relative, join cwd and relative path. */
520     if (getcwd(cwd,sizeof(cwd)) == NULL) {
521         sdsfree(relpath);
522         return NULL;
523     }
524     abspath = sdsnew(cwd);
525     if (sdslen(abspath) && abspath[sdslen(abspath)-1] != '/')
526         abspath = sdscat(abspath,"/");
527 
528     /* At this point we have the current path always ending with "/", and
529      * the trimmed relative path. Try to normalize the obvious case of
530      * trailing ../ elements at the start of the path.
531      *
532      * For every "../" we find in the filename, we remove it and also remove
533      * the last element of the cwd, unless the current cwd is "/". */
534     while (sdslen(relpath) >= 3 &&
535            relpath[0] == '.' && relpath[1] == '.' && relpath[2] == '/')
536     {
537         sdsrange(relpath,3,-1);
538         if (sdslen(abspath) > 1) {
539             char *p = abspath + sdslen(abspath)-2;
540             int trimlen = 1;
541 
542             while(*p != '/') {
543                 p--;
544                 trimlen++;
545             }
546             sdsrange(abspath,0,-(trimlen+1));
547         }
548     }
549 
550     /* Finally glue the two parts together. */
551     abspath = sdscatsds(abspath,relpath);
552     sdsfree(relpath);
553     return abspath;
554 }
555 
556 /* Return true if the specified path is just a file basename without any
557  * relative or absolute path. This function just checks that no / or \
558  * character exists inside the specified path, that's enough in the
559  * environments where Redis runs. */
560 int pathIsBaseName(char *path) {
561     return strchr(path,'/') == NULL && strchr(path,'\\') == NULL;
562 }
563 
564 #ifdef REDIS_TEST
565 #include <assert.h>
566 
567 static void test_string2ll(void) {
568     char buf[32];
569     long long v;
570 
571     /* May not start with +. */
572     strcpy(buf,"+1");
573     assert(string2ll(buf,strlen(buf),&v) == 0);
574 
575     /* Leading space. */
576     strcpy(buf," 1");
577     assert(string2ll(buf,strlen(buf),&v) == 0);
578 
579     /* Trailing space. */
580     strcpy(buf,"1 ");
581     assert(string2ll(buf,strlen(buf),&v) == 0);
582 
583     /* May not start with 0. */
584     strcpy(buf,"01");
585     assert(string2ll(buf,strlen(buf),&v) == 0);
586 
587     strcpy(buf,"-1");
588     assert(string2ll(buf,strlen(buf),&v) == 1);
589     assert(v == -1);
590 
591     strcpy(buf,"0");
592     assert(string2ll(buf,strlen(buf),&v) == 1);
593     assert(v == 0);
594 
595     strcpy(buf,"1");
596     assert(string2ll(buf,strlen(buf),&v) == 1);
597     assert(v == 1);
598 
599     strcpy(buf,"99");
600     assert(string2ll(buf,strlen(buf),&v) == 1);
601     assert(v == 99);
602 
603     strcpy(buf,"-99");
604     assert(string2ll(buf,strlen(buf),&v) == 1);
605     assert(v == -99);
606 
607     strcpy(buf,"-9223372036854775808");
608     assert(string2ll(buf,strlen(buf),&v) == 1);
609     assert(v == LLONG_MIN);
610 
611     strcpy(buf,"-9223372036854775809"); /* overflow */
612     assert(string2ll(buf,strlen(buf),&v) == 0);
613 
614     strcpy(buf,"9223372036854775807");
615     assert(string2ll(buf,strlen(buf),&v) == 1);
616     assert(v == LLONG_MAX);
617 
618     strcpy(buf,"9223372036854775808"); /* overflow */
619     assert(string2ll(buf,strlen(buf),&v) == 0);
620 }
621 
622 static void test_string2l(void) {
623     char buf[32];
624     long v;
625 
626     /* May not start with +. */
627     strcpy(buf,"+1");
628     assert(string2l(buf,strlen(buf),&v) == 0);
629 
630     /* May not start with 0. */
631     strcpy(buf,"01");
632     assert(string2l(buf,strlen(buf),&v) == 0);
633 
634     strcpy(buf,"-1");
635     assert(string2l(buf,strlen(buf),&v) == 1);
636     assert(v == -1);
637 
638     strcpy(buf,"0");
639     assert(string2l(buf,strlen(buf),&v) == 1);
640     assert(v == 0);
641 
642     strcpy(buf,"1");
643     assert(string2l(buf,strlen(buf),&v) == 1);
644     assert(v == 1);
645 
646     strcpy(buf,"99");
647     assert(string2l(buf,strlen(buf),&v) == 1);
648     assert(v == 99);
649 
650     strcpy(buf,"-99");
651     assert(string2l(buf,strlen(buf),&v) == 1);
652     assert(v == -99);
653 
654 #if LONG_MAX != LLONG_MAX
655     strcpy(buf,"-2147483648");
656     assert(string2l(buf,strlen(buf),&v) == 1);
657     assert(v == LONG_MIN);
658 
659     strcpy(buf,"-2147483649"); /* overflow */
660     assert(string2l(buf,strlen(buf),&v) == 0);
661 
662     strcpy(buf,"2147483647");
663     assert(string2l(buf,strlen(buf),&v) == 1);
664     assert(v == LONG_MAX);
665 
666     strcpy(buf,"2147483648"); /* overflow */
667     assert(string2l(buf,strlen(buf),&v) == 0);
668 #endif
669 }
670 
671 static void test_ll2string(void) {
672     char buf[32];
673     long long v;
674     int sz;
675 
676     v = 0;
677     sz = ll2string(buf, sizeof buf, v);
678     assert(sz == 1);
679     assert(!strcmp(buf, "0"));
680 
681     v = -1;
682     sz = ll2string(buf, sizeof buf, v);
683     assert(sz == 2);
684     assert(!strcmp(buf, "-1"));
685 
686     v = 99;
687     sz = ll2string(buf, sizeof buf, v);
688     assert(sz == 2);
689     assert(!strcmp(buf, "99"));
690 
691     v = -99;
692     sz = ll2string(buf, sizeof buf, v);
693     assert(sz == 3);
694     assert(!strcmp(buf, "-99"));
695 
696     v = -2147483648;
697     sz = ll2string(buf, sizeof buf, v);
698     assert(sz == 11);
699     assert(!strcmp(buf, "-2147483648"));
700 
701     v = LLONG_MIN;
702     sz = ll2string(buf, sizeof buf, v);
703     assert(sz == 20);
704     assert(!strcmp(buf, "-9223372036854775808"));
705 
706     v = LLONG_MAX;
707     sz = ll2string(buf, sizeof buf, v);
708     assert(sz == 19);
709     assert(!strcmp(buf, "9223372036854775807"));
710 }
711 
712 #define UNUSED(x) (void)(x)
713 int utilTest(int argc, char **argv) {
714     UNUSED(argc);
715     UNUSED(argv);
716 
717     test_string2ll();
718     test_string2l();
719     test_ll2string();
720     return 0;
721 }
722 #endif
723