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