quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

ares_str.c (10536B)


      1 /* MIT License
      2  *
      3  * Copyright (c) 1998 Massachusetts Institute of Technology
      4  * Copyright (c) The c-ares project and its contributors
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and associated documentation files (the "Software"), to deal
      8  * in the Software without restriction, including without limitation the rights
      9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10  * copies of the Software, and to permit persons to whom the Software is
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the next
     14  * paragraph) shall be included in all copies or substantial portions of the
     15  * Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  * SOFTWARE.
     24  *
     25  * SPDX-License-Identifier: MIT
     26  */
     27 
     28 #include "ares_private.h"
     29 #include "ares_str.h"
     30 
     31 #ifdef HAVE_STDINT_H
     32 #  include <stdint.h>
     33 #endif
     34 
     35 size_t ares_strnlen(const char *str, size_t maxlen) {
     36   const char *p = NULL;
     37   if (str == NULL) {
     38     return 0;
     39   }
     40 #ifdef HAVE_STRNLEN
     41   (void)p;
     42   return strnlen(str, maxlen);
     43 #else
     44   if ((p = memchr(str, 0, maxlen)) == NULL) {
     45     return maxlen;
     46   } else {
     47     return (size_t)(p - str);
     48   }
     49 #endif /* HAVE_STRNLEN */
     50 }
     51 
     52 size_t ares_strlen(const char *str)
     53 {
     54   if (str == NULL) {
     55     return 0;
     56   }
     57 
     58   return strlen(str);
     59 }
     60 
     61 char *ares_strdup(const char *s1)
     62 {
     63   size_t len;
     64   char  *out;
     65 
     66   if (s1 == NULL) {
     67     return NULL;
     68   }
     69 
     70   len = ares_strlen(s1);
     71 
     72   /* Don't see how this is possible */
     73   if (len == SIZE_MAX) {
     74     return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */
     75   }
     76 
     77   out = ares_malloc(len + 1);
     78   if (out == NULL) {
     79     return NULL;
     80   }
     81 
     82   if (len) {
     83     memcpy(out, s1, len);
     84   }
     85 
     86   out[len] = 0;
     87   return out;
     88 }
     89 
     90 size_t ares_strcpy(char *dest, const char *src, size_t dest_size)
     91 {
     92   size_t len = 0;
     93 
     94   if (dest == NULL || dest_size == 0) {
     95     return 0; /* LCOV_EXCL_LINE: DefensiveCoding */
     96   }
     97 
     98   len = ares_strlen(src);
     99 
    100   if (len >= dest_size) {
    101     len = dest_size - 1;
    102   }
    103 
    104   if (len) {
    105     memcpy(dest, src, len);
    106   }
    107 
    108   dest[len] = 0;
    109   return len;
    110 }
    111 
    112 ares_bool_t ares_str_isnum(const char *str)
    113 {
    114   size_t i;
    115 
    116   if (str == NULL || *str == 0) {
    117     return ARES_FALSE;
    118   }
    119 
    120   for (i = 0; str[i] != 0; i++) {
    121     if (!ares_isdigit(str[i])) {
    122       return ARES_FALSE;
    123     }
    124   }
    125   return ARES_TRUE;
    126 }
    127 
    128 ares_bool_t ares_str_isalnum(const char *str)
    129 {
    130   size_t i;
    131 
    132   if (str == NULL || *str == 0) {
    133     return ARES_FALSE;
    134   }
    135 
    136   for (i = 0; str[i] != 0; i++) {
    137     if (!ares_isdigit(str[i]) && !ares_isalpha(str[i])) {
    138       return ARES_FALSE;
    139     }
    140   }
    141   return ARES_TRUE;
    142 }
    143 
    144 void ares_str_rtrim(char *str)
    145 {
    146   size_t len;
    147   size_t i;
    148 
    149   if (str == NULL) {
    150     return; /* LCOV_EXCL_LINE: DefensiveCoding */
    151   }
    152 
    153   len = ares_strlen(str);
    154   for (i = len; i > 0; i--) {
    155     if (!ares_isspace(str[i - 1])) {
    156       break;
    157     }
    158   }
    159   str[i] = 0;
    160 }
    161 
    162 void ares_str_ltrim(char *str)
    163 {
    164   size_t i;
    165   size_t len;
    166 
    167   if (str == NULL) {
    168     return; /* LCOV_EXCL_LINE: DefensiveCoding */
    169   }
    170 
    171   for (i = 0; str[i] != 0 && ares_isspace(str[i]); i++) {
    172     /* Do nothing */
    173   }
    174 
    175   if (i == 0) {
    176     return;
    177   }
    178 
    179   len = ares_strlen(str);
    180   if (i != len) {
    181     memmove(str, str + i, len - i);
    182   }
    183   str[len - i] = 0;
    184 }
    185 
    186 void ares_str_trim(char *str)
    187 {
    188   ares_str_ltrim(str);
    189   ares_str_rtrim(str);
    190 }
    191 
    192 /* tolower() is locale-specific.  Use a lookup table fast conversion that only
    193  * operates on ASCII */
    194 static const unsigned char ares_tolower_lookup[] = {
    195   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
    196   0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
    197   0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
    198   0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
    199   0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40,
    200   0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
    201   0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
    202   0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
    203   0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74,
    204   0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81,
    205   0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
    206   0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B,
    207   0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
    208   0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
    209   0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2,
    210   0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
    211   0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC,
    212   0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
    213   0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6,
    214   0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
    215 };
    216 
    217 unsigned char ares_tolower(unsigned char c)
    218 {
    219   return ares_tolower_lookup[c];
    220 }
    221 
    222 void ares_str_lower(char *str)
    223 {
    224   size_t i;
    225 
    226   if (str == NULL) {
    227     return;
    228   }
    229 
    230   for (i = 0; str[i] != 0; i++) {
    231     str[i] = (char)ares_tolower((unsigned char)str[i]);
    232   }
    233 }
    234 
    235 unsigned char *ares_memmem(const unsigned char *big, size_t big_len,
    236                            const unsigned char *little, size_t little_len)
    237 {
    238   unsigned char *ptr;
    239 
    240   if (big == NULL || little == NULL || big_len == 0 || little_len == 0) {
    241     return NULL;
    242   }
    243 
    244 #ifdef HAVE_MEMMEM
    245   ptr = memmem(big, big_len, little, little_len);
    246   return ptr;
    247 #else
    248   while (1) {
    249     ptr = memchr(big, little[0], big_len);
    250     if (ptr == NULL) {
    251       break;
    252     }
    253 
    254     big_len -= (size_t)(ptr - big);
    255     big      = ptr;
    256     if (big_len < little_len) {
    257       break;
    258     }
    259 
    260     if (memcmp(big, little, little_len) == 0) {
    261       return ptr;
    262     }
    263 
    264     big++;
    265     big_len--;
    266   }
    267 
    268   return NULL;
    269 #endif
    270 }
    271 
    272 ares_bool_t ares_memeq(const unsigned char *ptr, const unsigned char *val,
    273                        size_t len)
    274 {
    275   return memcmp(ptr, val, len) == 0 ? ARES_TRUE : ARES_FALSE;
    276 }
    277 
    278 ares_bool_t ares_memeq_ci(const unsigned char *ptr, const unsigned char *val,
    279                           size_t len)
    280 {
    281   size_t i;
    282   for (i = 0; i < len; i++) {
    283     if (ares_tolower_lookup[ptr[i]] != ares_tolower_lookup[val[i]]) {
    284       return ARES_FALSE;
    285     }
    286   }
    287   return ARES_TRUE;
    288 }
    289 
    290 ares_bool_t ares_is_hostname(const char *str)
    291 {
    292   size_t i;
    293 
    294   if (str == NULL) {
    295     return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */
    296   }
    297 
    298   for (i = 0; str[i] != 0; i++) {
    299     if (!ares_is_hostnamech(str[i])) {
    300       return ARES_FALSE;
    301     }
    302   }
    303   return ARES_TRUE;
    304 }
    305 
    306 ares_bool_t ares_str_isprint(const char *str, size_t len)
    307 {
    308   size_t i;
    309 
    310   if (str == NULL && len != 0) {
    311     return ARES_FALSE;
    312   }
    313 
    314   for (i = 0; i < len; i++) {
    315     if (!ares_isprint(str[i])) {
    316       return ARES_FALSE;
    317     }
    318   }
    319   return ARES_TRUE;
    320 }
    321 
    322 int ares_strcmp(const char *a, const char *b)
    323 {
    324   if (a == NULL && b == NULL) {
    325     return 0;
    326   }
    327 
    328   if (a != NULL && b == NULL) {
    329     if (*a == 0) {
    330       return 0;
    331     }
    332     return 1;
    333   }
    334 
    335   if (a == NULL && b != NULL) {
    336     if (*b == 0) {
    337       return 0;
    338     }
    339     return -1;
    340   }
    341 
    342   return strcmp(a, b);
    343 }
    344 
    345 int ares_strncmp(const char *a, const char *b, size_t n)
    346 {
    347   if (n == 0) {
    348     return 0;
    349   }
    350 
    351   if (a == NULL && b == NULL) {
    352     return 0;
    353   }
    354 
    355   if (a != NULL && b == NULL) {
    356     if (*a == 0) {
    357       return 0;
    358     }
    359     return 1;
    360   }
    361 
    362   if (a == NULL && b != NULL) {
    363     if (*b == 0) {
    364       return 0;
    365     }
    366     return -1;
    367   }
    368 
    369   return strncmp(a, b, n);
    370 }
    371 
    372 int ares_strcasecmp(const char *a, const char *b)
    373 {
    374   if (a == NULL && b == NULL) {
    375     return 0;
    376   }
    377 
    378   if (a != NULL && b == NULL) {
    379     if (*a == 0) {
    380       return 0;
    381     }
    382     return 1;
    383   }
    384 
    385   if (a == NULL && b != NULL) {
    386     if (*b == 0) {
    387       return 0;
    388     }
    389     return -1;
    390   }
    391 
    392 #if defined(HAVE_STRCASECMP)
    393   return strcasecmp(a, b);
    394 #elif defined(HAVE_STRCMPI)
    395   return strcmpi(a, b);
    396 #elif defined(HAVE_STRICMP)
    397   return stricmp(a, b);
    398 #else
    399   {
    400     size_t i;
    401 
    402     for (i = 0; i < (size_t)-1; i++) {
    403       int c1 = ares_tolower(a[i]);
    404       int c2 = ares_tolower(b[i]);
    405       if (c1 != c2) {
    406         return c1 - c2;
    407       }
    408       if (!c1) {
    409         break;
    410       }
    411     }
    412   }
    413   return 0;
    414 #endif
    415 }
    416 
    417 int ares_strncasecmp(const char *a, const char *b, size_t n)
    418 {
    419   if (n == 0) {
    420     return 0;
    421   }
    422 
    423   if (a == NULL && b == NULL) {
    424     return 0;
    425   }
    426 
    427   if (a != NULL && b == NULL) {
    428     if (*a == 0) {
    429       return 0;
    430     }
    431     return 1;
    432   }
    433 
    434   if (a == NULL && b != NULL) {
    435     if (*b == 0) {
    436       return 0;
    437     }
    438     return -1;
    439   }
    440 
    441 #if defined(HAVE_STRNCASECMP)
    442   return strncasecmp(a, b, n);
    443 #elif defined(HAVE_STRNCMPI)
    444   return strncmpi(a, b, n);
    445 #elif defined(HAVE_STRNICMP)
    446   return strnicmp(a, b, n);
    447 #else
    448   {
    449     size_t i;
    450 
    451     for (i = 0; i < n; i++) {
    452       int c1 = ares_tolower(a[i]);
    453       int c2 = ares_tolower(b[i]);
    454       if (c1 != c2) {
    455         return c1 - c2;
    456       }
    457       if (!c1) {
    458         break;
    459       }
    460     }
    461   }
    462   return 0;
    463 #endif
    464 }
    465 
    466 ares_bool_t ares_strcaseeq(const char *a, const char *b)
    467 {
    468   return ares_strcasecmp(a, b) == 0 ? ARES_TRUE : ARES_FALSE;
    469 }
    470 
    471 ares_bool_t ares_strcaseeq_max(const char *a, const char *b, size_t n)
    472 {
    473   return ares_strncasecmp(a, b, n) == 0 ? ARES_TRUE : ARES_FALSE;
    474 }
    475 
    476 ares_bool_t ares_streq(const char *a, const char *b)
    477 {
    478   return ares_strcmp(a, b) == 0 ? ARES_TRUE : ARES_FALSE;
    479 }
    480 
    481 ares_bool_t ares_streq_max(const char *a, const char *b, size_t n)
    482 {
    483   return ares_strncmp(a, b, n) == 0 ? ARES_TRUE : ARES_FALSE;
    484 }
    485 
    486 void ares_free_array(void *arrp, size_t nmembers, void (*freefunc)(void *))
    487 {
    488   size_t i;
    489   void **arr = arrp;
    490 
    491   if (arr == NULL) {
    492     return;
    493   }
    494 
    495   if (freefunc != NULL) {
    496     if (nmembers == SIZE_MAX) {
    497       for (i = 0; arr[i] != NULL; i++) {
    498         freefunc(arr[i]);
    499       }
    500     } else {
    501       for (i = 0; i < nmembers; i++) {
    502         freefunc(arr[i]);
    503       }
    504     }
    505   }
    506 
    507   ares_free(arr);
    508 }