Coverage Report

Created: 2023-06-07 06:20

/src/mupdf/thirdparty/mujs/jsstring.c
Line
Count
Source (jump to first uncovered line)
1
#include "jsi.h"
2
#include "utf.h"
3
#include "regexp.h"
4
5
static int js_doregexec(js_State *J, Reprog *prog, const char *string, Resub *sub, int eflags)
6
0
{
7
0
  int result = js_regexec(prog, string, sub, eflags);
8
0
  if (result < 0)
9
0
    js_error(J, "regexec failed");
10
0
  return result;
11
0
}
12
13
static const char *checkstring(js_State *J, int idx)
14
0
{
15
0
  if (!js_iscoercible(J, idx))
16
0
    js_typeerror(J, "string function called on null or undefined");
17
0
  return js_tostring(J, idx);
18
0
}
19
20
int js_runeat(js_State *J, const char *s, int i)
21
0
{
22
0
  Rune rune = EOF;
23
0
  while (i-- >= 0) {
24
0
    rune = *(unsigned char*)s;
25
0
    if (rune < Runeself) {
26
0
      if (rune == 0)
27
0
        return EOF;
28
0
      ++s;
29
0
    } else
30
0
      s += chartorune(&rune, s);
31
0
  }
32
0
  return rune;
33
0
}
34
35
const char *js_utfidxtoptr(const char *s, int i)
36
0
{
37
0
  Rune rune;
38
0
  while (i-- > 0) {
39
0
    rune = *(unsigned char*)s;
40
0
    if (rune < Runeself) {
41
0
      if (rune == 0)
42
0
        return NULL;
43
0
      ++s;
44
0
    } else
45
0
      s += chartorune(&rune, s);
46
0
  }
47
0
  return s;
48
0
}
49
50
int js_utfptrtoidx(const char *s, const char *p)
51
0
{
52
0
  Rune rune;
53
0
  int i = 0;
54
0
  while (s < p) {
55
0
    if (*(unsigned char *)s < Runeself)
56
0
      ++s;
57
0
    else
58
0
      s += chartorune(&rune, s);
59
0
    ++i;
60
0
  }
61
0
  return i;
62
0
}
63
64
static void jsB_new_String(js_State *J)
65
0
{
66
0
  js_newstring(J, js_gettop(J) > 1 ? js_tostring(J, 1) : "");
67
0
}
68
69
static void jsB_String(js_State *J)
70
0
{
71
0
  js_pushstring(J, js_gettop(J) > 1 ? js_tostring(J, 1) : "");
72
0
}
73
74
static void Sp_toString(js_State *J)
75
0
{
76
0
  js_Object *self = js_toobject(J, 0);
77
0
  if (self->type != JS_CSTRING) js_typeerror(J, "not a string");
78
0
  js_pushstring(J, self->u.s.string);
79
0
}
80
81
static void Sp_valueOf(js_State *J)
82
0
{
83
0
  js_Object *self = js_toobject(J, 0);
84
0
  if (self->type != JS_CSTRING) js_typeerror(J, "not a string");
85
0
  js_pushstring(J, self->u.s.string);
86
0
}
87
88
static void Sp_charAt(js_State *J)
89
0
{
90
0
  char buf[UTFmax + 1];
91
0
  const char *s = checkstring(J, 0);
92
0
  int pos = js_tointeger(J, 1);
93
0
  Rune rune = js_runeat(J, s, pos);
94
0
  if (rune >= 0) {
95
0
    buf[runetochar(buf, &rune)] = 0;
96
0
    js_pushstring(J, buf);
97
0
  } else {
98
0
    js_pushliteral(J, "");
99
0
  }
100
0
}
101
102
static void Sp_charCodeAt(js_State *J)
103
0
{
104
0
  const char *s = checkstring(J, 0);
105
0
  int pos = js_tointeger(J, 1);
106
0
  Rune rune = js_runeat(J, s, pos);
107
0
  if (rune >= 0)
108
0
    js_pushnumber(J, rune);
109
0
  else
110
0
    js_pushnumber(J, NAN);
111
0
}
112
113
static void Sp_concat(js_State *J)
114
0
{
115
0
  int i, top = js_gettop(J);
116
0
  int n;
117
0
  char * volatile out = NULL;
118
0
  const char *s;
119
120
0
  if (top == 1)
121
0
    return;
122
123
0
  s = checkstring(J, 0);
124
0
  n = 1 + strlen(s);
125
126
0
  if (js_try(J)) {
127
0
    js_free(J, out);
128
0
    js_throw(J);
129
0
  }
130
131
0
  if (n > JS_STRLIMIT)
132
0
    js_rangeerror(J, "invalid string length");
133
0
  out = js_malloc(J, n);
134
0
  strcpy(out, s);
135
136
0
  for (i = 1; i < top; ++i) {
137
0
    s = js_tostring(J, i);
138
0
    n += strlen(s);
139
0
    if (n > JS_STRLIMIT)
140
0
      js_rangeerror(J, "invalid string length");
141
0
    out = js_realloc(J, out, n);
142
0
    strcat(out, s);
143
0
  }
144
145
0
  js_pushstring(J, out);
146
0
  js_endtry(J);
147
0
  js_free(J, out);
148
0
}
149
150
static void Sp_indexOf(js_State *J)
151
0
{
152
0
  const char *haystack = checkstring(J, 0);
153
0
  const char *needle = js_tostring(J, 1);
154
0
  int pos = js_tointeger(J, 2);
155
0
  int len = strlen(needle);
156
0
  int k = 0;
157
0
  Rune rune;
158
0
  while (*haystack) {
159
0
    if (k >= pos && !strncmp(haystack, needle, len)) {
160
0
      js_pushnumber(J, k);
161
0
      return;
162
0
    }
163
0
    haystack += chartorune(&rune, haystack);
164
0
    ++k;
165
0
  }
166
0
  js_pushnumber(J, -1);
167
0
}
168
169
static void Sp_lastIndexOf(js_State *J)
170
0
{
171
0
  const char *haystack = checkstring(J, 0);
172
0
  const char *needle = js_tostring(J, 1);
173
0
  int pos = js_isdefined(J, 2) ? js_tointeger(J, 2) : (int)strlen(haystack);
174
0
  int len = strlen(needle);
175
0
  int k = 0, last = -1;
176
0
  Rune rune;
177
0
  while (*haystack && k <= pos) {
178
0
    if (!strncmp(haystack, needle, len))
179
0
      last = k;
180
0
    haystack += chartorune(&rune, haystack);
181
0
    ++k;
182
0
  }
183
0
  js_pushnumber(J, last);
184
0
}
185
186
static void Sp_localeCompare(js_State *J)
187
0
{
188
0
  const char *a = checkstring(J, 0);
189
0
  const char *b = js_tostring(J, 1);
190
0
  js_pushnumber(J, strcmp(a, b));
191
0
}
192
193
static void Sp_slice(js_State *J)
194
0
{
195
0
  const char *str = checkstring(J, 0);
196
0
  const char *ss, *ee;
197
0
  int len = utflen(str);
198
0
  int s = js_tointeger(J, 1);
199
0
  int e = js_isdefined(J, 2) ? js_tointeger(J, 2) : len;
200
201
0
  s = s < 0 ? s + len : s;
202
0
  e = e < 0 ? e + len : e;
203
204
0
  s = s < 0 ? 0 : s > len ? len : s;
205
0
  e = e < 0 ? 0 : e > len ? len : e;
206
207
0
  if (s < e) {
208
0
    ss = js_utfidxtoptr(str, s);
209
0
    ee = js_utfidxtoptr(ss, e - s);
210
0
  } else {
211
0
    ss = js_utfidxtoptr(str, e);
212
0
    ee = js_utfidxtoptr(ss, s - e);
213
0
  }
214
215
0
  js_pushlstring(J, ss, ee - ss);
216
0
}
217
218
static void Sp_substring(js_State *J)
219
0
{
220
0
  const char *str = checkstring(J, 0);
221
0
  const char *ss, *ee;
222
0
  int len = utflen(str);
223
0
  int s = js_tointeger(J, 1);
224
0
  int e = js_isdefined(J, 2) ? js_tointeger(J, 2) : len;
225
226
0
  s = s < 0 ? 0 : s > len ? len : s;
227
0
  e = e < 0 ? 0 : e > len ? len : e;
228
229
0
  if (s < e) {
230
0
    ss = js_utfidxtoptr(str, s);
231
0
    ee = js_utfidxtoptr(ss, e - s);
232
0
  } else {
233
0
    ss = js_utfidxtoptr(str, e);
234
0
    ee = js_utfidxtoptr(ss, s - e);
235
0
  }
236
237
0
  js_pushlstring(J, ss, ee - ss);
238
0
}
239
240
static void Sp_toLowerCase(js_State *J)
241
0
{
242
0
  const char *s = checkstring(J, 0);
243
0
  char * volatile dst = NULL;
244
0
  char *d;
245
0
  Rune rune;
246
247
0
  if (js_try(J)) {
248
0
    js_free(J, dst);
249
0
    js_throw(J);
250
0
  }
251
252
0
  d = dst = js_malloc(J, UTFmax * strlen(s) + 1);
253
0
  while (*s) {
254
0
    s += chartorune(&rune, s);
255
0
    rune = tolowerrune(rune);
256
0
    d += runetochar(d, &rune);
257
0
  }
258
0
  *d = 0;
259
260
0
  js_pushstring(J, dst);
261
0
  js_endtry(J);
262
0
  js_free(J, dst);
263
0
}
264
265
static void Sp_toUpperCase(js_State *J)
266
0
{
267
0
  const char *s = checkstring(J, 0);
268
0
  char * volatile dst = NULL;
269
0
  char *d;
270
0
  Rune rune;
271
272
0
  if (js_try(J)) {
273
0
    js_free(J, dst);
274
0
    js_throw(J);
275
0
  }
276
277
0
  d = dst = js_malloc(J, UTFmax * strlen(s) + 1);
278
0
  while (*s) {
279
0
    s += chartorune(&rune, s);
280
0
    rune = toupperrune(rune);
281
0
    d += runetochar(d, &rune);
282
0
  }
283
0
  *d = 0;
284
285
0
  js_pushstring(J, dst);
286
0
  js_endtry(J);
287
0
  js_free(J, dst);
288
0
}
289
290
static int istrim(int c)
291
0
{
292
0
  return c == 0x9 || c == 0xB || c == 0xC || c == 0x20 || c == 0xA0 || c == 0xFEFF ||
293
0
    c == 0xA || c == 0xD || c == 0x2028 || c == 0x2029;
294
0
}
295
296
static void Sp_trim(js_State *J)
297
0
{
298
0
  const char *s, *e;
299
0
  s = checkstring(J, 0);
300
0
  while (istrim(*s))
301
0
    ++s;
302
0
  e = s + strlen(s);
303
0
  while (e > s && istrim(e[-1]))
304
0
    --e;
305
0
  js_pushlstring(J, s, e - s);
306
0
}
307
308
static void S_fromCharCode(js_State *J)
309
0
{
310
0
  int i, top = js_gettop(J);
311
0
  char * volatile s = NULL;
312
0
  char *p;
313
0
  Rune c;
314
315
0
  if (js_try(J)) {
316
0
    js_free(J, s);
317
0
    js_throw(J);
318
0
  }
319
320
0
  s = p = js_malloc(J, (top-1) * UTFmax + 1);
321
322
0
  for (i = 1; i < top; ++i) {
323
0
    c = js_touint32(J, i);
324
0
    p += runetochar(p, &c);
325
0
  }
326
0
  *p = 0;
327
328
0
  js_pushstring(J, s);
329
0
  js_endtry(J);
330
0
  js_free(J, s);
331
0
}
332
333
static void Sp_match(js_State *J)
334
0
{
335
0
  js_Regexp *re;
336
0
  const char *text;
337
0
  int len;
338
0
  const char *a, *b, *c, *e;
339
0
  Resub m;
340
341
0
  text = checkstring(J, 0);
342
343
0
  if (js_isregexp(J, 1))
344
0
    js_copy(J, 1);
345
0
  else if (js_isundefined(J, 1))
346
0
    js_newregexp(J, "", 0);
347
0
  else
348
0
    js_newregexp(J, js_tostring(J, 1), 0);
349
350
0
  re = js_toregexp(J, -1);
351
0
  if (!(re->flags & JS_REGEXP_G)) {
352
0
    js_RegExp_prototype_exec(J, re, text);
353
0
    return;
354
0
  }
355
356
0
  re->last = 0;
357
358
0
  js_newarray(J);
359
360
0
  len = 0;
361
0
  a = text;
362
0
  e = text + strlen(text);
363
0
  while (a <= e) {
364
0
    if (js_doregexec(J, re->prog, a, &m, a > text ? REG_NOTBOL : 0))
365
0
      break;
366
367
0
    b = m.sub[0].sp;
368
0
    c = m.sub[0].ep;
369
370
0
    js_pushlstring(J, b, c - b);
371
0
    js_setindex(J, -2, len++);
372
373
0
    a = c;
374
0
    if (c - b == 0)
375
0
      ++a;
376
0
  }
377
378
0
  if (len == 0) {
379
0
    js_pop(J, 1);
380
0
    js_pushnull(J);
381
0
  }
382
0
}
383
384
static void Sp_search(js_State *J)
385
0
{
386
0
  js_Regexp *re;
387
0
  const char *text;
388
0
  Resub m;
389
390
0
  text = checkstring(J, 0);
391
392
0
  if (js_isregexp(J, 1))
393
0
    js_copy(J, 1);
394
0
  else if (js_isundefined(J, 1))
395
0
    js_newregexp(J, "", 0);
396
0
  else
397
0
    js_newregexp(J, js_tostring(J, 1), 0);
398
399
0
  re = js_toregexp(J, -1);
400
401
0
  if (!js_doregexec(J, re->prog, text, &m, 0))
402
0
    js_pushnumber(J, js_utfptrtoidx(text, m.sub[0].sp));
403
0
  else
404
0
    js_pushnumber(J, -1);
405
0
}
406
407
static void Sp_replace_regexp(js_State *J)
408
0
{
409
0
  js_Regexp *re;
410
0
  const char *source, *s, *r;
411
0
  js_Buffer *sb = NULL;
412
0
  int n, x;
413
0
  Resub m;
414
415
0
  source = checkstring(J, 0);
416
0
  re = js_toregexp(J, 1);
417
418
0
  if (js_doregexec(J, re->prog, source, &m, 0)) {
419
0
    js_copy(J, 0);
420
0
    return;
421
0
  }
422
423
0
  re->last = 0;
424
425
0
loop:
426
0
  s = m.sub[0].sp;
427
0
  n = m.sub[0].ep - m.sub[0].sp;
428
429
0
  if (js_iscallable(J, 2)) {
430
0
    js_copy(J, 2);
431
0
    js_pushundefined(J);
432
0
    for (x = 0; m.sub[x].sp; ++x) /* arg 0..x: substring and subexps that matched */
433
0
      js_pushlstring(J, m.sub[x].sp, m.sub[x].ep - m.sub[x].sp);
434
0
    js_pushnumber(J, s - source); /* arg x+2: offset within search string */
435
0
    js_copy(J, 0); /* arg x+3: search string */
436
0
    js_call(J, 2 + x);
437
0
    r = js_tostring(J, -1);
438
0
    js_putm(J, &sb, source, s);
439
0
    js_puts(J, &sb, r);
440
0
    js_pop(J, 1);
441
0
  } else {
442
0
    r = js_tostring(J, 2);
443
0
    js_putm(J, &sb, source, s);
444
0
    while (*r) {
445
0
      if (*r == '$') {
446
0
        switch (*(++r)) {
447
0
        case 0: --r; /* end of string; back up */
448
        /* fallthrough */
449
0
        case '$': js_putc(J, &sb, '$'); break;
450
0
        case '`': js_putm(J, &sb, source, s); break;
451
0
        case '\'': js_puts(J, &sb, s + n); break;
452
0
        case '&':
453
0
          js_putm(J, &sb, s, s + n);
454
0
          break;
455
0
        case '0': case '1': case '2': case '3': case '4':
456
0
        case '5': case '6': case '7': case '8': case '9':
457
0
          x = *r - '0';
458
0
          if (r[1] >= '0' && r[1] <= '9')
459
0
            x = x * 10 + *(++r) - '0';
460
0
          if (x > 0 && x < m.nsub) {
461
0
            js_putm(J, &sb, m.sub[x].sp, m.sub[x].ep);
462
0
          } else {
463
0
            js_putc(J, &sb, '$');
464
0
            if (x > 10) {
465
0
              js_putc(J, &sb, '0' + x / 10);
466
0
              js_putc(J, &sb, '0' + x % 10);
467
0
            } else {
468
0
              js_putc(J, &sb, '0' + x);
469
0
            }
470
0
          }
471
0
          break;
472
0
        default:
473
0
          js_putc(J, &sb, '$');
474
0
          js_putc(J, &sb, *r);
475
0
          break;
476
0
        }
477
0
        ++r;
478
0
      } else {
479
0
        js_putc(J, &sb, *r++);
480
0
      }
481
0
    }
482
0
  }
483
484
0
  if (re->flags & JS_REGEXP_G) {
485
0
    source = m.sub[0].ep;
486
0
    if (n == 0) {
487
0
      if (*source)
488
0
        js_putc(J, &sb, *source++);
489
0
      else
490
0
        goto end;
491
0
    }
492
0
    if (!js_doregexec(J, re->prog, source, &m, REG_NOTBOL))
493
0
      goto loop;
494
0
  }
495
496
0
end:
497
0
  js_puts(J, &sb, s + n);
498
0
  js_putc(J, &sb, 0);
499
500
0
  if (js_try(J)) {
501
0
    js_free(J, sb);
502
0
    js_throw(J);
503
0
  }
504
0
  js_pushstring(J, sb ? sb->s : "");
505
0
  js_endtry(J);
506
0
  js_free(J, sb);
507
0
}
508
509
static void Sp_replace_string(js_State *J)
510
0
{
511
0
  const char *source, *needle, *s, *r;
512
0
  js_Buffer *sb = NULL;
513
0
  int n;
514
515
0
  source = checkstring(J, 0);
516
0
  needle = js_tostring(J, 1);
517
518
0
  s = strstr(source, needle);
519
0
  if (!s) {
520
0
    js_copy(J, 0);
521
0
    return;
522
0
  }
523
0
  n = strlen(needle);
524
525
0
  if (js_iscallable(J, 2)) {
526
0
    js_copy(J, 2);
527
0
    js_pushundefined(J);
528
0
    js_pushlstring(J, s, n); /* arg 1: substring that matched */
529
0
    js_pushnumber(J, s - source); /* arg 2: offset within search string */
530
0
    js_copy(J, 0); /* arg 3: search string */
531
0
    js_call(J, 3);
532
0
    r = js_tostring(J, -1);
533
0
    js_putm(J, &sb, source, s);
534
0
    js_puts(J, &sb, r);
535
0
    js_puts(J, &sb, s + n);
536
0
    js_putc(J, &sb, 0);
537
0
    js_pop(J, 1);
538
0
  } else {
539
0
    r = js_tostring(J, 2);
540
0
    js_putm(J, &sb, source, s);
541
0
    while (*r) {
542
0
      if (*r == '$') {
543
0
        switch (*(++r)) {
544
0
        case 0: --r; /* end of string; back up */
545
        /* fallthrough */
546
0
        case '$': js_putc(J, &sb, '$'); break;
547
0
        case '&': js_putm(J, &sb, s, s + n); break;
548
0
        case '`': js_putm(J, &sb, source, s); break;
549
0
        case '\'': js_puts(J, &sb, s + n); break;
550
0
        default: js_putc(J, &sb, '$'); js_putc(J, &sb, *r); break;
551
0
        }
552
0
        ++r;
553
0
      } else {
554
0
        js_putc(J, &sb, *r++);
555
0
      }
556
0
    }
557
0
    js_puts(J, &sb, s + n);
558
0
    js_putc(J, &sb, 0);
559
0
  }
560
561
0
  if (js_try(J)) {
562
0
    js_free(J, sb);
563
0
    js_throw(J);
564
0
  }
565
0
  js_pushstring(J, sb ? sb->s : "");
566
0
  js_endtry(J);
567
0
  js_free(J, sb);
568
0
}
569
570
static void Sp_replace(js_State *J)
571
0
{
572
0
  if (js_isregexp(J, 1))
573
0
    Sp_replace_regexp(J);
574
0
  else
575
0
    Sp_replace_string(J);
576
0
}
577
578
static void Sp_split_regexp(js_State *J)
579
0
{
580
0
  js_Regexp *re;
581
0
  const char *text;
582
0
  int limit, len, k;
583
0
  const char *p, *a, *b, *c, *e;
584
0
  Resub m;
585
586
0
  text = checkstring(J, 0);
587
0
  re = js_toregexp(J, 1);
588
0
  limit = js_isdefined(J, 2) ? js_tointeger(J, 2) : 1 << 30;
589
590
0
  js_newarray(J);
591
0
  len = 0;
592
593
0
  e = text + strlen(text);
594
595
  /* splitting the empty string */
596
0
  if (e == text) {
597
0
    if (js_doregexec(J, re->prog, text, &m, 0)) {
598
0
      if (len == limit) return;
599
0
      js_pushliteral(J, "");
600
0
      js_setindex(J, -2, 0);
601
0
    }
602
0
    return;
603
0
  }
604
605
0
  p = a = text;
606
0
  while (a < e) {
607
0
    if (js_doregexec(J, re->prog, a, &m, a > text ? REG_NOTBOL : 0))
608
0
      break; /* no match */
609
610
0
    b = m.sub[0].sp;
611
0
    c = m.sub[0].ep;
612
613
    /* empty string at end of last match */
614
0
    if (b == p) {
615
0
      ++a;
616
0
      continue;
617
0
    }
618
619
0
    if (len == limit) return;
620
0
    js_pushlstring(J, p, b - p);
621
0
    js_setindex(J, -2, len++);
622
623
0
    for (k = 1; k < m.nsub; ++k) {
624
0
      if (len == limit) return;
625
0
      js_pushlstring(J, m.sub[k].sp, m.sub[k].ep - m.sub[k].sp);
626
0
      js_setindex(J, -2, len++);
627
0
    }
628
629
0
    a = p = c;
630
0
  }
631
632
0
  if (len == limit) return;
633
0
  js_pushstring(J, p);
634
0
  js_setindex(J, -2, len);
635
0
}
636
637
static void Sp_split_string(js_State *J)
638
0
{
639
0
  const char *str = checkstring(J, 0);
640
0
  const char *sep = js_tostring(J, 1);
641
0
  int limit = js_isdefined(J, 2) ? js_tointeger(J, 2) : 1 << 30;
642
0
  int i, n;
643
644
0
  js_newarray(J);
645
646
0
  n = strlen(sep);
647
648
  /* empty string */
649
0
  if (n == 0) {
650
0
    Rune rune;
651
0
    for (i = 0; *str && i < limit; ++i) {
652
0
      n = chartorune(&rune, str);
653
0
      js_pushlstring(J, str, n);
654
0
      js_setindex(J, -2, i);
655
0
      str += n;
656
0
    }
657
0
    return;
658
0
  }
659
660
0
  for (i = 0; str && i < limit; ++i) {
661
0
    const char *s = strstr(str, sep);
662
0
    if (s) {
663
0
      js_pushlstring(J, str, s-str);
664
0
      js_setindex(J, -2, i);
665
0
      str = s + n;
666
0
    } else {
667
0
      js_pushstring(J, str);
668
0
      js_setindex(J, -2, i);
669
0
      str = NULL;
670
0
    }
671
0
  }
672
0
}
673
674
static void Sp_split(js_State *J)
675
0
{
676
0
  if (js_isundefined(J, 1)) {
677
0
    js_newarray(J);
678
0
    js_pushstring(J, js_tostring(J, 0));
679
0
    js_setindex(J, -2, 0);
680
0
  } else if (js_isregexp(J, 1)) {
681
0
    Sp_split_regexp(J);
682
0
  } else {
683
0
    Sp_split_string(J);
684
0
  }
685
0
}
686
687
void jsB_initstring(js_State *J)
688
0
{
689
0
  J->String_prototype->u.s.shrstr[0] = 0;
690
0
  J->String_prototype->u.s.string = J->String_prototype->u.s.shrstr;
691
0
  J->String_prototype->u.s.length = 0;
692
693
0
  js_pushobject(J, J->String_prototype);
694
0
  {
695
0
    jsB_propf(J, "String.prototype.toString", Sp_toString, 0);
696
0
    jsB_propf(J, "String.prototype.valueOf", Sp_valueOf, 0);
697
0
    jsB_propf(J, "String.prototype.charAt", Sp_charAt, 1);
698
0
    jsB_propf(J, "String.prototype.charCodeAt", Sp_charCodeAt, 1);
699
0
    jsB_propf(J, "String.prototype.concat", Sp_concat, 0); /* 1 */
700
0
    jsB_propf(J, "String.prototype.indexOf", Sp_indexOf, 1);
701
0
    jsB_propf(J, "String.prototype.lastIndexOf", Sp_lastIndexOf, 1);
702
0
    jsB_propf(J, "String.prototype.localeCompare", Sp_localeCompare, 1);
703
0
    jsB_propf(J, "String.prototype.match", Sp_match, 1);
704
0
    jsB_propf(J, "String.prototype.replace", Sp_replace, 2);
705
0
    jsB_propf(J, "String.prototype.search", Sp_search, 1);
706
0
    jsB_propf(J, "String.prototype.slice", Sp_slice, 2);
707
0
    jsB_propf(J, "String.prototype.split", Sp_split, 2);
708
0
    jsB_propf(J, "String.prototype.substring", Sp_substring, 2);
709
0
    jsB_propf(J, "String.prototype.toLowerCase", Sp_toLowerCase, 0);
710
0
    jsB_propf(J, "String.prototype.toLocaleLowerCase", Sp_toLowerCase, 0);
711
0
    jsB_propf(J, "String.prototype.toUpperCase", Sp_toUpperCase, 0);
712
0
    jsB_propf(J, "String.prototype.toLocaleUpperCase", Sp_toUpperCase, 0);
713
714
    /* ES5 */
715
0
    jsB_propf(J, "String.prototype.trim", Sp_trim, 0);
716
0
  }
717
0
  js_newcconstructor(J, jsB_String, jsB_new_String, "String", 0); /* 1 */
718
0
  {
719
0
    jsB_propf(J, "String.fromCharCode", S_fromCharCode, 0); /* 1 */
720
0
  }
721
0
  js_defglobal(J, "String", JS_DONTENUM);
722
0
}