Coverage Report

Created: 2026-03-11 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpac/src/bifs/script_dec.c
Line
Count
Source
1
/*
2
 *      GPAC - Multimedia Framework C SDK
3
 *
4
 *      Authors: Jean Le Feuvre
5
 *      Copyright (c) Telecom ParisTech 2000-2012
6
 *          All rights reserved
7
 *
8
 *  This file is part of GPAC / BIFS codec sub-project
9
 *
10
 *  GPAC is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU Lesser General Public License as published by
12
 *  the Free Software Foundation; either version 2, or (at your option)
13
 *  any later version.
14
 *
15
 *  GPAC is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU Lesser General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU Lesser General Public
21
 *  License along with this library; see the file COPYING.  If not, write to
22
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
 *
24
 */
25
26
27
#include "script.h"
28
29
#if !defined(GPAC_DISABLE_BIFS) && defined(GPAC_HAS_QJS)
30
31
#define BINOP_MINVAL ET_EQ
32
33
typedef struct
34
{
35
  GF_Node *script;
36
  GF_BifsDecoder *codec;
37
  GF_BitStream *bs;
38
  char *string;
39
  u32 length;
40
  GF_List *identifiers;
41
  char *new_line;
42
  u32 indent;
43
  u32 expr_stack_size;
44
} ScriptParser;
45
46
47
void SFS_Identifier(ScriptParser *parser);
48
void SFS_Arguments(ScriptParser *parser, Bool is_var);
49
void SFS_StatementBlock(ScriptParser *parser, Bool functBody);
50
void SFS_Statement(ScriptParser *parser);
51
void SFS_IfStatement(ScriptParser *parser);
52
void SFS_SwitchStatement(ScriptParser *parser);
53
void SFS_ForStatement(ScriptParser *parser);
54
void SFS_WhileStatement(ScriptParser *parser);
55
void SFS_ReturnStatement(ScriptParser *parser);
56
void SFS_CompoundExpression(ScriptParser *parser);
57
void SFS_OptionalExpression(ScriptParser *parser);
58
void SFS_Expression(ScriptParser *parser);
59
void SFS_NewObject(ScriptParser *parser);
60
void SFS_ArrayDeref(ScriptParser *parser);
61
void SFS_FunctionCall(ScriptParser *parser);
62
void SFS_ObjectMemberAccess(ScriptParser *parser);
63
void SFS_ObjectMethodCall(ScriptParser *parser);
64
void SFS_Params(ScriptParser *parser);
65
void SFS_GetNumber(ScriptParser *parser);
66
void SFS_GetString(ScriptParser *parser);
67
void SFS_GetBoolean(ScriptParser *parser);
68
69
0
#define PARSER_STEP_ALLOC 500
70
71
static void SFS_AddString(ScriptParser *parser, char *str)
72
0
{
73
0
  char *new_str;
74
0
  if (!str) return;
75
0
  if (strlen(parser->string) + strlen(str) >= parser->length) {
76
0
    parser->length = (u32) ( strlen(parser->string) + strlen(str) + PARSER_STEP_ALLOC );
77
0
    new_str = (char *)gf_malloc(sizeof(char)*parser->length);
78
0
    strcpy(new_str, parser->string);
79
0
    gf_free(parser->string);
80
0
    parser->string = new_str;
81
0
  }
82
0
  strncat(parser->string, str, parser->length - strlen(parser->string) - 1);
83
0
}
84
85
static void SFS_AddInt(ScriptParser *parser, s32 val)
86
0
{
87
0
  char msg[500];
88
0
  sprintf(msg, "%d", val);
89
0
  SFS_AddString(parser, msg);
90
0
}
91
static void SFS_AddChar(ScriptParser *parser, char c)
92
0
{
93
0
  char msg[2];
94
0
  sprintf(msg, "%c", c);
95
0
  SFS_AddString(parser, msg);
96
0
}
97
98
99
GF_Err ParseScriptField(ScriptParser *parser)
100
0
{
101
0
  GF_ScriptField *field;
102
0
  GF_Err e;
103
0
  u32 eventType, fieldType;
104
0
  char name[1000];
105
0
  GF_FieldInfo info;
106
107
0
  eventType = gf_bs_read_int(parser->bs, 2);
108
0
  fieldType = gf_bs_read_int(parser->bs, 6);
109
0
  gf_bifs_dec_name(parser->bs, name, 1000);
110
0
  field = gf_sg_script_field_new(parser->script, eventType, fieldType, name);
111
0
  if (!field) return GF_NON_COMPLIANT_BITSTREAM;
112
113
  //save the name in the list of identifiers
114
0
  gf_list_add(parser->identifiers, gf_strdup(name));
115
116
0
  if (parser->codec->pCurrentProto) {
117
0
    Bool isISfield = (Bool)gf_bs_read_int(parser->bs, 1);
118
0
    if (isISfield) {
119
0
      u32 numProtoField = gf_sg_proto_get_field_count(parser->codec->pCurrentProto);
120
0
      u32 numBits = gf_get_bit_size(numProtoField - 1);
121
0
      u32 field_all = gf_bs_read_int(parser->bs, numBits);
122
0
      e = gf_sg_script_field_get_info(field, &info);
123
0
      if (e) return e;
124
0
      e = gf_sg_proto_field_set_ised(parser->codec->pCurrentProto, field_all, parser->script, info.fieldIndex);
125
0
      return e;
126
0
    }
127
0
  }
128
  /*get default value*/
129
0
  if (eventType == GF_SG_SCRIPT_TYPE_FIELD) {
130
0
    if (gf_bs_read_int(parser->bs, 1)) {
131
0
      e = gf_sg_script_field_get_info(field, &info);
132
0
      if (e) return e;
133
0
      gf_bifs_dec_field(parser->codec, parser->bs, parser->script, &info, GF_FALSE);
134
0
    }
135
0
  }
136
137
0
  return parser->codec->LastError;
138
0
}
139
140
0
static void SFS_IncIndent(ScriptParser *pars) {
141
0
  pars->indent++;
142
0
}
143
0
static void SFS_DecIndent(ScriptParser *pars) {
144
0
  pars->indent--;
145
0
}
146
0
static void SFS_Space(ScriptParser *pars) {
147
0
  if (pars->new_line) SFS_AddString(pars, " ");
148
0
}
149
static void SFS_Indent(ScriptParser *pars)
150
0
{
151
0
  u32 i;
152
0
  if (pars->new_line) {
153
0
    for (i=0; i<pars->indent; i++) SFS_AddString(pars, " ");
154
0
  }
155
0
}
156
static GFINLINE void SFS_Line(ScriptParser *parser)
157
0
{
158
0
  if (parser->new_line) {
159
0
    SFS_AddString(parser, parser->new_line);
160
0
  }
161
0
}
162
163
164
GF_Err SFScript_Parse(GF_BifsDecoder *codec, SFScript *script_field, GF_BitStream *bs, GF_Node *n)
165
0
{
166
0
  GF_Err e;
167
0
  u32 i, count, nbBits;
168
0
  char *ptr;
169
0
  ScriptParser parser;
170
0
  e = GF_OK;
171
0
  if (gf_node_get_tag(n) != TAG_MPEG4_Script) return GF_NON_COMPLIANT_BITSTREAM;
172
173
0
  memset(&parser, 0, sizeof(ScriptParser));
174
0
  parser.codec = codec;
175
0
  parser.script = n;
176
0
  parser.bs = bs;
177
0
  parser.length = 500;
178
0
  parser.string = (char *) gf_malloc(sizeof(char)* parser.length);
179
0
  parser.string[0] = 0;
180
0
  parser.identifiers = gf_list_new();
181
0
  parser.new_line = (char *) (codec->dec_memory_mode ? "\n" : NULL);
182
0
  parser.indent = 0;
183
184
  //first parse fields
185
186
0
  if (gf_bs_read_int(bs, 1)) {
187
    //endFlag
188
0
    while (!gf_bs_read_int(bs, 1)) {
189
0
      e = ParseScriptField(&parser);
190
0
      if (e) goto exit;
191
0
    }
192
0
  } else {
193
0
    nbBits = gf_bs_read_int(bs, 4);
194
0
    count = gf_bs_read_int(bs, nbBits);
195
0
    for (i=0; i<count; i++) {
196
0
      e = ParseScriptField(&parser);
197
0
      if (e) goto exit;
198
0
    }
199
0
  }
200
  //reserevd
201
0
  gf_bs_read_int(bs, 1);
202
  //then parse
203
0
  SFS_AddString(&parser, "javascript:");
204
0
  SFS_AddString(&parser, parser.new_line);
205
206
  //hasFunction
207
0
  while (gf_bs_read_int(bs, 1)) {
208
0
    SFS_AddString(&parser, "function ");
209
0
    SFS_Identifier(&parser);
210
0
    SFS_Arguments(&parser, GF_FALSE);
211
0
    SFS_Space(&parser);
212
0
    SFS_StatementBlock(&parser, GF_TRUE);
213
0
    SFS_Line(&parser);
214
0
    if (codec->LastError) {
215
0
      e = codec->LastError;
216
0
      goto exit;
217
0
    }
218
0
  }
219
220
0
  SFS_Line(&parser);
221
222
0
  if (script_field->script_text) gf_free(script_field->script_text);
223
0
  script_field->script_text = (char *) gf_strdup(parser.string);
224
225
0
exit:
226
  //clean up
227
0
  while (gf_list_count(parser.identifiers)) {
228
0
    ptr = (char *)gf_list_get(parser.identifiers, 0);
229
0
    gf_free(ptr);
230
0
    gf_list_rem(parser.identifiers, 0);
231
0
  }
232
0
  gf_list_del(parser.identifiers);
233
0
  if (parser.string) gf_free(parser.string);
234
0
  return e;
235
0
}
236
237
238
239
void SFS_Identifier(ScriptParser *parser)
240
0
{
241
0
  u32 index;
242
0
  char name[500];
243
244
0
  if (parser->codec->LastError) return;
245
246
  //received
247
0
  if (gf_bs_read_int(parser->bs, 1)) {
248
0
    index = gf_bs_read_int(parser->bs, gf_get_bit_size(gf_list_count(parser->identifiers) - 1));
249
0
    SFS_AddString(parser, (char *)gf_list_get(parser->identifiers, index));
250
0
  }
251
  //parse
252
0
  else {
253
0
    gf_bifs_dec_name(parser->bs, name, 500);
254
0
    gf_list_add(parser->identifiers, gf_strdup(name));
255
0
    SFS_AddString(parser, name);
256
0
  }
257
0
}
258
259
void SFS_Arguments(ScriptParser *parser, Bool is_var)
260
0
{
261
0
  u32 val;
262
0
  if (parser->codec->LastError) return;
263
0
  if (!is_var) SFS_AddString(parser, "(");
264
265
0
  val = gf_bs_read_int(parser->bs, 1);
266
0
  while (val) {
267
0
    SFS_Identifier(parser);
268
0
    val = gf_bs_read_int(parser->bs, 1);
269
0
    if (val) SFS_AddString(parser, ",");
270
0
  }
271
0
  if (!is_var) SFS_AddString(parser, ")");
272
0
}
273
274
void SFS_StatementBlock(ScriptParser *parser, Bool funcBody)
275
0
{
276
0
  if (parser->codec->LastError) return;
277
278
0
  if (gf_bs_read_int(parser->bs, 1)) {
279
0
    SFS_AddString(parser, "{");
280
0
    SFS_IncIndent(parser);
281
282
0
    while (gf_bs_read_int(parser->bs, 1)) {
283
0
      SFS_Line(parser);
284
0
      SFS_Indent(parser);
285
0
      SFS_Statement(parser);
286
0
    }
287
0
    SFS_DecIndent(parser);
288
0
    SFS_Line(parser);
289
0
    SFS_Indent(parser);
290
0
    SFS_AddString(parser, "}");
291
0
  } else if (funcBody) {
292
0
    SFS_AddString(parser, "{");
293
0
    SFS_Statement(parser);
294
0
    SFS_AddString(parser, "}");
295
0
  } else {
296
0
    SFS_Statement(parser);
297
0
  }
298
0
}
299
300
301
void SFS_Statement(ScriptParser *parser)
302
0
{
303
0
  u32 val;
304
0
  if (parser->codec->LastError) return;
305
306
0
  val = gf_bs_read_int(parser->bs, NUMBITS_STATEMENT);
307
0
  switch (val) {
308
0
  case ST_IF:
309
0
    SFS_IfStatement(parser);
310
0
    break;
311
0
  case ST_FOR:
312
0
    SFS_ForStatement(parser);
313
0
    break;
314
0
  case ST_WHILE:
315
0
    SFS_WhileStatement(parser);
316
0
    break;
317
0
  case ST_RETURN:
318
0
    SFS_ReturnStatement(parser);
319
0
    break;
320
0
  case ST_BREAK:
321
0
    SFS_AddString(parser, "break;");
322
0
    break;
323
0
  case ST_CONTINUE:
324
0
    SFS_AddString(parser, "continue;");
325
0
    break;
326
0
  case ST_COMPOUND_EXPR:
327
0
    SFS_CompoundExpression(parser);
328
0
    SFS_AddString(parser, ";");
329
0
    break;
330
0
  case ST_SWITCH:
331
0
    SFS_SwitchStatement(parser);
332
0
    break;
333
0
  }
334
0
}
335
336
void SFS_IfStatement(ScriptParser *parser)
337
0
{
338
0
  if (parser->codec->LastError) return;
339
0
  SFS_AddString(parser, "if (");
340
0
  SFS_CompoundExpression(parser);
341
0
  SFS_AddString(parser, ") ");
342
0
  SFS_StatementBlock(parser, GF_FALSE);
343
  //has else
344
0
  if (gf_bs_read_int(parser->bs, 1)) {
345
0
    SFS_Line(parser);
346
0
    SFS_Indent(parser);
347
0
    SFS_AddString(parser, "else ");
348
0
    SFS_StatementBlock(parser, GF_FALSE);
349
0
  }
350
0
}
351
352
void SFS_SwitchStatement(ScriptParser *parser)
353
0
{
354
0
  u32 numBits, caseValue;
355
356
0
  if (parser->codec->LastError) return;
357
0
  SFS_AddString(parser, "switch (");
358
0
  SFS_CompoundExpression(parser);
359
0
  SFS_AddString(parser, ")");
360
0
  SFS_AddString(parser, "{");
361
0
  SFS_Line(parser);
362
363
0
  numBits = gf_bs_read_int(parser->bs, 5);
364
0
  do {
365
0
    SFS_Indent(parser);
366
0
    SFS_AddString(parser, "case ");
367
0
    caseValue = gf_bs_read_int(parser->bs, numBits);
368
0
    SFS_AddInt(parser, caseValue);
369
0
    SFS_AddString(parser, ":");
370
0
    SFS_Line(parser);
371
0
    SFS_Indent(parser);
372
0
    SFS_StatementBlock(parser, GF_FALSE);
373
0
    SFS_Line(parser);
374
0
  }
375
0
  while (gf_bs_read_int(parser->bs, 1));
376
377
  //default
378
0
  if (gf_bs_read_int(parser->bs, 1)) {
379
0
    SFS_AddString(parser, "default:");
380
0
    SFS_Line(parser);
381
0
    SFS_StatementBlock(parser, GF_FALSE);
382
0
  }
383
0
  SFS_AddString(parser, "}");
384
0
}
385
386
void SFS_ForStatement(ScriptParser *parser)
387
0
{
388
0
  if (parser->codec->LastError) return;
389
0
  SFS_AddString(parser, "for (");
390
0
  SFS_OptionalExpression(parser);
391
0
  SFS_AddString(parser, ";");
392
0
  SFS_OptionalExpression(parser);
393
0
  SFS_AddString(parser, ";");
394
0
  SFS_OptionalExpression(parser);
395
0
  SFS_AddString(parser, ")");
396
397
0
  SFS_StatementBlock(parser, GF_FALSE);
398
0
}
399
400
void SFS_WhileStatement(ScriptParser *parser)
401
0
{
402
0
  if (parser->codec->LastError) return;
403
0
  SFS_AddString(parser, "while (");
404
0
  SFS_CompoundExpression(parser);
405
0
  SFS_AddString(parser, ")");
406
407
0
  SFS_StatementBlock(parser, GF_FALSE);
408
0
}
409
410
void SFS_ReturnStatement(ScriptParser *parser)
411
0
{
412
0
  if (parser->codec->LastError) return;
413
0
  SFS_AddString(parser, "return");
414
0
  if (gf_bs_read_int(parser->bs, 1)) {
415
0
    SFS_AddString(parser, " ");
416
0
    SFS_CompoundExpression(parser);
417
0
  }
418
0
  SFS_AddString(parser, ";");
419
0
  SFS_Line(parser);
420
0
}
421
422
void SFS_CompoundExpression(ScriptParser *parser)
423
0
{
424
0
  if (parser->codec->LastError) return;
425
0
  SFS_Expression(parser);
426
0
  if (! gf_bs_read_int(parser->bs, 1)) return;
427
0
  if (parser->codec->LastError) return;
428
0
  SFS_AddString(parser, ",");
429
0
  SFS_CompoundExpression(parser);
430
0
}
431
432
void SFS_OptionalExpression(ScriptParser *parser)
433
0
{
434
0
  if (parser->codec->LastError) return;
435
0
  if (gf_bs_read_int(parser->bs, 1)) {
436
0
    SFS_CompoundExpression(parser);
437
0
  }
438
0
}
439
440
0
#define MAX_EXPR_STACK  500
441
void SFS_Expression(ScriptParser *parser)
442
0
{
443
0
  u32 val = gf_bs_read_int(parser->bs, NUMBITS_EXPR_TYPE);
444
0
  if (parser->codec->LastError) return;
445
446
  //limit max expression stack size
447
0
  parser->expr_stack_size++;
448
0
  if (parser->expr_stack_size>MAX_EXPR_STACK) {
449
0
    GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Max stack size %d reached for expressions, not supported\n", MAX_EXPR_STACK))
450
0
    parser->codec->LastError = GF_NON_COMPLIANT_BITSTREAM;
451
0
    return;
452
0
  }
453
454
0
  switch(val) {
455
0
  case ET_CURVED_EXPR:
456
0
    SFS_AddString(parser, "(");
457
0
    SFS_CompoundExpression(parser);
458
0
    SFS_AddString(parser, ")");
459
0
    break;
460
0
  case ET_NEGATIVE:
461
0
    SFS_AddString(parser, "-");
462
0
    SFS_Expression(parser);
463
0
    break;
464
0
  case ET_NOT:
465
0
    SFS_AddString(parser, "!");
466
0
    SFS_Expression(parser);
467
0
    break;
468
0
  case ET_ONESCOMP:
469
0
    SFS_AddString(parser, "~");
470
0
    SFS_Expression(parser);
471
0
    break;
472
0
  case ET_INCREMENT:
473
0
    SFS_AddString(parser, "++");
474
0
    SFS_Expression(parser);
475
0
    break;
476
0
  case ET_DECREMENT:
477
0
    SFS_AddString(parser, "--");
478
0
    SFS_Expression(parser);
479
0
    break;
480
0
  case ET_POST_INCREMENT:
481
0
    SFS_Expression(parser);
482
0
    SFS_AddString(parser, "++");
483
0
    break;
484
0
  case ET_POST_DECREMENT:
485
0
    SFS_Expression(parser);
486
0
    SFS_AddString(parser, "--");
487
0
    break;
488
0
  case ET_CONDTEST:
489
0
    SFS_Expression(parser);
490
0
    SFS_AddString(parser, " ? ");
491
0
    SFS_Expression(parser);
492
0
    SFS_AddString(parser, " : ");
493
0
    SFS_Expression(parser);
494
0
    break;
495
0
  case ET_STRING:
496
0
    SFS_AddString(parser, "'");
497
0
    SFS_GetString(parser);
498
0
    SFS_AddString(parser, "'");
499
0
    break;
500
0
  case ET_NUMBER:
501
0
    SFS_GetNumber(parser);
502
0
    break;
503
0
  case ET_IDENTIFIER:
504
0
    SFS_Identifier(parser);
505
0
    break;
506
0
  case ET_FUNCTION_CALL:
507
0
    SFS_FunctionCall(parser);
508
0
    break;
509
0
  case ET_NEW:
510
0
    SFS_NewObject(parser);
511
0
    break;
512
0
  case ET_OBJECT_MEMBER_ACCESS:
513
0
    SFS_ObjectMemberAccess(parser);
514
0
    break;
515
0
  case ET_OBJECT_METHOD_CALL:
516
0
    SFS_ObjectMethodCall(parser);
517
0
    break;
518
0
  case ET_ARRAY_DEREFERENCE:
519
0
    SFS_ArrayDeref(parser);
520
0
    break;
521
522
0
  case ET_MULTIPLY:
523
0
    SFS_Expression(parser);
524
0
    SFS_AddString(parser, "*");
525
0
    SFS_Expression(parser);
526
0
    break;
527
0
  case ET_DIVIDE:
528
0
    SFS_Expression(parser);
529
0
    SFS_AddString(parser, "/");
530
0
    SFS_Expression(parser);
531
0
    break;
532
0
  case ET_MOD:
533
0
    SFS_Expression(parser);
534
0
    SFS_AddString(parser, "%");
535
0
    SFS_Expression(parser);
536
0
    break;
537
0
  case ET_PLUS:
538
0
    SFS_Expression(parser);
539
0
    SFS_AddString(parser, "+");
540
0
    SFS_Expression(parser);
541
0
    break;
542
0
  case ET_MINUS:
543
0
    SFS_Expression(parser);
544
0
    SFS_AddString(parser, "-");
545
0
    SFS_Expression(parser);
546
0
    break;
547
0
  case ET_LSHIFT:
548
0
    SFS_Expression(parser);
549
0
    SFS_AddString(parser, "<<");
550
0
    SFS_Expression(parser);
551
0
    break;
552
0
  case ET_RSHIFT:
553
0
    SFS_Expression(parser);
554
0
    SFS_AddString(parser, ">>");
555
0
    SFS_Expression(parser);
556
0
    break;
557
0
  case ET_RSHIFTFILL:
558
0
    SFS_Expression(parser);
559
0
    SFS_AddString(parser, ">>>");
560
0
    SFS_Expression(parser);
561
0
    break;
562
0
  case ET_AND:
563
0
    SFS_Expression(parser);
564
0
    SFS_AddString(parser, "&");
565
0
    SFS_Expression(parser);
566
0
    break;
567
0
  case ET_XOR:
568
0
    SFS_Expression(parser);
569
0
    SFS_AddString(parser, "^");
570
0
    SFS_Expression(parser);
571
0
    break;
572
0
  case ET_OR:
573
0
    SFS_Expression(parser);
574
0
    SFS_AddString(parser, "|");
575
0
    SFS_Expression(parser);
576
0
    break;
577
0
  case ET_LT:
578
0
    SFS_Expression(parser);
579
0
    SFS_AddString(parser, "<");
580
0
    SFS_Expression(parser);
581
0
    break;
582
0
  case ET_LE:
583
0
    SFS_Expression(parser);
584
0
    SFS_AddString(parser, "<=");
585
0
    SFS_Expression(parser);
586
0
    break;
587
0
  case ET_GT:
588
0
    SFS_Expression(parser);
589
0
    SFS_AddString(parser, ">");
590
0
    SFS_Expression(parser);
591
0
    break;
592
0
  case ET_GE:
593
0
    SFS_Expression(parser);
594
0
    SFS_AddString(parser, ">=");
595
0
    SFS_Expression(parser);
596
0
    break;
597
0
  case ET_EQ:
598
0
    SFS_Expression(parser);
599
0
    SFS_AddString(parser, "==");
600
0
    SFS_Expression(parser);
601
0
    break;
602
0
  case ET_NE:
603
0
    SFS_Expression(parser);
604
0
    SFS_AddString(parser, "!=");
605
0
    SFS_Expression(parser);
606
0
    break;
607
0
  case ET_LAND:
608
0
    SFS_Expression(parser);
609
0
    SFS_AddString(parser, "&&");
610
0
    SFS_Expression(parser);
611
0
    break;
612
0
  case ET_LOR:
613
0
    SFS_Expression(parser);
614
0
    SFS_AddString(parser, "||");
615
0
    SFS_Expression(parser);
616
0
    break;
617
0
  case ET_ASSIGN:
618
0
    SFS_Expression(parser);
619
0
    SFS_AddString(parser, "=");
620
0
    SFS_Expression(parser);
621
0
    break;
622
0
  case ET_PLUSEQ:
623
0
    SFS_Expression(parser);
624
0
    SFS_AddString(parser, "+=");
625
0
    SFS_Expression(parser);
626
0
    break;
627
0
  case ET_MINUSEQ:
628
0
    SFS_Expression(parser);
629
0
    SFS_AddString(parser, "-=");
630
0
    SFS_Expression(parser);
631
0
    break;
632
0
  case ET_MULTIPLYEQ:
633
0
    SFS_Expression(parser);
634
0
    SFS_AddString(parser, "*=");
635
0
    SFS_Expression(parser);
636
0
    break;
637
0
  case ET_DIVIDEEQ:
638
0
    SFS_Expression(parser);
639
0
    SFS_AddString(parser, "/=");
640
0
    SFS_Expression(parser);
641
0
    break;
642
0
  case ET_MODEQ:
643
0
    SFS_Expression(parser);
644
0
    SFS_AddString(parser, "%=");
645
0
    SFS_Expression(parser);
646
0
    break;
647
0
  case ET_LSHIFTEQ:
648
0
    SFS_Expression(parser);
649
0
    SFS_AddString(parser, "<<=");
650
0
    SFS_Expression(parser);
651
0
    break;
652
0
  case ET_RSHIFTEQ:
653
0
    SFS_Expression(parser);
654
0
    SFS_AddString(parser, ">>=");
655
0
    SFS_Expression(parser);
656
0
    break;
657
0
  case ET_RSHIFTFILLEQ:
658
0
    SFS_Expression(parser);
659
0
    SFS_AddString(parser, ">>>=");
660
0
    SFS_Expression(parser);
661
0
    break;
662
0
  case ET_ANDEQ:
663
0
    SFS_Expression(parser);
664
0
    SFS_AddString(parser, "&=");
665
0
    SFS_Expression(parser);
666
0
    break;
667
0
  case ET_XOREQ:
668
0
    SFS_Expression(parser);
669
0
    SFS_AddString(parser, "^=");
670
0
    SFS_Expression(parser);
671
0
    break;
672
0
  case ET_OREQ:
673
0
    SFS_Expression(parser);
674
0
    SFS_AddString(parser, "|=");
675
0
    SFS_Expression(parser);
676
0
    break;
677
0
  case ET_BOOLEAN:
678
0
    SFS_GetBoolean(parser);
679
0
    break;
680
0
  case ET_VAR:
681
0
    SFS_AddString(parser, "var ");
682
0
    SFS_Arguments(parser, GF_TRUE);
683
0
    break;
684
0
  case ET_FUNCTION_ASSIGN:
685
0
    SFS_AddString(parser, "function ");
686
0
    SFS_Arguments(parser, GF_FALSE);
687
0
    SFS_StatementBlock(parser, GF_TRUE);
688
0
    break;
689
0
  default:
690
0
    parser->codec->LastError = GF_NON_COMPLIANT_BITSTREAM;
691
0
    break;
692
0
  }
693
0
  parser->expr_stack_size--;
694
0
}
695
696
void SFS_NewObject(ScriptParser *parser)
697
0
{
698
0
  if (parser->codec->LastError) return;
699
0
  SFS_AddString(parser, "new ");
700
0
  SFS_Identifier(parser);
701
0
  SFS_AddString(parser, "(");
702
0
  SFS_Params(parser);
703
0
  SFS_AddString(parser, ") ");
704
0
}
705
706
void SFS_ArrayDeref(ScriptParser *parser)
707
0
{
708
0
  if (parser->codec->LastError) return;
709
0
  SFS_Expression(parser);
710
0
  if (parser->codec->LastError) return;
711
0
  SFS_AddString(parser, "[");
712
0
  SFS_CompoundExpression(parser);
713
0
  SFS_AddString(parser, "]");
714
0
}
715
716
void SFS_FunctionCall(ScriptParser *parser)
717
0
{
718
0
  if (parser->codec->LastError) return;
719
0
  SFS_Identifier(parser);
720
0
  SFS_AddString(parser, "(");
721
0
  SFS_Params(parser);
722
0
  SFS_AddString(parser, ")");
723
0
}
724
725
void SFS_ObjectMemberAccess(ScriptParser *parser)
726
0
{
727
0
  if (parser->codec->LastError) return;
728
0
  SFS_Expression(parser);
729
0
  if (parser->codec->LastError) return;
730
0
  SFS_AddString(parser, ".");
731
0
  SFS_Identifier(parser);
732
0
}
733
734
735
void SFS_ObjectMethodCall(ScriptParser *parser)
736
0
{
737
0
  if (parser->codec->LastError) return;
738
0
  SFS_Expression(parser);
739
0
  if (parser->codec->LastError) return;
740
0
  SFS_AddString(parser, ".");
741
0
  SFS_Identifier(parser);
742
0
  SFS_AddString(parser, "(");
743
0
  SFS_Params(parser);
744
0
  SFS_AddString(parser, ")");
745
0
}
746
747
void SFS_Params(ScriptParser *parser)
748
0
{
749
0
  u32 val;
750
0
  if (parser->codec->LastError) return;
751
0
  val = gf_bs_read_int(parser->bs, 1);
752
0
  while (val) {
753
0
    SFS_Expression(parser);
754
0
    if (parser->codec->LastError) return;
755
0
    val = gf_bs_read_int(parser->bs, 1);
756
0
    if(val) SFS_AddString(parser, ",");
757
0
  }
758
0
}
759
760
void SFS_GetNumber(ScriptParser *parser)
761
0
{
762
0
  u32 val, nbBits;
763
764
0
  if (parser->codec->LastError) return;
765
  // integer
766
0
  if (gf_bs_read_int(parser->bs, 1)) {
767
0
    nbBits = gf_bs_read_int(parser->bs, 5);
768
0
    val = gf_bs_read_int(parser->bs, nbBits);
769
0
    SFS_AddInt(parser, val);
770
0
    return;
771
0
  }
772
  // real number
773
0
  val = gf_bs_read_int(parser->bs, 4);
774
0
  while ( val != 15) {
775
0
    if (val<=9) {
776
0
      SFS_AddChar(parser, (char) (val + '0') );
777
0
    } else if (val==10) {
778
0
      SFS_AddChar(parser, '.');
779
0
    } else if (val==11) {
780
0
      SFS_AddChar(parser, 'E');
781
0
    } else if (val==12) {
782
0
      SFS_AddChar(parser, '-');
783
0
    }
784
0
    val = gf_bs_read_int(parser->bs, 4);
785
0
  }
786
0
}
787
788
void SFS_GetString(ScriptParser *parser)
789
0
{
790
0
  char name[1000];
791
0
  if (parser->codec->LastError) return;
792
0
  gf_bifs_dec_name(parser->bs, name, 1000);
793
0
  SFS_AddString(parser, name);
794
0
}
795
796
void SFS_GetBoolean(ScriptParser *parser)
797
0
{
798
0
  if (parser->codec->LastError) return;
799
0
  if (gf_bs_read_int(parser->bs, 1)) {
800
0
    SFS_AddString(parser, "true");
801
0
  } else {
802
0
    SFS_AddString(parser, "false");
803
0
  }
804
0
}
805
806
#endif /*!defined(GPAC_DISABLE_BIFS) && defined(GPAC_HAS_QJS)*/