Coverage Report

Created: 2024-04-23 06:32

/src/testdir/build/lua-master/source/lstrlib.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
** $Id: lstrlib.c $
3
** Standard library for string operations and pattern-matching
4
** See Copyright Notice in lua.h
5
*/
6
7
#define lstrlib_c
8
#define LUA_LIB
9
10
#include "lprefix.h"
11
12
13
#include <ctype.h>
14
#include <float.h>
15
#include <limits.h>
16
#include <locale.h>
17
#include <math.h>
18
#include <stddef.h>
19
#include <stdio.h>
20
#include <stdlib.h>
21
#include <string.h>
22
23
#include "lua.h"
24
25
#include "lauxlib.h"
26
#include "lualib.h"
27
28
29
/*
30
** maximum number of captures that a pattern can do during
31
** pattern-matching. This limit is arbitrary, but must fit in
32
** an unsigned char.
33
*/
34
#if !defined(LUA_MAXCAPTURES)
35
83.2k
#define LUA_MAXCAPTURES   32
36
#endif
37
38
39
/* macro to 'unsign' a character */
40
86.1M
#define uchar(c)  ((unsigned char)(c))
41
42
43
/*
44
** Some sizes are better limited to fit in 'int', but must also fit in
45
** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.)
46
*/
47
0
#define MAX_SIZET ((size_t)(~(size_t)0))
48
49
#define MAXSIZE  \
50
267k
  (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX))
51
52
53
54
55
2
static int str_len (lua_State *L) {
56
2
  size_t l;
57
2
  luaL_checklstring(L, 1, &l);
58
2
  lua_pushinteger(L, (lua_Integer)l);
59
2
  return 1;
60
2
}
61
62
63
/*
64
** translate a relative initial string position
65
** (negative means back from end): clip result to [1, inf).
66
** The length of any string in Lua must fit in a lua_Integer,
67
** so there are no overflows in the casts.
68
** The inverted comparison avoids a possible overflow
69
** computing '-pos'.
70
*/
71
206k
static size_t posrelatI (lua_Integer pos, size_t len) {
72
206k
  if (pos > 0)
73
199k
    return (size_t)pos;
74
7.00k
  else if (pos == 0)
75
3.11k
    return 1;
76
3.88k
  else if (pos < -(lua_Integer)len)  /* inverted comparison */
77
3.27k
    return 1;  /* clip to 1 */
78
611
  else return len + (size_t)pos + 1;
79
206k
}
80
81
82
/*
83
** Gets an optional ending string position from argument 'arg',
84
** with default value 'def'.
85
** Negative means back from end: clip result to [0, len]
86
*/
87
static size_t getendpos (lua_State *L, int arg, lua_Integer def,
88
7.72k
                         size_t len) {
89
7.72k
  lua_Integer pos = luaL_optinteger(L, arg, def);
90
7.72k
  if (pos > (lua_Integer)len)
91
694
    return len;
92
7.02k
  else if (pos >= 0)
93
132
    return (size_t)pos;
94
6.89k
  else if (pos < -(lua_Integer)len)
95
5.94k
    return 0;
96
954
  else return len + (size_t)pos + 1;
97
7.72k
}
98
99
100
6.20k
static int str_sub (lua_State *L) {
101
6.20k
  size_t l;
102
6.20k
  const char *s = luaL_checklstring(L, 1, &l);
103
6.20k
  size_t start = posrelatI(luaL_checkinteger(L, 2), l);
104
6.20k
  size_t end = getendpos(L, 3, -1, l);
105
6.20k
  if (start <= end)
106
951
    lua_pushlstring(L, s + start - 1, (end - start) + 1);
107
5.25k
  else lua_pushliteral(L, "");
108
6.20k
  return 1;
109
6.20k
}
110
111
112
0
static int str_reverse (lua_State *L) {
113
0
  size_t l, i;
114
0
  luaL_Buffer b;
115
0
  const char *s = luaL_checklstring(L, 1, &l);
116
0
  char *p = luaL_buffinitsize(L, &b, l);
117
0
  for (i = 0; i < l; i++)
118
0
    p[i] = s[l - i - 1];
119
0
  luaL_pushresultsize(&b, l);
120
0
  return 1;
121
0
}
122
123
124
50
static int str_lower (lua_State *L) {
125
50
  size_t l;
126
50
  size_t i;
127
50
  luaL_Buffer b;
128
50
  const char *s = luaL_checklstring(L, 1, &l);
129
50
  char *p = luaL_buffinitsize(L, &b, l);
130
153
  for (i=0; i<l; i++)
131
103
    p[i] = tolower(uchar(s[i]));
132
50
  luaL_pushresultsize(&b, l);
133
50
  return 1;
134
50
}
135
136
137
0
static int str_upper (lua_State *L) {
138
0
  size_t l;
139
0
  size_t i;
140
0
  luaL_Buffer b;
141
0
  const char *s = luaL_checklstring(L, 1, &l);
142
0
  char *p = luaL_buffinitsize(L, &b, l);
143
0
  for (i=0; i<l; i++)
144
0
    p[i] = toupper(uchar(s[i]));
145
0
  luaL_pushresultsize(&b, l);
146
0
  return 1;
147
0
}
148
149
150
9.17k
static int str_rep (lua_State *L) {
151
9.17k
  size_t l, lsep;
152
9.17k
  const char *s = luaL_checklstring(L, 1, &l);
153
9.17k
  lua_Integer n = luaL_checkinteger(L, 2);
154
9.17k
  const char *sep = luaL_optlstring(L, 3, "", &lsep);
155
9.17k
  if (n <= 0)
156
218
    lua_pushliteral(L, "");
157
8.96k
  else if (l_unlikely(l + lsep < l || l + lsep > MAXSIZE / n))
158
1
    return luaL_error(L, "resulting string too large");
159
8.95k
  else {
160
8.95k
    size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep;
161
8.95k
    luaL_Buffer b;
162
8.95k
    char *p = luaL_buffinitsize(L, &b, totallen);
163
8.73M
    while (n-- > 1) {  /* first n-1 copies (followed by separator) */
164
8.72M
      memcpy(p, s, l * sizeof(char)); p += l;
165
8.72M
      if (lsep > 0) {  /* empty 'memcpy' is not that cheap */
166
0
        memcpy(p, sep, lsep * sizeof(char));
167
0
        p += lsep;
168
0
      }
169
8.72M
    }
170
8.95k
    memcpy(p, s, l * sizeof(char));  /* last copy (not followed by separator) */
171
8.95k
    luaL_pushresultsize(&b, totallen);
172
8.95k
  }
173
9.17k
  return 1;
174
9.17k
}
175
176
177
8.53k
static int str_byte (lua_State *L) {
178
8.53k
  size_t l;
179
8.53k
  const char *s = luaL_checklstring(L, 1, &l);
180
8.53k
  lua_Integer pi = luaL_optinteger(L, 2, 1);
181
8.53k
  size_t posi = posrelatI(pi, l);
182
8.53k
  size_t pose = getendpos(L, 3, pi, l);
183
8.53k
  int n, i;
184
8.53k
  if (posi > pose) return 0;  /* empty interval; return no values */
185
7.01k
  if (l_unlikely(pose - posi >= (size_t)INT_MAX))  /* arithmetic overflow? */
186
0
    return luaL_error(L, "string slice too long");
187
7.01k
  n = (int)(pose -  posi) + 1;
188
7.01k
  luaL_checkstack(L, n, "string slice too long");
189
7.02k
  for (i=0; i<n; i++)
190
7
    lua_pushinteger(L, uchar(s[posi+i-1]));
191
7.01k
  return n;
192
7.01k
}
193
194
195
4
static int str_char (lua_State *L) {
196
4
  int n = lua_gettop(L);  /* number of arguments */
197
4
  int i;
198
4
  luaL_Buffer b;
199
4
  char *p = luaL_buffinitsize(L, &b, n);
200
8
  for (i=1; i<=n; i++) {
201
4
    lua_Unsigned c = (lua_Unsigned)luaL_checkinteger(L, i);
202
4
    luaL_argcheck(L, c <= (lua_Unsigned)UCHAR_MAX, i, "value out of range");
203
4
    p[i - 1] = uchar(c);
204
4
  }
205
4
  luaL_pushresultsize(&b, n);
206
4
  return 1;
207
4
}
208
209
210
/*
211
** Buffer to store the result of 'string.dump'. It must be initialized
212
** after the call to 'lua_dump', to ensure that the function is on the
213
** top of the stack when 'lua_dump' is called. ('luaL_buffinit' might
214
** push stuff.)
215
*/
216
struct str_Writer {
217
  int init;  /* true iff buffer has been initialized */
218
  luaL_Buffer B;
219
};
220
221
222
0
static int writer (lua_State *L, const void *b, size_t size, void *ud) {
223
0
  struct str_Writer *state = (struct str_Writer *)ud;
224
0
  if (!state->init) {
225
0
    state->init = 1;
226
0
    luaL_buffinit(L, &state->B);
227
0
  }
228
0
  if (b == NULL) {  /* finishing dump? */
229
0
    luaL_pushresult(&state->B);  /* push result */
230
0
    lua_replace(L, 1);  /* move it to reserved slot */
231
0
  }
232
0
  else
233
0
    luaL_addlstring(&state->B, (const char *)b, size);
234
0
  return 0;
235
0
}
236
237
238
0
static int str_dump (lua_State *L) {
239
0
  struct str_Writer state;
240
0
  int strip = lua_toboolean(L, 2);
241
0
  luaL_argcheck(L, lua_type(L, 1) == LUA_TFUNCTION && !lua_iscfunction(L, 1),
242
0
                   1, "Lua function expected");
243
  /* ensure function is on the top of the stack and vacate slot 1 */
244
0
  lua_pushvalue(L, 1);
245
0
  state.init = 0;
246
0
  lua_dump(L, writer, &state, strip);
247
0
  lua_settop(L, 1);  /* leave final result on top */
248
0
  return 1;
249
0
}
250
251
252
253
/*
254
** {======================================================
255
** METAMETHODS
256
** =======================================================
257
*/
258
259
#if defined(LUA_NOCVTS2N) /* { */
260
261
/* no coercion from strings to numbers */
262
263
static const luaL_Reg stringmetamethods[] = {
264
  {"__index", NULL},  /* placeholder */
265
  {NULL, NULL}
266
};
267
268
#else   /* }{ */
269
270
550k
static int tonum (lua_State *L, int arg) {
271
550k
  if (lua_type(L, arg) == LUA_TNUMBER) {  /* already a number? */
272
221k
    lua_pushvalue(L, arg);
273
221k
    return 1;
274
221k
  }
275
328k
  else {  /* check whether it is a numerical string */
276
328k
    size_t len;
277
328k
    const char *s = lua_tolstring(L, arg, &len);
278
328k
    return (s != NULL && lua_stringtonumber(L, s) == len + 1);
279
328k
  }
280
550k
}
281
282
283
34.8k
static void trymt (lua_State *L, const char *mtname) {
284
34.8k
  lua_settop(L, 2);  /* back to the original arguments */
285
34.8k
  if (l_unlikely(lua_type(L, 2) == LUA_TSTRING ||
286
34.8k
                 !luaL_getmetafield(L, 2, mtname)))
287
34.8k
    luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2,
288
34.8k
                  luaL_typename(L, -2), luaL_typename(L, -1));
289
34.8k
  lua_insert(L, -3);  /* put metamethod before arguments */
290
34.8k
  lua_call(L, 2, 1);  /* call metamethod */
291
34.8k
}
292
293
294
276k
static int arith (lua_State *L, int op, const char *mtname) {
295
276k
  if (tonum(L, 1) && tonum(L, 2))
296
241k
    lua_arith(L, op);  /* result will be on the top */
297
34.8k
  else
298
34.8k
    trymt(L, mtname);
299
276k
  return 1;
300
276k
}
301
302
303
1.80k
static int arith_add (lua_State *L) {
304
1.80k
  return arith(L, LUA_OPADD, "__add");
305
1.80k
}
306
307
84.0k
static int arith_sub (lua_State *L) {
308
84.0k
  return arith(L, LUA_OPSUB, "__sub");
309
84.0k
}
310
311
36.8k
static int arith_mul (lua_State *L) {
312
36.8k
  return arith(L, LUA_OPMUL, "__mul");
313
36.8k
}
314
315
31.9k
static int arith_mod (lua_State *L) {
316
31.9k
  return arith(L, LUA_OPMOD, "__mod");
317
31.9k
}
318
319
61.0k
static int arith_pow (lua_State *L) {
320
61.0k
  return arith(L, LUA_OPPOW, "__pow");
321
61.0k
}
322
323
615
static int arith_div (lua_State *L) {
324
615
  return arith(L, LUA_OPDIV, "__div");
325
615
}
326
327
39.3k
static int arith_idiv (lua_State *L) {
328
39.3k
  return arith(L, LUA_OPIDIV, "__idiv");
329
39.3k
}
330
331
20.8k
static int arith_unm (lua_State *L) {
332
20.8k
  return arith(L, LUA_OPUNM, "__unm");
333
20.8k
}
334
335
336
static const luaL_Reg stringmetamethods[] = {
337
  {"__add", arith_add},
338
  {"__sub", arith_sub},
339
  {"__mul", arith_mul},
340
  {"__mod", arith_mod},
341
  {"__pow", arith_pow},
342
  {"__div", arith_div},
343
  {"__idiv", arith_idiv},
344
  {"__unm", arith_unm},
345
  {"__index", NULL},  /* placeholder */
346
  {NULL, NULL}
347
};
348
349
#endif    /* } */
350
351
/* }====================================================== */
352
353
/*
354
** {======================================================
355
** PATTERN MATCHING
356
** =======================================================
357
*/
358
359
360
84.3M
#define CAP_UNFINISHED  (-1)
361
33.8k
#define CAP_POSITION  (-2)
362
363
364
typedef struct MatchState {
365
  const char *src_init;  /* init of source string */
366
  const char *src_end;  /* end ('\0') of source string */
367
  const char *p_end;  /* end ('\0') of pattern */
368
  lua_State *L;
369
  int matchdepth;  /* control for recursive depth (to avoid C stack overflow) */
370
  unsigned char level;  /* total number of captures (finished or unfinished) */
371
  struct {
372
    const char *init;
373
    ptrdiff_t len;
374
  } capture[LUA_MAXCAPTURES];
375
} MatchState;
376
377
378
/* recursive function */
379
static const char *match (MatchState *ms, const char *s, const char *p);
380
381
382
/* maximum recursion depth for 'match' */
383
#if !defined(MAXCCALLS)
384
80.7k
#define MAXCCALLS 200
385
#endif
386
387
388
56.8M
#define L_ESC   '%'
389
1.62M
#define SPECIALS  "^$*+?.([%-"
390
391
392
27.3M
static int check_capture (MatchState *ms, int l) {
393
27.3M
  l -= '1';
394
27.3M
  if (l_unlikely(l < 0 || l >= ms->level ||
395
27.3M
                 ms->capture[l].len == CAP_UNFINISHED))
396
130
    return luaL_error(ms->L, "invalid capture index %%%d", l + 1);
397
27.3M
  return l;
398
27.3M
}
399
400
401
27.7M
static int capture_to_close (MatchState *ms) {
402
27.7M
  int level = ms->level;
403
56.5M
  for (level--; level>=0; level--)
404
56.5M
    if (ms->capture[level].len == CAP_UNFINISHED) return level;
405
87
  return luaL_error(ms->L, "invalid pattern capture");
406
27.7M
}
407
408
409
14.3M
static const char *classend (MatchState *ms, const char *p) {
410
14.3M
  switch (*p++) {
411
259k
    case L_ESC: {
412
259k
      if (l_unlikely(p == ms->p_end))
413
23
        luaL_error(ms->L, "malformed pattern (ends with '%%')");
414
259k
      return p+1;
415
0
    }
416
68.2k
    case '[': {
417
68.2k
      if (*p == '^') p++;
418
5.84M
      do {  /* look for a ']' */
419
5.84M
        if (l_unlikely(p == ms->p_end))
420
15.7k
          luaL_error(ms->L, "malformed pattern (missing ']')");
421
5.84M
        if (*(p++) == L_ESC && p < ms->p_end)
422
71.6k
          p++;  /* skip escapes (e.g. '%]') */
423
5.84M
      } while (*p != ']');
424
68.2k
      return p+1;
425
0
    }
426
13.9M
    default: {
427
13.9M
      return p;
428
0
    }
429
14.3M
  }
430
14.3M
}
431
432
433
354k
static int match_class (int c, int cl) {
434
354k
  int res;
435
354k
  switch (tolower(cl)) {
436
0
    case 'a' : res = isalpha(c); break;
437
1
    case 'c' : res = iscntrl(c); break;
438
0
    case 'd' : res = isdigit(c); break;
439
64
    case 'g' : res = isgraph(c); break;
440
41
    case 'l' : res = islower(c); break;
441
0
    case 'p' : res = ispunct(c); break;
442
11
    case 's' : res = isspace(c); break;
443
0
    case 'u' : res = isupper(c); break;
444
0
    case 'w' : res = isalnum(c); break;
445
50
    case 'x' : res = isxdigit(c); break;
446
19
    case 'z' : res = (c == 0); break;  /* deprecated option */
447
354k
    default: return (cl == c);
448
354k
  }
449
186
  return (islower(cl) ? res : !res);
450
354k
}
451
452
453
115k
static int matchbracketclass (int c, const char *p, const char *ec) {
454
115k
  int sig = 1;
455
115k
  if (*(p+1) == '^') {
456
50
    sig = 0;
457
50
    p++;  /* skip the '^' */
458
50
  }
459
2.04M
  while (++p < ec) {
460
1.97M
    if (*p == L_ESC) {
461
97.0k
      p++;
462
97.0k
      if (match_class(c, uchar(*p)))
463
1.18k
        return sig;
464
97.0k
    }
465
1.88M
    else if ((*(p+1) == '-') && (p+2 < ec)) {
466
0
      p+=2;
467
0
      if (uchar(*(p-2)) <= c && c <= uchar(*p))
468
0
        return sig;
469
0
    }
470
1.88M
    else if (uchar(*p) == c) return sig;
471
1.97M
  }
472
61.5k
  return !sig;
473
115k
}
474
475
476
static int singlematch (MatchState *ms, const char *s, const char *p,
477
43.0M
                        const char *ep) {
478
43.0M
  if (s >= ms->src_end)
479
744k
    return 0;
480
42.2M
  else {
481
42.2M
    int c = uchar(*s);
482
42.2M
    switch (*p) {
483
27.7M
      case '.': return 1;  /* matches any char */
484
257k
      case L_ESC: return match_class(c, uchar(*(p+1)));
485
49.5k
      case '[': return matchbracketclass(c, p, ep-1);
486
14.2M
      default:  return (uchar(*p) == c);
487
42.2M
    }
488
42.2M
  }
489
43.0M
}
490
491
492
static const char *matchbalance (MatchState *ms, const char *s,
493
181k
                                   const char *p) {
494
181k
  if (l_unlikely(p >= ms->p_end - 1))
495
0
    luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')");
496
181k
  if (*s != *p) return NULL;
497
8.53k
  else {
498
8.53k
    int b = *p;
499
8.53k
    int e = *(p+1);
500
8.53k
    int cont = 1;
501
573k
    while (++s < ms->src_end) {
502
566k
      if (*s == e) {
503
21.1k
        if (--cont == 0) return s+1;
504
21.1k
      }
505
545k
      else if (*s == b) cont++;
506
566k
    }
507
8.53k
  }
508
7.15k
  return NULL;  /* string ends out of balance */
509
181k
}
510
511
512
static const char *max_expand (MatchState *ms, const char *s,
513
335k
                                 const char *p, const char *ep) {
514
335k
  ptrdiff_t i = 0;  /* counts maximum expand for item */
515
966k
  while (singlematch(ms, s + i, p, ep))
516
630k
    i++;
517
  /* keeps trying to match with the maximum repetitions */
518
1.27M
  while (i>=0) {
519
956k
    const char *res = match(ms, (s+i), ep+1);
520
956k
    if (res) return res;
521
938k
    i--;  /* else didn't match; reduce 1 repetition to try again */
522
938k
  }
523
317k
  return NULL;
524
335k
}
525
526
527
static const char *min_expand (MatchState *ms, const char *s,
528
21.7k
                                 const char *p, const char *ep) {
529
27.8M
  for (;;) {
530
27.8M
    const char *res = match(ms, s, ep+1);
531
27.8M
    if (res != NULL)
532
108
      return res;
533
27.8M
    else if (singlematch(ms, s, p, ep))
534
27.7M
      s++;  /* try with one more repetition */
535
21.6k
    else return NULL;
536
27.8M
  }
537
21.7k
}
538
539
540
static const char *start_capture (MatchState *ms, const char *s,
541
83.2k
                                    const char *p, int what) {
542
83.2k
  const char *res;
543
83.2k
  int level = ms->level;
544
83.2k
  if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
545
83.2k
  ms->capture[level].init = s;
546
83.2k
  ms->capture[level].len = what;
547
83.2k
  ms->level = level+1;
548
83.2k
  if ((res=match(ms, s, p)) == NULL)  /* match failed? */
549
82.7k
    ms->level--;  /* undo capture */
550
83.2k
  return res;
551
83.2k
}
552
553
554
static const char *end_capture (MatchState *ms, const char *s,
555
27.7M
                                  const char *p) {
556
27.7M
  int l = capture_to_close(ms);
557
27.7M
  const char *res;
558
27.7M
  ms->capture[l].len = s - ms->capture[l].init;  /* close capture */
559
27.7M
  if ((res = match(ms, s, p)) == NULL)  /* match failed? */
560
27.7M
    ms->capture[l].len = CAP_UNFINISHED;  /* undo capture */
561
27.7M
  return res;
562
27.7M
}
563
564
565
27.3M
static const char *match_capture (MatchState *ms, const char *s, int l) {
566
27.3M
  size_t len;
567
27.3M
  l = check_capture(ms, l);
568
27.3M
  len = ms->capture[l].len;
569
27.3M
  if ((size_t)(ms->src_end-s) >= len &&
570
27.3M
      memcmp(ms->capture[l].init, s, len) == 0)
571
89.2k
    return s+len;
572
27.2M
  else return NULL;
573
27.3M
}
574
575
576
63.1M
static const char *match (MatchState *ms, const char *s, const char *p) {
577
63.1M
  if (l_unlikely(ms->matchdepth-- == 0))
578
0
    luaL_error(ms->L, "pattern too complex");
579
69.7M
  init: /* using goto to optimize tail recursion */
580
69.7M
  if (p != ms->p_end) {  /* end of pattern? */
581
69.7M
    switch (*p) {
582
83.2k
      case '(': {  /* start capture */
583
83.2k
        if (*(p + 1) == ')')  /* position capture? */
584
33.0k
          s = start_capture(ms, s, p + 2, CAP_POSITION);
585
50.1k
        else
586
50.1k
          s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
587
83.2k
        break;
588
0
      }
589
27.7M
      case ')': {  /* end capture */
590
27.7M
        s = end_capture(ms, s, p + 1);
591
27.7M
        break;
592
0
      }
593
44.0k
      case '$': {
594
44.0k
        if ((p + 1) != ms->p_end)  /* is the '$' the last char in pattern? */
595
88
          goto dflt;  /* no; go to default */
596
43.9k
        s = (s == ms->src_end) ? s : NULL;  /* check end of string */
597
43.9k
        break;
598
44.0k
      }
599
27.8M
      case L_ESC: {  /* escaped sequences not in the format class[*+?-]? */
600
27.8M
        switch (*(p + 1)) {
601
181k
          case 'b': {  /* balanced string? */
602
181k
            s = matchbalance(ms, s, p + 2);
603
181k
            if (s != NULL) {
604
1.37k
              p += 4; goto init;  /* return match(ms, s, p + 4); */
605
1.37k
            }  /* else fail (s == NULL) */
606
180k
            break;
607
181k
          }
608
180k
          case 'f': {  /* frontier? */
609
57.7k
            const char *ep; char previous;
610
57.7k
            p += 2;
611
57.7k
            if (l_unlikely(*p != '['))
612
2.78k
              luaL_error(ms->L, "missing '[' after '%%f' in pattern");
613
57.7k
            ep = classend(ms, p);  /* points to what is next */
614
57.7k
            previous = (s == ms->src_init) ? '\0' : *(s - 1);
615
57.7k
            if (!matchbracketclass(uchar(previous), p, ep - 1) &&
616
57.7k
               matchbracketclass(uchar(*s), p, ep - 1)) {
617
5.05k
              p = ep; goto init;  /* return match(ms, s, ep); */
618
5.05k
            }
619
52.7k
            s = NULL;  /* match failed */
620
52.7k
            break;
621
57.7k
          }
622
27.3M
          case '0': case '1': case '2': case '3':
623
27.3M
          case '4': case '5': case '6': case '7':
624
27.3M
          case '8': case '9': {  /* capture results (%0-%9)? */
625
27.3M
            s = match_capture(ms, s, uchar(*(p + 1)));
626
27.3M
            if (s != NULL) {
627
89.2k
              p += 2; goto init;  /* return match(ms, s, p + 2) */
628
89.2k
            }
629
27.2M
            break;
630
27.3M
          }
631
27.2M
          default: goto dflt;
632
27.8M
        }
633
27.4M
        break;
634
27.8M
      }
635
27.4M
      default: dflt: {  /* pattern class plus optional suffix */
636
14.2M
        const char *ep = classend(ms, p);  /* points to optional suffix */
637
        /* does not match at least once? */
638
14.2M
        if (!singlematch(ms, s, p, ep)) {
639
11.5M
          if (*ep == '*' || *ep == '?' || *ep == '-') {  /* accept empty? */
640
4.11M
            p = ep + 1; goto init;  /* return match(ms, s, ep + 1); */
641
4.11M
          }
642
7.42M
          else  /* '+' or no suffix */
643
7.42M
            s = NULL;  /* fail */
644
11.5M
        }
645
2.71M
        else {  /* matched once */
646
2.71M
          switch (*ep) {  /* handle optional suffix */
647
365k
            case '?': {  /* optional */
648
365k
              const char *res;
649
365k
              if ((res = match(ms, s + 1, ep + 1)) != NULL)
650
166
                s = res;
651
364k
              else {
652
364k
                p = ep + 1; goto init;  /* else return match(ms, s, ep + 1); */
653
364k
              }
654
166
              break;
655
365k
            }
656
166
            case '+':  /* 1 or more repetitions */
657
0
              s++;  /* 1 match already done */
658
              /* FALLTHROUGH */
659
335k
            case '*':  /* 0 or more repetitions */
660
335k
              s = max_expand(ms, s, p, ep);
661
335k
              break;
662
21.7k
            case '-':  /* 0 or more repetitions (minimum) */
663
21.7k
              s = min_expand(ms, s, p, ep);
664
21.7k
              break;
665
1.99M
            default:  /* no suffix */
666
1.99M
              s++; p = ep; goto init;  /* return match(ms, s + 1, ep); */
667
2.71M
          }
668
2.71M
        }
669
7.77M
        break;
670
14.2M
      }
671
69.7M
    }
672
69.7M
  }
673
63.1M
  ms->matchdepth++;
674
63.1M
  return s;
675
69.7M
}
676
677
678
679
static const char *lmemfind (const char *s1, size_t l1,
680
112k
                               const char *s2, size_t l2) {
681
112k
  if (l2 == 0) return s1;  /* empty strings are everywhere */
682
97.9k
  else if (l2 > l1) return NULL;  /* avoids a negative 'l1' */
683
78.7k
  else {
684
78.7k
    const char *init;  /* to search for a '*s2' inside 's1' */
685
78.7k
    l2--;  /* 1st char will be checked by 'memchr' */
686
78.7k
    l1 = l1-l2;  /* 's2' cannot be found after that */
687
369k
    while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
688
318k
      init++;   /* 1st char is already checked */
689
318k
      if (memcmp(init, s2+1, l2) == 0)
690
28.2k
        return init-1;
691
290k
      else {  /* correct 'l1' and 's1' to try again */
692
290k
        l1 -= init-s1;
693
290k
        s1 = init;
694
290k
      }
695
318k
    }
696
50.5k
    return NULL;  /* not found */
697
78.7k
  }
698
112k
}
699
700
701
/*
702
** get information about the i-th capture. If there are no captures
703
** and 'i==0', return information about the whole match, which
704
** is the range 's'..'e'. If the capture is a string, return
705
** its length and put its address in '*cap'. If it is an integer
706
** (a position), push it on the stack and return CAP_POSITION.
707
*/
708
static size_t get_onecapture (MatchState *ms, int i, const char *s,
709
433
                              const char *e, const char **cap) {
710
433
  if (i >= ms->level) {
711
25
    if (l_unlikely(i != 0))
712
0
      luaL_error(ms->L, "invalid capture index %%%d", i + 1);
713
25
    *cap = s;
714
25
    return e - s;
715
25
  }
716
408
  else {
717
408
    ptrdiff_t capl = ms->capture[i].len;
718
408
    *cap = ms->capture[i].init;
719
408
    if (l_unlikely(capl == CAP_UNFINISHED))
720
0
      luaL_error(ms->L, "unfinished capture");
721
408
    else if (capl == CAP_POSITION)
722
272
      lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1);
723
408
    return capl;
724
408
  }
725
433
}
726
727
728
/*
729
** Push the i-th capture on the stack.
730
*/
731
static void push_onecapture (MatchState *ms, int i, const char *s,
732
433
                                                    const char *e) {
733
433
  const char *cap;
734
433
  ptrdiff_t l = get_onecapture(ms, i, s, e, &cap);
735
433
  if (l != CAP_POSITION)
736
161
    lua_pushlstring(ms->L, cap, l);
737
  /* else position was already pushed */
738
433
}
739
740
741
9.39k
static int push_captures (MatchState *ms, const char *s, const char *e) {
742
9.39k
  int i;
743
9.39k
  int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
744
9.39k
  luaL_checkstack(ms->L, nlevels, "too many captures");
745
9.82k
  for (i = 0; i < nlevels; i++)
746
433
    push_onecapture(ms, i, s, e);
747
9.39k
  return nlevels;  /* number of strings pushed */
748
9.39k
}
749
750
751
/* check whether pattern has no special characters */
752
185k
static int nospecials (const char *p, size_t l) {
753
185k
  size_t upto = 0;
754
1.62M
  do {
755
1.62M
    if (strpbrk(p + upto, SPECIALS))
756
73.2k
      return 0;  /* pattern has a special character */
757
1.55M
    upto += strlen(p + upto) + 1;  /* may have more after \0 */
758
1.55M
  } while (upto <= l);
759
112k
  return 1;  /* no special chars found */
760
185k
}
761
762
763
static void prepstate (MatchState *ms, lua_State *L,
764
80.7k
                       const char *s, size_t ls, const char *p, size_t lp) {
765
80.7k
  ms->L = L;
766
80.7k
  ms->matchdepth = MAXCCALLS;
767
80.7k
  ms->src_init = s;
768
80.7k
  ms->src_end = s + ls;
769
80.7k
  ms->p_end = p + lp;
770
80.7k
}
771
772
773
6.18M
static void reprepstate (MatchState *ms) {
774
6.18M
  ms->level = 0;
775
6.18M
  lua_assert(ms->matchdepth == MAXCCALLS);
776
6.18M
}
777
778
779
186k
static int str_find_aux (lua_State *L, int find) {
780
186k
  size_t ls, lp;
781
186k
  const char *s = luaL_checklstring(L, 1, &ls);
782
186k
  const char *p = luaL_checklstring(L, 2, &lp);
783
186k
  size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1;
784
186k
  if (init > ls) {  /* start after string's end? */
785
0
    luaL_pushfail(L);  /* cannot find anything */
786
0
    return 1;
787
0
  }
788
  /* explicit request or no special characters? */
789
186k
  if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) {
790
    /* do a plain search */
791
112k
    const char *s2 = lmemfind(s + init, ls - init, p, lp);
792
112k
    if (s2) {
793
42.3k
      lua_pushinteger(L, (s2 - s) + 1);
794
42.3k
      lua_pushinteger(L, (s2 - s) + lp);
795
42.3k
      return 2;
796
42.3k
    }
797
112k
  }
798
74.1k
  else {
799
74.1k
    MatchState ms;
800
74.1k
    const char *s1 = s + init;
801
74.1k
    int anchor = (*p == '^');
802
74.1k
    if (anchor) {
803
0
      p++; lp--;  /* skip anchor character */
804
0
    }
805
74.1k
    prepstate(&ms, L, s, ls, p, lp);
806
6.13M
    do {
807
6.13M
      const char *res;
808
6.13M
      reprepstate(&ms);
809
6.13M
      if ((res=match(&ms, s1, p)) != NULL) {
810
9.37k
        if (find) {
811
9.36k
          lua_pushinteger(L, (s1 - s) + 1);  /* start */
812
9.36k
          lua_pushinteger(L, res - s);   /* end */
813
9.36k
          return push_captures(&ms, NULL, 0) + 2;
814
9.36k
        }
815
2
        else
816
2
          return push_captures(&ms, s1, res);
817
9.37k
      }
818
6.13M
    } while (s1++ < ms.src_end && !anchor);
819
74.1k
  }
820
134k
  luaL_pushfail(L);  /* not found */
821
134k
  return 1;
822
186k
}
823
824
825
185k
static int str_find (lua_State *L) {
826
185k
  return str_find_aux(L, 1);
827
185k
}
828
829
830
953
static int str_match (lua_State *L) {
831
953
  return str_find_aux(L, 0);
832
953
}
833
834
835
/* state for 'gmatch' */
836
typedef struct GMatchState {
837
  const char *src;  /* current position */
838
  const char *p;  /* pattern */
839
  const char *lastmatch;  /* end of last match */
840
  MatchState ms;  /* match state */
841
} GMatchState;
842
843
844
204
static int gmatch_aux (lua_State *L) {
845
204
  GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3));
846
204
  const char *src;
847
204
  gm->ms.L = L;
848
48.1k
  for (src = gm->src; src <= gm->ms.src_end; src++) {
849
47.9k
    const char *e;
850
47.9k
    reprepstate(&gm->ms);
851
47.9k
    if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) {
852
23
      gm->src = gm->lastmatch = e;
853
23
      return push_captures(&gm->ms, src, e);
854
23
    }
855
47.9k
  }
856
181
  return 0;  /* not found */
857
204
}
858
859
860
6.57k
static int gmatch (lua_State *L) {
861
6.57k
  size_t ls, lp;
862
6.57k
  const char *s = luaL_checklstring(L, 1, &ls);
863
6.57k
  const char *p = luaL_checklstring(L, 2, &lp);
864
6.57k
  size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1;
865
6.57k
  GMatchState *gm;
866
6.57k
  lua_settop(L, 2);  /* keep strings on closure to avoid being collected */
867
6.57k
  gm = (GMatchState *)lua_newuserdatauv(L, sizeof(GMatchState), 0);
868
6.57k
  if (init > ls)  /* start after string's end? */
869
0
    init = ls + 1;  /* avoid overflows in 's + init' */
870
6.57k
  prepstate(&gm->ms, L, s, ls, p, lp);
871
6.57k
  gm->src = s + init; gm->p = p; gm->lastmatch = NULL;
872
6.57k
  lua_pushcclosure(L, gmatch_aux, 3);
873
6.57k
  return 1;
874
6.57k
}
875
876
877
static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
878
0
                                                   const char *e) {
879
0
  size_t l;
880
0
  lua_State *L = ms->L;
881
0
  const char *news = lua_tolstring(L, 3, &l);
882
0
  const char *p;
883
0
  while ((p = (char *)memchr(news, L_ESC, l)) != NULL) {
884
0
    luaL_addlstring(b, news, p - news);
885
0
    p++;  /* skip ESC */
886
0
    if (*p == L_ESC)  /* '%%' */
887
0
      luaL_addchar(b, *p);
888
0
    else if (*p == '0')  /* '%0' */
889
0
        luaL_addlstring(b, s, e - s);
890
0
    else if (isdigit(uchar(*p))) {  /* '%n' */
891
0
      const char *cap;
892
0
      ptrdiff_t resl = get_onecapture(ms, *p - '1', s, e, &cap);
893
0
      if (resl == CAP_POSITION)
894
0
        luaL_addvalue(b);  /* add position to accumulated result */
895
0
      else
896
0
        luaL_addlstring(b, cap, resl);
897
0
    }
898
0
    else
899
0
      luaL_error(L, "invalid use of '%c' in replacement string", L_ESC);
900
0
    l -= p + 1 - news;
901
0
    news = p + 1;
902
0
  }
903
0
  luaL_addlstring(b, news, l);
904
0
}
905
906
907
/*
908
** Add the replacement value to the string buffer 'b'.
909
** Return true if the original string was changed. (Function calls and
910
** table indexing resulting in nil or false do not change the subject.)
911
*/
912
static int add_value (MatchState *ms, luaL_Buffer *b, const char *s,
913
0
                                      const char *e, int tr) {
914
0
  lua_State *L = ms->L;
915
0
  switch (tr) {
916
0
    case LUA_TFUNCTION: {  /* call the function */
917
0
      int n;
918
0
      lua_pushvalue(L, 3);  /* push the function */
919
0
      n = push_captures(ms, s, e);  /* all captures as arguments */
920
0
      lua_call(L, n, 1);  /* call it */
921
0
      break;
922
0
    }
923
0
    case LUA_TTABLE: {  /* index the table */
924
0
      push_onecapture(ms, 0, s, e);  /* first capture is the index */
925
0
      lua_gettable(L, 3);
926
0
      break;
927
0
    }
928
0
    default: {  /* LUA_TNUMBER or LUA_TSTRING */
929
0
      add_s(ms, b, s, e);  /* add value to the buffer */
930
0
      return 1;  /* something changed */
931
0
    }
932
0
  }
933
0
  if (!lua_toboolean(L, -1)) {  /* nil or false? */
934
0
    lua_pop(L, 1);  /* remove value */
935
0
    luaL_addlstring(b, s, e - s);  /* keep original text */
936
0
    return 0;  /* no changes */
937
0
  }
938
0
  else if (l_unlikely(!lua_isstring(L, -1)))
939
0
    return luaL_error(L, "invalid replacement value (a %s)",
940
0
                         luaL_typename(L, -1));
941
0
  else {
942
0
    luaL_addvalue(b);  /* add result to accumulator */
943
0
    return 1;  /* something changed */
944
0
  }
945
0
}
946
947
948
0
static int str_gsub (lua_State *L) {
949
0
  size_t srcl, lp;
950
0
  const char *src = luaL_checklstring(L, 1, &srcl);  /* subject */
951
0
  const char *p = luaL_checklstring(L, 2, &lp);  /* pattern */
952
0
  const char *lastmatch = NULL;  /* end of last match */
953
0
  int tr = lua_type(L, 3);  /* replacement type */
954
0
  lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1);  /* max replacements */
955
0
  int anchor = (*p == '^');
956
0
  lua_Integer n = 0;  /* replacement count */
957
0
  int changed = 0;  /* change flag */
958
0
  MatchState ms;
959
0
  luaL_Buffer b;
960
0
  luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
961
0
                   tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
962
0
                      "string/function/table");
963
0
  luaL_buffinit(L, &b);
964
0
  if (anchor) {
965
0
    p++; lp--;  /* skip anchor character */
966
0
  }
967
0
  prepstate(&ms, L, src, srcl, p, lp);
968
0
  while (n < max_s) {
969
0
    const char *e;
970
0
    reprepstate(&ms);  /* (re)prepare state for new match */
971
0
    if ((e = match(&ms, src, p)) != NULL && e != lastmatch) {  /* match? */
972
0
      n++;
973
0
      changed = add_value(&ms, &b, src, e, tr) | changed;
974
0
      src = lastmatch = e;
975
0
    }
976
0
    else if (src < ms.src_end)  /* otherwise, skip one character */
977
0
      luaL_addchar(&b, *src++);
978
0
    else break;  /* end of subject */
979
0
    if (anchor) break;
980
0
  }
981
0
  if (!changed)  /* no changes? */
982
0
    lua_pushvalue(L, 1);  /* return original string */
983
0
  else {  /* something changed */
984
0
    luaL_addlstring(&b, src, ms.src_end-src);
985
0
    luaL_pushresult(&b);  /* create and return new string */
986
0
  }
987
0
  lua_pushinteger(L, n);  /* number of substitutions */
988
0
  return 2;
989
0
}
990
991
/* }====================================================== */
992
993
994
995
/*
996
** {======================================================
997
** STRING FORMAT
998
** =======================================================
999
*/
1000
1001
#if !defined(lua_number2strx) /* { */
1002
1003
/*
1004
** Hexadecimal floating-point formatter
1005
*/
1006
1007
#define SIZELENMOD  (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
1008
1009
1010
/*
1011
** Number of bits that goes into the first digit. It can be any value
1012
** between 1 and 4; the following definition tries to align the number
1013
** to nibble boundaries by making what is left after that first digit a
1014
** multiple of 4.
1015
*/
1016
#define L_NBFD    ((l_floatatt(MANT_DIG) - 1)%4 + 1)
1017
1018
1019
/*
1020
** Add integer part of 'x' to buffer and return new 'x'
1021
*/
1022
static lua_Number adddigit (char *buff, int n, lua_Number x) {
1023
  lua_Number dd = l_mathop(floor)(x);  /* get integer part from 'x' */
1024
  int d = (int)dd;
1025
  buff[n] = (d < 10 ? d + '0' : d - 10 + 'a');  /* add to buffer */
1026
  return x - dd;  /* return what is left */
1027
}
1028
1029
1030
static int num2straux (char *buff, int sz, lua_Number x) {
1031
  /* if 'inf' or 'NaN', format it like '%g' */
1032
  if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL)
1033
    return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x);
1034
  else if (x == 0) {  /* can be -0... */
1035
    /* create "0" or "-0" followed by exponent */
1036
    return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x);
1037
  }
1038
  else {
1039
    int e;
1040
    lua_Number m = l_mathop(frexp)(x, &e);  /* 'x' fraction and exponent */
1041
    int n = 0;  /* character count */
1042
    if (m < 0) {  /* is number negative? */
1043
      buff[n++] = '-';  /* add sign */
1044
      m = -m;  /* make it positive */
1045
    }
1046
    buff[n++] = '0'; buff[n++] = 'x';  /* add "0x" */
1047
    m = adddigit(buff, n++, m * (1 << L_NBFD));  /* add first digit */
1048
    e -= L_NBFD;  /* this digit goes before the radix point */
1049
    if (m > 0) {  /* more digits? */
1050
      buff[n++] = lua_getlocaledecpoint();  /* add radix point */
1051
      do {  /* add as many digits as needed */
1052
        m = adddigit(buff, n++, m * 16);
1053
      } while (m > 0);
1054
    }
1055
    n += l_sprintf(buff + n, sz - n, "p%+d", e);  /* add exponent */
1056
    lua_assert(n < sz);
1057
    return n;
1058
  }
1059
}
1060
1061
1062
static int lua_number2strx (lua_State *L, char *buff, int sz,
1063
                            const char *fmt, lua_Number x) {
1064
  int n = num2straux(buff, sz, x);
1065
  if (fmt[SIZELENMOD] == 'A') {
1066
    int i;
1067
    for (i = 0; i < n; i++)
1068
      buff[i] = toupper(uchar(buff[i]));
1069
  }
1070
  else if (l_unlikely(fmt[SIZELENMOD] != 'a'))
1071
    return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
1072
  return n;
1073
}
1074
1075
#endif        /* } */
1076
1077
1078
/*
1079
** Maximum size for items formatted with '%f'. This size is produced
1080
** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.',
1081
** and '\0') + number of decimal digits to represent maxfloat (which
1082
** is maximum exponent + 1). (99+3+1, adding some extra, 110)
1083
*/
1084
75
#define MAX_ITEMF (110 + l_floatatt(MAX_10_EXP))
1085
1086
1087
/*
1088
** All formats except '%f' do not need that large limit.  The other
1089
** float formats use exponents, so that they fit in the 99 limit for
1090
** significant digits; 's' for large strings and 'q' add items directly
1091
** to the buffer; all integer formats also fit in the 99 limit.  The
1092
** worst case are floats: they may need 99 significant digits, plus
1093
** '0x', '-', '.', 'e+XXXX', and '\0'. Adding some extra, 120.
1094
*/
1095
68.7k
#define MAX_ITEM  120
1096
1097
1098
/* valid flags in a format specification */
1099
#if !defined(L_FMTFLAGSF)
1100
1101
/* valid flags for a, A, e, E, f, F, g, and G conversions */
1102
69.0k
#define L_FMTFLAGSF "-+#0 "
1103
1104
/* valid flags for o, x, and X conversions */
1105
2.12k
#define L_FMTFLAGSX "-#0"
1106
1107
/* valid flags for d and i conversions */
1108
2.08k
#define L_FMTFLAGSI "-+0 "
1109
1110
/* valid flags for u conversions */
1111
32
#define L_FMTFLAGSU "-0"
1112
1113
/* valid flags for c, p, and s conversions */
1114
136
#define L_FMTFLAGSC "-"
1115
1116
#endif
1117
1118
1119
/*
1120
** Maximum size of each format specification (such as "%-099.99d"):
1121
** Initial '%', flags (up to 5), width (2), period, precision (2),
1122
** length modifier (8), conversion specifier, and final '\0', plus some
1123
** extra.
1124
*/
1125
68.7k
#define MAX_FORMAT  32
1126
1127
1128
30.0k
static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
1129
30.0k
  luaL_addchar(b, '"');
1130
23.9M
  while (len--) {
1131
23.9M
    if (*s == '"' || *s == '\\' || *s == '\n') {
1132
1.73M
      luaL_addchar(b, '\\');
1133
1.73M
      luaL_addchar(b, *s);
1134
1.73M
    }
1135
22.2M
    else if (iscntrl(uchar(*s))) {
1136
1.87M
      char buff[10];
1137
1.87M
      if (!isdigit(uchar(*(s+1))))
1138
1.76M
        l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
1139
108k
      else
1140
108k
        l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s));
1141
1.87M
      luaL_addstring(b, buff);
1142
1.87M
    }
1143
20.3M
    else
1144
20.3M
      luaL_addchar(b, *s);
1145
23.9M
    s++;
1146
23.9M
  }
1147
30.0k
  luaL_addchar(b, '"');
1148
30.0k
}
1149
1150
1151
/*
1152
** Serialize a floating-point number in such a way that it can be
1153
** scanned back by Lua. Use hexadecimal format for "common" numbers
1154
** (to preserve precision); inf, -inf, and NaN are handled separately.
1155
** (NaN cannot be expressed as a numeral, so we write '(0/0)' for it.)
1156
*/
1157
0
static int quotefloat (lua_State *L, char *buff, lua_Number n) {
1158
0
  const char *s;  /* for the fixed representations */
1159
0
  if (n == (lua_Number)HUGE_VAL)  /* inf? */
1160
0
    s = "1e9999";
1161
0
  else if (n == -(lua_Number)HUGE_VAL)  /* -inf? */
1162
0
    s = "-1e9999";
1163
0
  else if (n != n)  /* NaN? */
1164
0
    s = "(0/0)";
1165
0
  else {  /* format number as hexadecimal */
1166
0
    int  nb = lua_number2strx(L, buff, MAX_ITEM,
1167
0
                                 "%" LUA_NUMBER_FRMLEN "a", n);
1168
    /* ensures that 'buff' string uses a dot as the radix character */
1169
0
    if (memchr(buff, '.', nb) == NULL) {  /* no dot? */
1170
0
      char point = lua_getlocaledecpoint();  /* try locale point */
1171
0
      char *ppoint = (char *)memchr(buff, point, nb);
1172
0
      if (ppoint) *ppoint = '.';  /* change it to a dot */
1173
0
    }
1174
0
    return nb;
1175
0
  }
1176
  /* for the fixed representations */
1177
0
  return l_sprintf(buff, MAX_ITEM, "%s", s);
1178
0
}
1179
1180
1181
30.0k
static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
1182
30.0k
  switch (lua_type(L, arg)) {
1183
30.0k
    case LUA_TSTRING: {
1184
30.0k
      size_t len;
1185
30.0k
      const char *s = lua_tolstring(L, arg, &len);
1186
30.0k
      addquoted(b, s, len);
1187
30.0k
      break;
1188
0
    }
1189
0
    case LUA_TNUMBER: {
1190
0
      char *buff = luaL_prepbuffsize(b, MAX_ITEM);
1191
0
      int nb;
1192
0
      if (!lua_isinteger(L, arg))  /* float? */
1193
0
        nb = quotefloat(L, buff, lua_tonumber(L, arg));
1194
0
      else {  /* integers */
1195
0
        lua_Integer n = lua_tointeger(L, arg);
1196
0
        const char *format = (n == LUA_MININTEGER)  /* corner case? */
1197
0
                           ? "0x%" LUA_INTEGER_FRMLEN "x"  /* use hex */
1198
0
                           : LUA_INTEGER_FMT;  /* else use default format */
1199
0
        nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n);
1200
0
      }
1201
0
      luaL_addsize(b, nb);
1202
0
      break;
1203
0
    }
1204
0
    case LUA_TNIL: case LUA_TBOOLEAN: {
1205
0
      luaL_tolstring(L, arg, NULL);
1206
0
      luaL_addvalue(b);
1207
0
      break;
1208
0
    }
1209
0
    default: {
1210
0
      luaL_argerror(L, arg, "value has no literal form");
1211
0
    }
1212
30.0k
  }
1213
30.0k
}
1214
1215
1216
272
static const char *get2digits (const char *s) {
1217
272
  if (isdigit(uchar(*s))) {
1218
77
    s++;
1219
77
    if (isdigit(uchar(*s))) s++;  /* (2 digits at most) */
1220
77
  }
1221
272
  return s;
1222
272
}
1223
1224
1225
/*
1226
** Check whether a conversion specification is valid. When called,
1227
** first character in 'form' must be '%' and last character must
1228
** be a valid conversion specifier. 'flags' are the accepted flags;
1229
** 'precision' signals whether to accept a precision.
1230
*/
1231
static void checkformat (lua_State *L, const char *form, const char *flags,
1232
318
                                       int precision) {
1233
318
  const char *spec = form + 1;  /* skip '%' */
1234
318
  spec += strspn(spec, flags);  /* skip flags */
1235
318
  if (*spec != '0') {  /* a width cannot start with '0' */
1236
272
    spec = get2digits(spec);  /* skip width */
1237
272
    if (*spec == '.' && precision) {
1238
0
      spec++;
1239
0
      spec = get2digits(spec);  /* skip precision */
1240
0
    }
1241
272
  }
1242
318
  if (!isalpha(uchar(*spec)))  /* did not go to the end? */
1243
46
    luaL_error(L, "invalid conversion specification: '%s'", form);
1244
318
}
1245
1246
1247
/*
1248
** Get a conversion specification and copy it to 'form'.
1249
** Return the address of its last character.
1250
*/
1251
static const char *getformat (lua_State *L, const char *strfrmt,
1252
68.7k
                                            char *form) {
1253
  /* spans flags, width, and precision ('0' is included as a flag) */
1254
68.7k
  size_t len = strspn(strfrmt, L_FMTFLAGSF "123456789.");
1255
68.7k
  len++;  /* adds following character (should be the specifier) */
1256
  /* still needs space for '%', '\0', plus a length modifier */
1257
68.7k
  if (len >= MAX_FORMAT - 10)
1258
32.5k
    luaL_error(L, "invalid format (too long)");
1259
68.7k
  *(form++) = '%';
1260
68.7k
  memcpy(form, strfrmt, len * sizeof(char));
1261
68.7k
  *(form + len) = '\0';
1262
68.7k
  return strfrmt + len - 1;
1263
68.7k
}
1264
1265
1266
/*
1267
** add length modifier into formats
1268
*/
1269
192
static void addlenmod (char *form, const char *lenmod) {
1270
192
  size_t l = strlen(form);
1271
192
  size_t lm = strlen(lenmod);
1272
192
  char spec = form[l - 1];
1273
192
  strcpy(form + l - 1, lenmod);
1274
192
  form[l + lm - 1] = spec;
1275
192
  form[l + lm] = '\0';
1276
192
}
1277
1278
1279
87.1k
static int str_format (lua_State *L) {
1280
87.1k
  int top = lua_gettop(L);
1281
87.1k
  int arg = 1;
1282
87.1k
  size_t sfl;
1283
87.1k
  const char *strfrmt = luaL_checklstring(L, arg, &sfl);
1284
87.1k
  const char *strfrmt_end = strfrmt+sfl;
1285
87.1k
  const char *flags;
1286
87.1k
  luaL_Buffer b;
1287
87.1k
  luaL_buffinit(L, &b);
1288
14.7M
  while (strfrmt < strfrmt_end) {
1289
14.7M
    if (*strfrmt != L_ESC)
1290
14.6M
      luaL_addchar(&b, *strfrmt++);
1291
101k
    else if (*++strfrmt == L_ESC)
1292
32.5k
      luaL_addchar(&b, *strfrmt++);  /* %% */
1293
68.7k
    else { /* format item */
1294
68.7k
      char form[MAX_FORMAT];  /* to store the format ('%...') */
1295
68.7k
      int maxitem = MAX_ITEM;  /* maximum length for the result */
1296
68.7k
      char *buff = luaL_prepbuffsize(&b, maxitem);  /* to put result */
1297
68.7k
      int nb = 0;  /* number of bytes in result */
1298
68.7k
      if (++arg > top)
1299
58
        return luaL_argerror(L, arg, "no value");
1300
68.7k
      strfrmt = getformat(L, strfrmt, form);
1301
68.7k
      switch (*strfrmt++) {
1302
39
        case 'c': {
1303
39
          checkformat(L, form, L_FMTFLAGSC, 0);
1304
39
          nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg));
1305
39
          break;
1306
0
        }
1307
2.08k
        case 'd': case 'i':
1308
2.08k
          flags = L_FMTFLAGSI;
1309
2.08k
          goto intcase;
1310
32
        case 'u':
1311
32
          flags = L_FMTFLAGSU;
1312
32
          goto intcase;
1313
2.12k
        case 'o': case 'x': case 'X':
1314
2.12k
          flags = L_FMTFLAGSX;
1315
4.23k
         intcase: {
1316
4.23k
          lua_Integer n = luaL_checkinteger(L, arg);
1317
4.23k
          checkformat(L, form, flags, 1);
1318
4.23k
          addlenmod(form, LUA_INTEGER_FRMLEN);
1319
4.23k
          nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n);
1320
4.23k
          break;
1321
2.12k
        }
1322
192
        case 'a': case 'A':
1323
192
          checkformat(L, form, L_FMTFLAGSF, 1);
1324
192
          addlenmod(form, LUA_NUMBER_FRMLEN);
1325
192
          nb = lua_number2strx(L, buff, maxitem, form,
1326
192
                                  luaL_checknumber(L, arg));
1327
192
          break;
1328
75
        case 'f':
1329
75
          maxitem = MAX_ITEMF;  /* extra space for '%f' */
1330
75
          buff = luaL_prepbuffsize(&b, maxitem);
1331
          /* FALLTHROUGH */
1332
105
        case 'e': case 'E': case 'g': case 'G': {
1333
105
          lua_Number n = luaL_checknumber(L, arg);
1334
105
          checkformat(L, form, L_FMTFLAGSF, 1);
1335
105
          addlenmod(form, LUA_NUMBER_FRMLEN);
1336
105
          nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n);
1337
105
          break;
1338
105
        }
1339
32
        case 'p': {
1340
32
          const void *p = lua_topointer(L, arg);
1341
32
          checkformat(L, form, L_FMTFLAGSC, 0);
1342
32
          if (p == NULL) {  /* avoid calling 'printf' with argument NULL */
1343
0
            p = "(null)";  /* result */
1344
0
            form[strlen(form) - 1] = 's';  /* format it as a string */
1345
0
          }
1346
32
          nb = l_sprintf(buff, maxitem, form, p);
1347
32
          break;
1348
105
        }
1349
30.0k
        case 'q': {
1350
30.0k
          if (form[2] != '\0')  /* modifiers? */
1351
0
            return luaL_error(L, "specifier '%%q' cannot have modifiers");
1352
30.0k
          addliteral(L, &b, arg);
1353
30.0k
          break;
1354
30.0k
        }
1355
785
        case 's': {
1356
785
          size_t l;
1357
785
          const char *s = luaL_tolstring(L, arg, &l);
1358
785
          if (form[2] == '\0')  /* no modifiers? */
1359
720
            luaL_addvalue(&b);  /* keep entire string */
1360
65
          else {
1361
65
            luaL_argcheck(L, l == strlen(s), arg, "string contains zeros");
1362
65
            checkformat(L, form, L_FMTFLAGSC, 1);
1363
65
            if (strchr(form, '.') == NULL && l >= 100) {
1364
              /* no precision and string is too long to be formatted */
1365
25
              luaL_addvalue(&b);  /* keep entire string */
1366
25
            }
1367
40
            else {  /* format the string into 'buff' */
1368
40
              nb = l_sprintf(buff, maxitem, form, s);
1369
40
              lua_pop(L, 1);  /* remove result from 'luaL_tolstring' */
1370
40
            }
1371
65
          }
1372
785
          break;
1373
30.0k
        }
1374
737
        default: {  /* also treat cases 'pnLlh' */
1375
737
          return luaL_error(L, "invalid conversion '%s' to 'format'", form);
1376
30.0k
        }
1377
68.7k
      }
1378
30.8k
      lua_assert(nb < maxitem);
1379
30.8k
      luaL_addsize(&b, nb);
1380
30.8k
    }
1381
14.7M
  }
1382
49.2k
  luaL_pushresult(&b);
1383
49.2k
  return 1;
1384
87.1k
}
1385
1386
/* }====================================================== */
1387
1388
1389
/*
1390
** {======================================================
1391
** PACK/UNPACK
1392
** =======================================================
1393
*/
1394
1395
1396
/* value used for padding */
1397
#if !defined(LUAL_PACKPADBYTE)
1398
#define LUAL_PACKPADBYTE    0x00
1399
#endif
1400
1401
/* maximum size for the binary representation of an integer */
1402
38
#define MAXINTSIZE  16
1403
1404
/* number of bits in a character */
1405
235k
#define NB  CHAR_BIT
1406
1407
/* mask for one character (NB 1's) */
1408
109k
#define MC  ((1 << NB) - 1)
1409
1410
/* size of a lua_Integer */
1411
42.5k
#define SZINT ((int)sizeof(lua_Integer))
1412
1413
1414
/* dummy union to get native endianness */
1415
static const union {
1416
  int dummy;
1417
  char little;  /* true iff machine is little endian */
1418
} nativeendian = {1};
1419
1420
1421
/*
1422
** information to pack/unpack stuff
1423
*/
1424
typedef struct Header {
1425
  lua_State *L;
1426
  int islittle;
1427
  int maxalign;
1428
} Header;
1429
1430
1431
/*
1432
** options for pack/unpack
1433
*/
1434
typedef enum KOption {
1435
  Kint,   /* signed integers */
1436
  Kuint,  /* unsigned integers */
1437
  Kfloat, /* single-precision floating-point numbers */
1438
  Knumber,  /* Lua "native" floating-point numbers */
1439
  Kdouble,  /* double-precision floating-point numbers */
1440
  Kchar,  /* fixed-length strings */
1441
  Kstring,  /* strings with prefixed length */
1442
  Kzstr,  /* zero-terminated strings */
1443
  Kpadding, /* padding */
1444
  Kpaddalign, /* padding for alignment */
1445
  Knop    /* no-op (configuration or spaces) */
1446
} KOption;
1447
1448
1449
/*
1450
** Read an integer numeral from string 'fmt' or return 'df' if
1451
** there is no numeral
1452
*/
1453
508k
static int digit (int c) { return '0' <= c && c <= '9'; }
1454
1455
139k
static int getnum (const char **fmt, int df) {
1456
139k
  if (!digit(**fmt))  /* no number? */
1457
39.1k
    return df;  /* return default value */
1458
100k
  else {
1459
100k
    int a = 0;
1460
368k
    do {
1461
368k
      a = a*10 + (*((*fmt)++) - '0');
1462
368k
    } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10);
1463
100k
    return a;
1464
100k
  }
1465
139k
}
1466
1467
1468
/*
1469
** Read an integer numeral and raises an error if it is larger
1470
** than the maximum size for integers.
1471
*/
1472
50.7k
static int getnumlimit (Header *h, const char **fmt, int df) {
1473
50.7k
  int sz = getnum(fmt, df);
1474
50.7k
  if (l_unlikely(sz > MAXINTSIZE || sz <= 0))
1475
38
    return luaL_error(h->L, "integral size (%d) out of limits [1,%d]",
1476
38
                            sz, MAXINTSIZE);
1477
50.7k
  return sz;
1478
50.7k
}
1479
1480
1481
/*
1482
** Initialize Header
1483
*/
1484
115k
static void initheader (lua_State *L, Header *h) {
1485
115k
  h->L = L;
1486
115k
  h->islittle = nativeendian.little;
1487
115k
  h->maxalign = 1;
1488
115k
}
1489
1490
1491
/*
1492
** Read and classify next option. 'size' is filled with option's size.
1493
*/
1494
216k
static KOption getoption (Header *h, const char **fmt, int *size) {
1495
  /* dummy structure to get native alignment requirements */
1496
216k
  struct cD { char c; union { LUAI_MAXALIGN; } u; };
1497
216k
  int opt = *((*fmt)++);
1498
216k
  *size = 0;  /* default */
1499
216k
  switch (opt) {
1500
5.83k
    case 'b': *size = sizeof(char); return Kint;
1501
11.5k
    case 'B': *size = sizeof(char); return Kuint;
1502
0
    case 'h': *size = sizeof(short); return Kint;
1503
285
    case 'H': *size = sizeof(short); return Kuint;
1504
0
    case 'l': *size = sizeof(long); return Kint;
1505
57
    case 'L': *size = sizeof(long); return Kuint;
1506
139
    case 'j': *size = sizeof(lua_Integer); return Kint;
1507
1
    case 'J': *size = sizeof(lua_Integer); return Kuint;
1508
0
    case 'T': *size = sizeof(size_t); return Kuint;
1509
6.14k
    case 'f': *size = sizeof(float); return Kfloat;
1510
1.27k
    case 'n': *size = sizeof(lua_Number); return Knumber;
1511
170
    case 'd': *size = sizeof(double); return Kdouble;
1512
1.23k
    case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint;
1513
3.04k
    case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint;
1514
9.10k
    case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring;
1515
89.1k
    case 'c':
1516
89.1k
      *size = getnum(fmt, -1);
1517
89.1k
      if (l_unlikely(*size == -1))
1518
10.0k
        luaL_error(h->L, "missing size for format option 'c'");
1519
89.1k
      return Kchar;
1520
7.54k
    case 'z': return Kzstr;
1521
6.08k
    case 'x': *size = 1; return Kpadding;
1522
200
    case 'X': return Kpaddalign;
1523
12.1k
    case ' ': break;
1524
788
    case '<': h->islittle = 1; break;
1525
17.5k
    case '>': h->islittle = 0; break;
1526
827
    case '=': h->islittle = nativeendian.little; break;
1527
37.3k
    case '!': {
1528
37.3k
      const int maxalign = offsetof(struct cD, u);
1529
37.3k
      h->maxalign = getnumlimit(h, fmt, maxalign);
1530
37.3k
      break;
1531
0
    }
1532
6.01k
    default: luaL_error(h->L, "invalid format option '%c'", opt);
1533
216k
  }
1534
68.6k
  return Knop;
1535
216k
}
1536
1537
1538
/*
1539
** Read, classify, and fill other details about the next option.
1540
** 'psize' is filled with option's size, 'notoalign' with its
1541
** alignment requirements.
1542
** Local variable 'size' gets the size to be aligned. (Kpadal option
1543
** always gets its full alignment, other options are limited by
1544
** the maximum alignment ('maxalign'). Kchar option needs no alignment
1545
** despite its size.
1546
*/
1547
static KOption getdetails (Header *h, size_t totalsize,
1548
216k
                           const char **fmt, int *psize, int *ntoalign) {
1549
216k
  KOption opt = getoption(h, fmt, psize);
1550
216k
  int align = *psize;  /* usually, alignment follows size */
1551
216k
  if (opt == Kpaddalign) {  /* 'X' gets alignment from following option */
1552
200
    if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0)
1553
0
      luaL_argerror(h->L, 1, "invalid next option for option 'X'");
1554
200
  }
1555
216k
  if (align <= 1 || opt == Kchar)  /* need no alignment? */
1556
178k
    *ntoalign = 0;
1557
37.4k
  else {
1558
37.4k
    if (align > h->maxalign)  /* enforce maximum alignment */
1559
13.8k
      align = h->maxalign;
1560
37.4k
    if (l_unlikely((align & (align - 1)) != 0))  /* not a power of 2? */
1561
0
      luaL_argerror(h->L, 1, "format asks for alignment not power of 2");
1562
37.4k
    *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1);
1563
37.4k
  }
1564
216k
  return opt;
1565
216k
}
1566
1567
1568
/*
1569
** Pack integer 'n' with 'size' bytes and 'islittle' endianness.
1570
** The final 'if' handles the case when 'size' is larger than
1571
** the size of a Lua integer, correcting the extra sign-extension
1572
** bytes if necessary (by default they would be zeros).
1573
*/
1574
static void packint (luaL_Buffer *b, lua_Unsigned n,
1575
12.7k
                     int islittle, int size, int neg) {
1576
12.7k
  char *buff = luaL_prepbuffsize(b, size);
1577
12.7k
  int i;
1578
12.7k
  buff[islittle ? 0 : size - 1] = (char)(n & MC);  /* first byte */
1579
109k
  for (i = 1; i < size; i++) {
1580
96.6k
    n >>= NB;
1581
96.6k
    buff[islittle ? i : size - 1 - i] = (char)(n & MC);
1582
96.6k
  }
1583
12.7k
  if (neg && size > SZINT) {  /* negative number need sign extension? */
1584
120
    for (i = SZINT; i < size; i++)  /* correct extra bytes */
1585
68
      buff[islittle ? i : size - 1 - i] = (char)MC;
1586
52
  }
1587
12.7k
  luaL_addsize(b, size);  /* add result to buffer */
1588
12.7k
}
1589
1590
1591
/*
1592
** Copy 'size' bytes from 'src' to 'dest', correcting endianness if
1593
** given 'islittle' is different from native endianness.
1594
*/
1595
static void copywithendian (char *dest, const char *src,
1596
7.58k
                            int size, int islittle) {
1597
7.58k
  if (islittle == nativeendian.little)
1598
6.18k
    memcpy(dest, src, size);
1599
1.39k
  else {
1600
1.39k
    dest += size - 1;
1601
12.2k
    while (size-- != 0)
1602
10.8k
      *(dest--) = *(src++);
1603
1.39k
  }
1604
7.58k
}
1605
1606
1607
108k
static int str_pack (lua_State *L) {
1608
108k
  luaL_Buffer b;
1609
108k
  Header h;
1610
108k
  const char *fmt = luaL_checkstring(L, 1);  /* format string */
1611
108k
  int arg = 1;  /* current argument to pack */
1612
108k
  size_t totalsize = 0;  /* accumulate total size of result */
1613
108k
  initheader(L, &h);
1614
108k
  lua_pushnil(L);  /* mark to separate arguments from string buffer */
1615
108k
  luaL_buffinit(L, &b);
1616
252k
  while (*fmt != '\0') {
1617
161k
    int size, ntoalign;
1618
161k
    KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1619
161k
    totalsize += ntoalign + size;
1620
162k
    while (ntoalign-- > 0)
1621
607
     luaL_addchar(&b, LUAL_PACKPADBYTE);  /* fill alignment */
1622
161k
    arg++;
1623
161k
    switch (opt) {
1624
1.19k
      case Kint: {  /* signed integers */
1625
1.19k
        lua_Integer n = luaL_checkinteger(L, arg);
1626
1.19k
        if (size < SZINT) {  /* need overflow check? */
1627
1.10k
          lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1);
1628
1.10k
          luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow");
1629
1.10k
        }
1630
1.19k
        packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0));
1631
1.19k
        break;
1632
0
      }
1633
3.04k
      case Kuint: {  /* unsigned integers */
1634
3.04k
        lua_Integer n = luaL_checkinteger(L, arg);
1635
3.04k
        if (size < SZINT)  /* need overflow check? */
1636
0
          luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)),
1637
3.04k
                           arg, "unsigned overflow");
1638
3.04k
        packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
1639
3.04k
        break;
1640
0
      }
1641
6.06k
      case Kfloat: {  /* C float */
1642
6.06k
        float f = (float)luaL_checknumber(L, arg);  /* get argument */
1643
6.06k
        char *buff = luaL_prepbuffsize(&b, sizeof(f));
1644
        /* move 'f' to final result, correcting endianness if needed */
1645
6.06k
        copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
1646
6.06k
        luaL_addsize(&b, size);
1647
6.06k
        break;
1648
0
      }
1649
0
      case Knumber: {  /* Lua float */
1650
0
        lua_Number f = luaL_checknumber(L, arg);  /* get argument */
1651
0
        char *buff = luaL_prepbuffsize(&b, sizeof(f));
1652
        /* move 'f' to final result, correcting endianness if needed */
1653
0
        copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
1654
0
        luaL_addsize(&b, size);
1655
0
        break;
1656
0
      }
1657
58
      case Kdouble: {  /* C double */
1658
58
        double f = (double)luaL_checknumber(L, arg);  /* get argument */
1659
58
        char *buff = luaL_prepbuffsize(&b, sizeof(f));
1660
        /* move 'f' to final result, correcting endianness if needed */
1661
58
        copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
1662
58
        luaL_addsize(&b, size);
1663
58
        break;
1664
0
      }
1665
73.3k
      case Kchar: {  /* fixed-size string */
1666
73.3k
        size_t len;
1667
73.3k
        const char *s = luaL_checklstring(L, arg, &len);
1668
73.3k
        luaL_argcheck(L, len <= (size_t)size, arg,
1669
73.3k
                         "string longer than given size");
1670
73.3k
        luaL_addlstring(&b, s, len);  /* add string */
1671
1.90G
        while (len++ < (size_t)size)  /* pad extra space */
1672
1.90G
          luaL_addchar(&b, LUAL_PACKPADBYTE);
1673
73.3k
        break;
1674
0
      }
1675
8.51k
      case Kstring: {  /* strings with length count */
1676
8.51k
        size_t len;
1677
8.51k
        const char *s = luaL_checklstring(L, arg, &len);
1678
8.51k
        luaL_argcheck(L, size >= (int)sizeof(size_t) ||
1679
8.51k
                         len < ((size_t)1 << (size * NB)),
1680
8.51k
                         arg, "string length does not fit in given size");
1681
8.51k
        packint(&b, (lua_Unsigned)len, h.islittle, size, 0);  /* pack length */
1682
8.51k
        luaL_addlstring(&b, s, len);
1683
8.51k
        totalsize += len;
1684
8.51k
        break;
1685
0
      }
1686
7.54k
      case Kzstr: {  /* zero-terminated string */
1687
7.54k
        size_t len;
1688
7.54k
        const char *s = luaL_checklstring(L, arg, &len);
1689
7.54k
        luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros");
1690
7.54k
        luaL_addlstring(&b, s, len);
1691
7.54k
        luaL_addchar(&b, '\0');  /* add zero at the end */
1692
7.54k
        totalsize += len + 1;
1693
7.54k
        break;
1694
0
      }
1695
6.08k
      case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE);  /* FALLTHROUGH */
1696
45.7k
      case Kpaddalign: case Knop:
1697
45.7k
        arg--;  /* undo increment */
1698
45.7k
        break;
1699
161k
    }
1700
161k
  }
1701
90.8k
  luaL_pushresult(&b);
1702
90.8k
  return 1;
1703
108k
}
1704
1705
1706
0
static int str_packsize (lua_State *L) {
1707
0
  Header h;
1708
0
  const char *fmt = luaL_checkstring(L, 1);  /* format string */
1709
0
  size_t totalsize = 0;  /* accumulate total size of result */
1710
0
  initheader(L, &h);
1711
0
  while (*fmt != '\0') {
1712
0
    int size, ntoalign;
1713
0
    KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1714
0
    luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1,
1715
0
                     "variable-length format");
1716
0
    size += ntoalign;  /* total space used by option */
1717
0
    luaL_argcheck(L, totalsize <= MAXSIZE - size, 1,
1718
0
                     "format result too large");
1719
0
    totalsize += size;
1720
0
  }
1721
0
  lua_pushinteger(L, (lua_Integer)totalsize);
1722
0
  return 1;
1723
0
}
1724
1725
1726
/*
1727
** Unpack an integer with 'size' bytes and 'islittle' endianness.
1728
** If size is smaller than the size of a Lua integer and integer
1729
** is signed, must do sign extension (propagating the sign to the
1730
** higher bits); if size is larger than the size of a Lua integer,
1731
** it must check the unread bytes to see whether they do not cause an
1732
** overflow.
1733
*/
1734
static lua_Integer unpackint (lua_State *L, const char *str,
1735
18.2k
                              int islittle, int size, int issigned) {
1736
18.2k
  lua_Unsigned res = 0;
1737
18.2k
  int i;
1738
18.2k
  int limit = (size  <= SZINT) ? size : SZINT;
1739
40.8k
  for (i = limit - 1; i >= 0; i--) {
1740
22.5k
    res <<= NB;
1741
22.5k
    res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i];
1742
22.5k
  }
1743
18.2k
  if (size < SZINT) {  /* real size smaller than lua_Integer? */
1744
17.7k
    if (issigned) {  /* needs sign extension? */
1745
5.83k
      lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1);
1746
5.83k
      res = ((res ^ mask) - mask);  /* do sign extension */
1747
5.83k
    }
1748
17.7k
  }
1749
559
  else if (size > SZINT) {  /* must check unread bytes */
1750
0
    int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC;
1751
0
    for (i = limit; i < size; i++) {
1752
0
      if (l_unlikely((unsigned char)str[islittle ? i : size - 1 - i] != mask))
1753
0
        luaL_error(L, "%d-byte integer does not fit into Lua Integer", size);
1754
0
    }
1755
0
  }
1756
18.2k
  return (lua_Integer)res;
1757
18.2k
}
1758
1759
1760
6.43k
static int str_unpack (lua_State *L) {
1761
6.43k
  Header h;
1762
6.43k
  const char *fmt = luaL_checkstring(L, 1);
1763
6.43k
  size_t ld;
1764
6.43k
  const char *data = luaL_checklstring(L, 2, &ld);
1765
6.43k
  size_t pos = posrelatI(luaL_optinteger(L, 3, 1), ld) - 1;
1766
6.43k
  int n = 0;  /* number of results */
1767
6.43k
  luaL_argcheck(L, pos <= ld, 3, "initial position out of string");
1768
6.43k
  initheader(L, &h);
1769
55.4k
  while (*fmt != '\0') {
1770
54.7k
    int size, ntoalign;
1771
54.7k
    KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign);
1772
54.7k
    luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2,
1773
54.7k
                    "data string too short");
1774
54.7k
    pos += ntoalign;  /* skip alignment */
1775
    /* stack space for item + next position */
1776
54.7k
    luaL_checkstack(L, 2, "too many results");
1777
54.7k
    n++;
1778
54.7k
    switch (opt) {
1779
5.83k
      case Kint:
1780
17.6k
      case Kuint: {
1781
17.6k
        lua_Integer res = unpackint(L, data + pos, h.islittle, size,
1782
17.6k
                                       (opt == Kint));
1783
17.6k
        lua_pushinteger(L, res);
1784
17.6k
        break;
1785
5.83k
      }
1786
74
      case Kfloat: {
1787
74
        float f;
1788
74
        copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
1789
74
        lua_pushnumber(L, (lua_Number)f);
1790
74
        break;
1791
5.83k
      }
1792
1.27k
      case Knumber: {
1793
1.27k
        lua_Number f;
1794
1.27k
        copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
1795
1.27k
        lua_pushnumber(L, f);
1796
1.27k
        break;
1797
5.83k
      }
1798
112
      case Kdouble: {
1799
112
        double f;
1800
112
        copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
1801
112
        lua_pushnumber(L, (lua_Number)f);
1802
112
        break;
1803
5.83k
      }
1804
69
      case Kchar: {
1805
69
        lua_pushlstring(L, data + pos, size);
1806
69
        break;
1807
5.83k
      }
1808
590
      case Kstring: {
1809
590
        size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0);
1810
590
        luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short");
1811
590
        lua_pushlstring(L, data + pos + size, len);
1812
590
        pos += len;  /* skip string */
1813
590
        break;
1814
5.83k
      }
1815
0
      case Kzstr: {
1816
0
        size_t len = strlen(data + pos);
1817
0
        luaL_argcheck(L, pos + len < ld, 2,
1818
0
                         "unfinished string for format 'z'");
1819
0
        lua_pushlstring(L, data + pos, len);
1820
0
        pos += len + 1;  /* skip string plus final '\0' */
1821
0
        break;
1822
5.83k
      }
1823
29.2k
      case Kpaddalign: case Kpadding: case Knop:
1824
29.2k
        n--;  /* undo increment */
1825
29.2k
        break;
1826
54.7k
    }
1827
49.0k
    pos += size;
1828
49.0k
  }
1829
651
  lua_pushinteger(L, pos + 1);  /* next position */
1830
651
  return n + 1;
1831
6.43k
}
1832
1833
/* }====================================================== */
1834
1835
1836
static const luaL_Reg strlib[] = {
1837
  {"byte", str_byte},
1838
  {"char", str_char},
1839
  {"dump", str_dump},
1840
  {"find", str_find},
1841
  {"format", str_format},
1842
  {"gmatch", gmatch},
1843
  {"gsub", str_gsub},
1844
  {"len", str_len},
1845
  {"lower", str_lower},
1846
  {"match", str_match},
1847
  {"rep", str_rep},
1848
  {"reverse", str_reverse},
1849
  {"sub", str_sub},
1850
  {"upper", str_upper},
1851
  {"pack", str_pack},
1852
  {"packsize", str_packsize},
1853
  {"unpack", str_unpack},
1854
  {NULL, NULL}
1855
};
1856
1857
1858
4.53k
static void createmetatable (lua_State *L) {
1859
  /* table to be metatable for strings */
1860
4.53k
  luaL_newlibtable(L, stringmetamethods);
1861
4.53k
  luaL_setfuncs(L, stringmetamethods, 0);
1862
4.53k
  lua_pushliteral(L, "");  /* dummy string */
1863
4.53k
  lua_pushvalue(L, -2);  /* copy table */
1864
4.53k
  lua_setmetatable(L, -2);  /* set table as metatable for strings */
1865
4.53k
  lua_pop(L, 1);  /* pop dummy string */
1866
4.53k
  lua_pushvalue(L, -2);  /* get string library */
1867
4.53k
  lua_setfield(L, -2, "__index");  /* metatable.__index = string */
1868
4.53k
  lua_pop(L, 1);  /* pop metatable */
1869
4.53k
}
1870
1871
1872
/*
1873
** Open string library
1874
*/
1875
4.53k
LUAMOD_API int luaopen_string (lua_State *L) {
1876
4.53k
  luaL_newlib(L, strlib);
1877
4.53k
  createmetatable(L);
1878
4.53k
  return 1;
1879
4.53k
}
1880