• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #3532

20 Nov 2024 07:11AM UTC coverage: 60.78% (+0.6%) from 60.213%
#3532

push

travis-ci

web-flow
Merge pull request #28823 from taosdata/fix/3.0/TD-32587

fix:[TD-32587]fix stmt segmentation fault

119943 of 252352 branches covered (47.53%)

Branch coverage included in aggregate %.

1 of 4 new or added lines in 1 file covered. (25.0%)

463 existing lines in 99 files now uncovered.

200682 of 275165 relevant lines covered (72.93%)

15642683.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.02
/source/util/src/tutil.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#define _DEFAULT_SOURCE
17
#include "tutil.h"
18
#include "tlog.h"
19

20
void *tmemmem(const char *haystack, int32_t hlen, const char *needle, int32_t nlen) {
×
21
  const char *limit;
22

23
  if (nlen == 0 || hlen < nlen) {
×
24
    return NULL;
×
25
  }
26

27
  limit = haystack + hlen - nlen + 1;
×
28
  while ((haystack = (char *)memchr(haystack, needle[0], limit - haystack)) != NULL) {
×
29
    if (memcmp(haystack, needle, nlen) == 0) {
×
30
      return (void *)haystack;
×
31
    }
32
    haystack++;
×
33
  }
34
  return NULL;
×
35
}
36

37
int32_t strdequote(char *z) {
27,917,221✔
38
  if (z == NULL) {
27,917,221!
39
    return 0;
×
40
  }
41

42
  int32_t quote = z[0];
27,917,221✔
43
  if (quote != '\'' && quote != '"' && quote != '`') {
27,917,221!
44
    return (int32_t)strlen(z);
27,920,914✔
45
  }
46

UNCOV
47
  int32_t i = 1, j = 0;
×
48

49
  while (z[i] != 0) {
71,738!
50
    if (z[i] == quote) {
89,140✔
51
      if (z[i + 1] == quote) {
13,709!
52
        z[j++] = (char)quote;
×
53
        i++;
×
54
      } else {
55
        z[j++] = 0;
13,709✔
56
        return (j - 1);
13,709✔
57
      }
58
    } else {
59
      z[j++] = z[i];
75,431✔
60
    }
61

62
    i++;
75,431✔
63
  }
64

65
  return j + 1;  // only one quote, do nothing
×
66
}
67

68
size_t strtrim(char *z) {
8,248✔
69
  int32_t i = 0;
8,248✔
70
  int32_t j = 0;
8,248✔
71

72
  int32_t delta = 0;
8,248✔
73
  while (isspace(z[j])) {
8,300✔
74
    ++j;
52✔
75
  }
76

77
  if (z[j] == 0) {
8,248✔
78
    z[0] = 0;
40✔
79
    return 0;
40✔
80
  }
81

82
  delta = j;
8,208✔
83

84
  int32_t stop = 0;
8,208✔
85
  while (z[j] != 0) {
87,171✔
86
    if (isspace(z[j]) && stop == 0) {
78,963✔
87
      stop = j;
385✔
88
    } else if (!isspace(z[j]) && stop != 0) {
78,578✔
89
      stop = 0;
355✔
90
    }
91

92
    z[i++] = z[j++];
78,963✔
93
  }
94

95
  if (stop > 0) {
8,208✔
96
    z[stop - delta] = 0;
30✔
97
    return (stop - delta);
30✔
98
  } else if (j != i) {
8,178✔
99
    z[i] = 0;
18✔
100
  }
101

102
  return i;
8,178✔
103
}
104

105
char **strsplit(char *z, const char *delim, int32_t *num) {
4,962✔
106
  *num = 0;
4,962✔
107
  int32_t size = 4;
4,962✔
108

109
  char **split = taosMemoryMalloc(POINTER_BYTES * size);
4,962✔
110
  if (split == NULL) {
4,962!
111
    return NULL;
×
112
  }
113

114
  for (char *p = strsep(&z, delim); p != NULL; p = strsep(&z, delim)) {
9,924✔
115
    size_t len = strlen(p);
4,962✔
116
    if (len == 0) {
4,962!
117
      continue;
×
118
    }
119

120
    split[(*num)++] = p;
4,962✔
121
    if ((*num) >= size) {
4,962!
122
      size = (size << 1);
×
123
      split = taosMemoryRealloc(split, POINTER_BYTES * size);
×
124
      if (split == NULL) {
×
125
        return NULL;
×
126
      }
127
    }
128
  }
129

130
  return split;
4,962✔
131
}
132

133
char *strnchr(const char *haystack, char needle, int32_t len, bool skipquote) {
13,352,049✔
134
  for (int32_t i = 0; i < len; ++i) {
222,388,031✔
135
    // skip the needle in quote, jump to the end of quoted string
136
    if (skipquote && (haystack[i] == '\'' || haystack[i] == '"')) {
218,351,359!
137
      char quote = haystack[i++];
12,012✔
138
      while (i < len && haystack[i++] != quote)
72,054✔
139
        ;
140
      if (i >= len) {
12,012!
141
        return NULL;
12,012✔
142
      }
143
    }
144

145
    if (haystack[i] == needle) {
218,339,347✔
146
      return (char *)&haystack[i];
9,303,365✔
147
    }
148
  }
149

150
  return NULL;
4,036,672✔
151
}
152

153
TdUcs4 *wcsnchr(const TdUcs4 *haystack, TdUcs4 needle, size_t len) {
12,437✔
154
  for (int32_t i = 0; i < len; ++i) {
33,273✔
155
    if (haystack[i] == needle) {
24,825✔
156
      return (TdUcs4 *)&haystack[i];
3,989✔
157
    }
158
  }
159

160
  return NULL;
8,448✔
161
}
162

163
char *strtolower(char *dst, const char *src) {
20,354,496✔
164
  int32_t esc = 0;
20,354,496✔
165
  char    quote = 0, *p = dst, c;
20,354,496✔
166

167
  for (c = *src++; c; c = *src++) {
680,134,149✔
168
    if (esc) {
659,779,653!
169
      esc = 0;
×
170
    } else if (quote) {
659,779,653✔
171
      if (c == '\\') {
26,901,107!
172
        esc = 1;
×
173
      } else if (c == quote) {
26,901,107✔
174
        quote = 0;
2,653,409✔
175
      }
176
    } else if (c >= 'A' && c <= 'Z') {
632,878,546✔
177
      c -= 'A' - 'a';
9,431,368✔
178
    } else if (c == '\'' || c == '"') {
623,447,178✔
179
      quote = c;
2,653,409✔
180
    }
181
    *p++ = c;
659,779,653✔
182
  }
183

184
  *p = 0;
20,354,496✔
185
  return dst;
20,354,496✔
186
}
187

188
char *strntolower(char *dst, const char *src, int32_t n) {
12,318,919✔
189
  int32_t esc = 0;
12,318,919✔
190
  char    quote = 0, *p = dst, c;
12,318,919✔
191

192
  if (n == 0) {
12,318,919✔
193
    *p = 0;
1,625✔
194
    return dst;
1,625✔
195
  }
196
  for (c = *src++; n-- > 0; c = *src++) {
2,147,483,647✔
197
    if (esc) {
2,147,483,647✔
198
      esc = 0;
5,716✔
199
    } else if (quote) {
2,147,483,647✔
200
      if (c == '\\') {
2,147,483,647✔
201
        esc = 1;
5,716✔
202
      } else if (c == quote) {
2,147,483,647✔
203
        quote = 0;
148,238,494✔
204
      }
205
    } else if (c >= 'A' && c <= 'Z') {
2,147,483,647✔
206
      c -= 'A' - 'a';
198,024,576✔
207
    } else if (c == '\'' || c == '"' || c == '`') {
2,147,483,647!
208
      quote = c;
148,708,578✔
209
    }
210
    *p++ = c;
2,147,483,647✔
211
  }
212

213
  *p = 0;
12,317,294✔
214
  return dst;
12,317,294✔
215
}
216

217
char *strntolower_s(char *dst, const char *src, int32_t n) {
×
218
  char *p = dst, c;
×
219
  if (n == 0) {
×
220
    return NULL;
×
221
  }
222

223
  while (n-- > 0) {
×
224
    c = *src;
×
225
    if (c >= 'A' && c <= 'Z') {
×
226
      c -= 'A' - 'a';
×
227
    }
228
    *p++ = c;
×
229
    src++;
×
230
  }
231

232
  return dst;
×
233
}
234

235
char *paGetToken(char *string, char **token, int32_t *tokenLen) {
31,913,979✔
236
  char quote = 0;
31,913,979✔
237

238
  while (*string != 0) {
54,641,900✔
239
    if (*string == ' ' || *string == '\t') {
52,070,659✔
240
      ++string;
22,727,921✔
241
    } else {
242
      break;
243
    }
244
  }
245

246
  if (*string == '@') {
31,913,979✔
247
    quote = 1;
8,784✔
248
    string++;
8,784✔
249
  }
250

251
  *token = string;
31,913,979✔
252

253
  while (*string != 0) {
127,361,391✔
254
    if (*string == '@' && quote) {
119,186,147✔
255
      //*string = 0;
256
      ++string;
8,784✔
257
      break;
8,784✔
258
    }
259

260
    if (*string == '#' || *string == '\n' || *string == '\r') {
119,177,363!
261
      *string = 0;
389,365✔
262
      break;
389,365✔
263
    }
264

265
    if ((*string == ' ' || *string == '\t') && !quote) {
118,787,998✔
266
      break;
267
    } else {
268
      ++string;
95,447,412✔
269
    }
270
  }
271

272
  *tokenLen = (int32_t)(string - *token);
31,913,979✔
273
  if (quote) {
31,913,979✔
274
    *tokenLen = *tokenLen - 1;
8,784✔
275
  }
276

277
  return string;
31,913,979✔
278
}
279

280
int64_t strnatoi(char *num, int32_t len) {
12,911,290✔
281
  int64_t ret = 0, i, dig, base = 1;
12,911,290✔
282

283
  if (len > (int32_t)strlen(num)) {
12,911,290✔
284
    len = (int32_t)strlen(num);
24✔
285
  }
286

287
  if ((len > 2) && (num[0] == '0') && ((num[1] == 'x') || (num[1] == 'X'))) {
12,911,290!
288
    for (i = len - 1; i >= 2; --i, base *= 16) {
×
289
      if (num[i] >= '0' && num[i] <= '9') {
×
290
        dig = (num[i] - '0');
×
291
      } else if (num[i] >= 'a' && num[i] <= 'f') {
×
292
        dig = num[i] - 'a' + 10;
×
293
      } else if (num[i] >= 'A' && num[i] <= 'F') {
×
294
        dig = num[i] - 'A' + 10;
×
295
      } else {
296
        return 0;
×
297
      }
298
      ret += dig * base;
×
299
    }
300
  } else {
301
    for (i = len - 1; i >= 0; --i, base *= 10) {
39,036,234✔
302
      if (num[i] >= '0' && num[i] <= '9') {
26,124,944!
303
        dig = (num[i] - '0');
26,124,944✔
304
      } else {
305
        return 0;
×
306
      }
307
      ret += dig * base;
26,124,944✔
308
    }
309
  }
310

311
  return ret;
12,911,290✔
312
}
313

314
char *strbetween(char *string, char *begin, char *end) {
×
315
  char *result = NULL;
×
316
  char *_begin = strstr(string, begin);
×
317
  if (_begin != NULL) {
×
318
    char   *_end = strstr(_begin + strlen(begin), end);
×
319
    int32_t size = (int32_t)(_end - _begin);
×
320
    if (_end != NULL && size > 0) {
×
321
      result = (char *)taosMemoryCalloc(1, size);
×
322
      if (!result) {
×
323
        return NULL;
×
324
      }
325
      memcpy(result, _begin + strlen(begin), size - +strlen(begin));
×
326
    }
327
  }
328
  return result;
×
329
}
330

331
int32_t tintToHex(uint64_t val, char hex[]) {
14,814,834✔
332
  const char hexstr[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
14,814,834✔
333

334
  int32_t j = 0, k = 0;
14,814,834✔
335
  if (val == 0) {
14,814,834✔
336
    hex[j++] = hexstr[0];
10,103✔
337
    return j;
10,103✔
338
  }
339

340
  // ignore the initial 0
341
  while ((val & (((uint64_t)0xfL) << ((15 - k) * 4))) == 0) {
102,171,427✔
342
    k += 1;
87,366,696✔
343
  }
344

345
  for (j = 0; k < 16; ++k, ++j) {
164,267,152✔
346
    hex[j] = hexstr[(val & (((uint64_t)0xfL) << ((15 - k) * 4))) >> (15 - k) * 4];
149,462,421✔
347
  }
348

349
  return j;
14,804,731✔
350
}
351

352
int32_t titoa(uint64_t val, size_t radix, char str[]) {
238,252,365✔
353
  if (radix < 2 || radix > 16) {
238,252,365!
354
    return 0;
×
355
  }
356

357
  const char *s = "0123456789abcdef";
238,301,323✔
358
  char        buf[65] = {0};
238,301,323✔
359

360
  int32_t  i = 0;
238,301,323✔
361
  uint64_t v = val;
238,301,323✔
362
  do {
363
    buf[i++] = s[v % radix];
2,147,483,647✔
364
    v /= radix;
2,147,483,647✔
365
  } while (v > 0);
2,147,483,647✔
366

367
  // reverse order
368
  for (int32_t j = 0; j < i; ++j) {
2,147,483,647✔
369
    str[j] = buf[i - j - 1];
2,147,483,647✔
370
  }
371

372
  return i;
238,301,323✔
373
}
374

375
int32_t taosByteArrayToHexStr(char bytes[], int32_t len, char hexstr[]) {
×
376
  int32_t i;
377
  char    hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
×
378

379
  for (i = 0; i < len; i++) {
×
380
    hexstr[i * 2] = hexval[((bytes[i] >> 4u) & 0xF)];
×
381
    hexstr[(i * 2) + 1] = hexval[(bytes[i]) & 0x0F];
×
382
  }
383

384
  return 0;
×
385
}
386

387
int32_t taosHexStrToByteArray(char hexstr[], char bytes[]) {
×
388
  int32_t len, i;
389
  char    ch;
390
  // char *by;
391

392
  len = (int32_t)strlen((char *)hexstr) / 2;
×
393

394
  for (i = 0; i < len; i++) {
×
395
    ch = hexstr[i * 2];
×
396
    if (ch >= '0' && ch <= '9')
×
397
      bytes[i] = (char)(ch - '0');
×
398
    else if (ch >= 'A' && ch <= 'F')
×
399
      bytes[i] = (char)(ch - 'A' + 10);
×
400
    else if (ch >= 'a' && ch <= 'f')
×
401
      bytes[i] = (char)(ch - 'a' + 10);
×
402
    else
403
      return -1;
×
404

405
    ch = hexstr[i * 2 + 1];
×
406
    if (ch >= '0' && ch <= '9')
×
407
      bytes[i] = (char)((bytes[i] << 4) + (ch - '0'));
×
408
    else if (ch >= 'A' && ch <= 'F')
×
409
      bytes[i] = (char)((bytes[i] << 4) + (ch - 'A' + 10));
×
410
    else if (ch >= 'a' && ch <= 'f')
×
411
      bytes[i] = (char)((bytes[i] << 4) + (ch - 'a' + 10));
×
412
    else
413
      return -1;
×
414
  }
415

416
  return 0;
×
417
}
418

419
char *taosIpStr(uint32_t ipInt) {
595✔
420
  static char    ipStrArray[3][30];
421
  static int32_t ipStrIndex = 0;
422

423
  char *ipStr = ipStrArray[(ipStrIndex++) % 3];
595✔
424
  // sprintf(ipStr, "0x%x:%u.%u.%u.%u", ipInt, ipInt & 0xFF, (ipInt >> 8) & 0xFF, (ipInt >> 16) & 0xFF, (uint8_t)(ipInt
425
  // >> 24));
426
  sprintf(ipStr, "%u.%u.%u.%u", ipInt & 0xFF, (ipInt >> 8) & 0xFF, (ipInt >> 16) & 0xFF, (uint8_t)(ipInt >> 24));
595✔
427
  return ipStr;
595✔
428
}
429

430
void taosIp2String(uint32_t ip, char *str) {
89,153✔
431
  sprintf(str, "%u.%u.%u.%u", ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (uint8_t)(ip >> 24));
89,153✔
432
}
89,153✔
433

434
void taosIpPort2String(uint32_t ip, uint16_t port, char *str) {
×
435
  sprintf(str, "%u.%u.%u.%u:%u", ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (uint8_t)(ip >> 24), port);
×
436
}
×
437

438
size_t tstrncspn(const char *str, size_t size, const char *reject, size_t rsize) {
9,657,549✔
439
  if (rsize == 0 || rsize == 1) {
9,657,549!
440
    char *p = strnchr(str, reject[0], size, false);
×
441
    return (p == NULL) ? size : (p - str);
×
442
  }
443

444
  /* Use multiple small memsets to enable inlining on most targets.  */
445
  unsigned char  table[256];
446
  unsigned char *p = memset(table, 0, 64);
9,657,601✔
447
  memset(p + 64, 0, 64);
9,657,601✔
448
  memset(p + 128, 0, 64);
9,657,601✔
449
  memset(p + 192, 0, 64);
9,657,601✔
450

451
  unsigned char *s = (unsigned char *)reject;
9,657,601✔
452
  int32_t        index = 0;
9,657,601✔
453
  do {
454
    p[s[index++]] = 1;
19,315,719✔
455
  } while (index < rsize);
19,315,719✔
456

457
  s = (unsigned char *)str;
9,657,601✔
458
  int32_t times = size >> 2;
9,657,601✔
459
  if (times == 0) {
9,657,601✔
460
    for (int32_t i = 0; i < size; ++i) {
57,814✔
461
      if (p[s[i]]) {
47,843✔
462
        return i;
26,402✔
463
      }
464
    }
465

466
    return size;
9,971✔
467
  }
468

469
  index = 0;
9,621,228✔
470
  uint32_t c0, c1, c2, c3;
471
  for (int32_t i = 0; i < times; ++i, index += 4) {
9,653,945✔
472
    int32_t j = index;
9,632,906✔
473
    c0 = p[s[j]];
9,632,906✔
474
    c1 = p[s[j + 1]];
9,632,906✔
475
    c2 = p[s[j + 2]];
9,632,906✔
476
    c3 = p[s[j + 3]];
9,632,906✔
477

478
    if ((c0 | c1 | c2 | c3) != 0) {
9,632,906✔
479
      size_t count = i * 4;
9,600,189✔
480
      return (c0 | c1) != 0 ? count - c0 + 1 : count - c2 + 3;
9,600,189✔
481
    }
482
  }
483

484
  int32_t offset = times * 4;
21,039✔
485
  for (int32_t i = offset; i < size; ++i) {
55,444✔
486
    if (p[s[i]]) {
34,844✔
487
      return i;
439✔
488
    }
489
  }
490

491
  return size;
20,600✔
492
}
493

494
size_t twcsncspn(const TdUcs4 *wcs, size_t size, const TdUcs4 *reject, size_t rsize) {
4,263✔
495
  if (rsize == 0 || rsize == 1) {
4,263!
496
    TdUcs4 *p = wcsnchr(wcs, reject[0], size);
×
497
    return (p == NULL) ? size : (p - wcs);
×
498
  }
499

500
  size_t index = 0;
4,263✔
501
  while ((index < size) && (wcsnchr(reject, wcs[index], rsize) == NULL)) {
12,784✔
502
    ++index;
8,521✔
503
  }
504

505
  return index;
4,283✔
506
}
507

508
int32_t parseCfgReal(const char *str, float *out) {
52✔
509
  float val;
510
  char  *endPtr;
511
  errno = 0;
52✔
512
  val = taosStr2Float(str, &endPtr);
52✔
513
  if (str == endPtr || errno == ERANGE || isnan(val)) {
52!
514
    return terrno = TSDB_CODE_INVALID_CFG_VALUE;
2✔
515
  }
516
  while (isspace((unsigned char)*endPtr)) endPtr++;
52✔
517
  if (*endPtr != '\0') {
50✔
518
    return terrno = TSDB_CODE_INVALID_CFG_VALUE;
3✔
519
  }
520
  *out = val;
47✔
521
  return TSDB_CODE_SUCCESS;
47✔
522
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc