Coverage Report

Created: 2026-08-28 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/yara/libyara/re.c
Line
Count
Source
1
/*
2
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
3
4
Redistribution and use in source and binary forms, with or without modification,
5
are permitted provided that the following conditions are met:
6
7
1. Redistributions of source code must retain the above copyright notice, this
8
list of conditions and the following disclaimer.
9
10
2. Redistributions in binary form must reproduce the above copyright notice,
11
this list of conditions and the following disclaimer in the documentation and/or
12
other materials provided with the distribution.
13
14
3. Neither the name of the copyright holder nor the names of its contributors
15
may be used to endorse or promote products derived from this software without
16
specific prior written permission.
17
18
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
*/
29
30
/*
31
32
This module implements a regular expressions engine based on Thompson's
33
algorithm as described by Russ Cox in http://swtch.com/~rsc/regexp/regexp2.html.
34
35
What the article names a "thread" has been named a "fiber" in this code, in
36
order to avoid confusion with operating system threads.
37
38
*/
39
40
#include <assert.h>
41
#include <string.h>
42
#include <yara/arena.h>
43
#include <yara/compiler.h>
44
#include <yara/error.h>
45
#include <yara/globals.h>
46
#include <yara/hex_lexer.h>
47
#include <yara/libyara.h>
48
#include <yara/limits.h>
49
#include <yara/mem.h>
50
#include <yara/re.h>
51
#include <yara/re_lexer.h>
52
#include <yara/strutils.h>
53
#include <yara/threading.h>
54
#include <yara/unaligned.h>
55
#include <yara/utils.h>
56
57
0
#define EMIT_BACKWARDS               0x01
58
0
#define EMIT_DONT_SET_FORWARDS_CODE  0x02
59
0
#define EMIT_DONT_SET_BACKWARDS_CODE 0x04
60
61
#ifndef INT16_MAX
62
#define INT16_MAX (32767)
63
#endif
64
65
typedef uint8_t RE_SPLIT_ID_TYPE;
66
67
// RE_REPEAT_ARGS and RE_REPEAT_ANY_ARGS are structures that are embedded in
68
// the regexp's instruction stream. As such, they are not always aligned to
69
// 8-byte boundaries, so they need to be "packed" structures in order to prevent
70
// issues due to unaligned memory accesses.
71
#pragma pack(push)
72
#pragma pack(1)
73
74
typedef struct _RE_REPEAT_ARGS
75
{
76
  uint16_t min;
77
  uint16_t max;
78
  int32_t offset;
79
80
} RE_REPEAT_ARGS;
81
82
typedef struct _RE_REPEAT_ANY_ARGS
83
{
84
  uint16_t min;
85
  uint16_t max;
86
87
} RE_REPEAT_ANY_ARGS;
88
89
#pragma pack(pop)
90
91
typedef struct _RE_EMIT_CONTEXT
92
{
93
  YR_ARENA* arena;
94
  RE_SPLIT_ID_TYPE next_split_id;
95
96
} RE_EMIT_CONTEXT;
97
98
0
#define CHAR_IN_CLASS(cls, chr) ((cls)[(chr) / 8] & 1 << ((chr) % 8))
99
100
static bool _yr_re_is_char_in_class(
101
    RE_CLASS* re_class,
102
    uint8_t chr,
103
    int case_insensitive)
104
0
{
105
0
  int result = CHAR_IN_CLASS(re_class->bitmap, chr);
106
107
0
  if (case_insensitive)
108
0
    result |= CHAR_IN_CLASS(re_class->bitmap, yr_altercase[chr]);
109
110
0
  if (re_class->negated)
111
0
    result = !result;
112
113
0
  return result;
114
0
}
115
116
static bool _yr_re_is_word_char(const uint8_t* input, uint8_t character_size)
117
0
{
118
0
  int result = ((yr_isalnum(input) || (*input) == '_'));
119
120
0
  if (character_size == 2)
121
0
    result = result && (*(input + 1) == 0);
122
123
0
  return result;
124
0
}
125
126
RE_NODE* yr_re_node_create(int type)
127
0
{
128
0
  RE_NODE* result = (RE_NODE*) yr_malloc(sizeof(RE_NODE));
129
130
0
  if (result != NULL)
131
0
  {
132
0
    result->type = type;
133
0
    result->children_head = NULL;
134
0
    result->children_tail = NULL;
135
0
    result->prev_sibling = NULL;
136
0
    result->next_sibling = NULL;
137
0
    result->greedy = true;
138
0
    result->forward_code_ref = YR_ARENA_NULL_REF;
139
0
    result->backward_code_ref = YR_ARENA_NULL_REF;
140
0
  }
141
142
0
  return result;
143
0
}
144
145
void yr_re_node_destroy(RE_NODE* node)
146
0
{
147
0
  RE_NODE* child = node->children_head;
148
0
  RE_NODE* next_child;
149
150
0
  while (child != NULL)
151
0
  {
152
0
    next_child = child->next_sibling;
153
0
    yr_re_node_destroy(child);
154
0
    child = next_child;
155
0
  }
156
157
0
  if (node->type == RE_NODE_CLASS)
158
0
    yr_free(node->re_class);
159
160
0
  yr_free(node);
161
0
}
162
163
////////////////////////////////////////////////////////////////////////////////
164
// Appends a node to the end of the children list.
165
//
166
void yr_re_node_append_child(RE_NODE* node, RE_NODE* child)
167
0
{
168
0
  if (node->children_head == NULL)
169
0
    node->children_head = child;
170
171
0
  if (node->children_tail != NULL)
172
0
    node->children_tail->next_sibling = child;
173
174
0
  child->prev_sibling = node->children_tail;
175
0
  node->children_tail = child;
176
0
}
177
178
////////////////////////////////////////////////////////////////////////////////
179
// Appends a node to the beginning of the children list.
180
//
181
void yr_re_node_prepend_child(RE_NODE* node, RE_NODE* child)
182
0
{
183
0
  child->next_sibling = node->children_head;
184
185
0
  if (node->children_head != NULL)
186
0
    node->children_head->prev_sibling = child;
187
188
0
  node->children_head = child;
189
190
0
  if (node->children_tail == NULL)
191
0
    node->children_tail = child;
192
0
}
193
194
int yr_re_ast_create(RE_AST** re_ast)
195
0
{
196
0
  *re_ast = (RE_AST*) yr_malloc(sizeof(RE_AST));
197
198
0
  if (*re_ast == NULL)
199
0
    return ERROR_INSUFFICIENT_MEMORY;
200
201
0
  (*re_ast)->flags = 0;
202
0
  (*re_ast)->root_node = NULL;
203
204
0
  return ERROR_SUCCESS;
205
0
}
206
207
void yr_re_ast_destroy(RE_AST* re_ast)
208
0
{
209
0
  if (re_ast->root_node != NULL)
210
0
    yr_re_node_destroy(re_ast->root_node);
211
212
0
  yr_free(re_ast);
213
0
}
214
215
////////////////////////////////////////////////////////////////////////////////
216
// Parses a regexp but don't emit its code. A further call to
217
// yr_re_ast_emit_code is required to get the code.
218
//
219
int yr_re_parse(
220
    const char* re_string,
221
    RE_AST** re_ast,
222
    RE_ERROR* error,
223
    int flags)
224
0
{
225
0
  return yr_parse_re_string(re_string, re_ast, error, flags);
226
0
}
227
228
////////////////////////////////////////////////////////////////////////////////
229
// Parses a hex string but don't emit its code. A further call to
230
// yr_re_ast_emit_code is required to get the code.
231
//
232
int yr_re_parse_hex(const char* hex_string, RE_AST** re_ast, RE_ERROR* error)
233
0
{
234
0
  return yr_parse_hex_string(hex_string, re_ast, error);
235
0
}
236
237
////////////////////////////////////////////////////////////////////////////////
238
// Parses the regexp and emit its code to the provided to the
239
// YR_RE_CODE_SECTION in the specified arena.
240
//
241
int yr_re_compile(
242
    const char* re_string,
243
    int flags,
244
    int parser_flags,
245
    YR_ARENA* arena,
246
    YR_ARENA_REF* ref,
247
    RE_ERROR* error)
248
0
{
249
0
  RE_AST* re_ast;
250
0
  RE _re;
251
0
  int result;
252
253
0
  result = yr_re_parse(re_string, &re_ast, error, parser_flags);
254
0
  if (result != ERROR_UNKNOWN_ESCAPE_SEQUENCE)
255
0
    FAIL_ON_ERROR(result);
256
257
0
  _re.flags = flags;
258
259
0
  FAIL_ON_ERROR_WITH_CLEANUP(
260
0
      yr_arena_write_data(arena, YR_RE_CODE_SECTION, &_re, sizeof(_re), ref),
261
0
      yr_re_ast_destroy(re_ast));
262
263
0
  FAIL_ON_ERROR_WITH_CLEANUP(
264
0
      yr_re_ast_emit_code(re_ast, arena, false), yr_re_ast_destroy(re_ast));
265
266
0
  yr_re_ast_destroy(re_ast);
267
268
0
  return result;
269
0
}
270
271
////////////////////////////////////////////////////////////////////////////////
272
// Verifies if the target string matches the pattern
273
//
274
// Args:
275
//    context: Scan context
276
//    re: A pointer to a compiled regexp
277
//    target: Target string
278
//
279
// Returns:
280
//    See return codes for yr_re_exec
281
//
282
int yr_re_match(YR_SCAN_CONTEXT* context, RE* re, const char* target)
283
0
{
284
0
  int result;
285
286
0
  yr_re_exec(
287
0
      context,
288
0
      re->code,
289
0
      (uint8_t*) target,
290
0
      strlen(target),
291
0
      0,
292
0
      re->flags | RE_FLAGS_SCAN,
293
0
      NULL,
294
0
      NULL,
295
0
      &result);
296
297
0
  return result;
298
0
}
299
300
////////////////////////////////////////////////////////////////////////////////
301
// Verifies if the provided regular expression is just a literal string
302
// like "abc", "12345", without any wildcard, operator, etc. In that case
303
// returns the string as a SIZED_STRING, or returns NULL if otherwise.
304
//
305
// The caller is responsible for deallocating the returned SIZED_STRING by
306
// calling yr_free.
307
//
308
SIZED_STRING* yr_re_ast_extract_literal(RE_AST* re_ast)
309
0
{
310
0
  SIZED_STRING* string;
311
0
  RE_NODE* child;
312
313
0
  int length = 0;
314
315
0
  if (re_ast->root_node->type == RE_NODE_LITERAL)
316
0
  {
317
0
    length = 1;
318
0
  }
319
0
  else if (re_ast->root_node->type == RE_NODE_CONCAT)
320
0
  {
321
0
    child = re_ast->root_node->children_tail;
322
323
0
    while (child != NULL && child->type == RE_NODE_LITERAL)
324
0
    {
325
0
      length++;
326
0
      child = child->prev_sibling;
327
0
    }
328
329
0
    if (child != NULL)
330
0
      return NULL;
331
0
  }
332
0
  else
333
0
  {
334
0
    return NULL;
335
0
  }
336
337
0
  string = (SIZED_STRING*) yr_malloc(sizeof(SIZED_STRING) + length);
338
339
0
  if (string == NULL)
340
0
    return NULL;
341
342
0
  string->length = length;
343
0
  string->flags = 0;
344
345
0
  if (re_ast->root_node->type == RE_NODE_LITERAL)
346
0
  {
347
0
    string->c_string[0] = re_ast->root_node->value;
348
0
  }
349
0
  else
350
0
  {
351
0
    child = re_ast->root_node->children_tail;
352
353
0
    while (child != NULL)
354
0
    {
355
0
      string->c_string[--length] = child->value;
356
0
      child = child->prev_sibling;
357
0
    }
358
0
  }
359
360
0
  string->c_string[string->length] = '\0';
361
362
0
  return string;
363
0
}
364
365
int _yr_re_node_has_unbounded_quantifier_for_dot(RE_NODE* re_node)
366
0
{
367
0
  RE_NODE* child;
368
369
0
  if ((re_node->type == RE_NODE_STAR || re_node->type == RE_NODE_PLUS) &&
370
0
      re_node->children_head->type == RE_NODE_ANY)
371
0
    return true;
372
373
0
  if (re_node->type == RE_NODE_RANGE_ANY && re_node->end == RE_MAX_RANGE)
374
0
    return true;
375
376
0
  if (re_node->type == RE_NODE_CONCAT)
377
0
  {
378
0
    child = re_node->children_tail;
379
380
0
    while (child != NULL)
381
0
    {
382
0
      if (_yr_re_node_has_unbounded_quantifier_for_dot(child))
383
0
        return true;
384
385
0
      child = child->prev_sibling;
386
0
    }
387
0
  }
388
389
0
  return false;
390
0
}
391
392
////////////////////////////////////////////////////////////////////////////////
393
// Detects the use of .*, .+ or .{x,} in a regexp. The use of wildcards with
394
// quantifiers that don't have a reasonably small upper bound causes a
395
// performance penalty. This function detects such cases in order to warn the
396
// user about this.
397
//
398
int yr_re_ast_has_unbounded_quantifier_for_dot(RE_AST* re_ast)
399
0
{
400
0
  return _yr_re_node_has_unbounded_quantifier_for_dot(re_ast->root_node);
401
0
}
402
403
////////////////////////////////////////////////////////////////////////////////
404
// In some cases splitting a regular expression (or hex string) in two parts is
405
// convenient for increasing performance. This happens when the pattern contains
406
// a large gap (a.k.a jump), for example: { 01 02 03 [0-999] 04 05 06 }
407
// In this case the string is splitted in { 01 02 03 } and { 04 05 06 } where
408
// the latter is chained to the former. This means that { 01 02 03 } and
409
// { 04 05 06 } are handled as individual strings, and when both of them are
410
// found, YARA verifies if the distance between the matches complies with the
411
// [0-999] restriction.
412
//
413
// This function traverses a regexp's AST looking for nodes where it should be
414
// splitted. It must be noticed that this only applies to two-level ASTs (i.e.
415
// an AST consisting in a RE_NODE_CONCAT at the root where all the children are
416
// leaves).
417
//
418
// For example, { 01 02 03 [0-1000] 04 05 06 [500-2000] 07 08 09 } has the
419
// following AST:
420
//
421
// RE_NODE_CONCAT
422
// |
423
// |- RE_NODE_LITERAL (01)
424
// |- RE_NODE_LITERAL (02)
425
// |- RE_NODE_LITERAL (03)
426
// |- RE_NODE_RANGE_ANY (start=0, end=1000)
427
// |- RE_NODE_LITERAL (04)
428
// |- RE_NODE_LITERAL (05)
429
// |- RE_NODE_LITERAL (06)
430
// |- RE_NODE_RANGE_ANY (start=500, end=2000)
431
// |- RE_NODE_LITERAL (07)
432
// |- RE_NODE_LITERAL (08)
433
// |- RE_NODE_LITERAL (09)
434
//
435
// If the AST above is passed in the re_ast argument, it will be trimmed to:
436
//
437
// RE_NODE_CONCAT
438
// |
439
// |- RE_NODE_LITERAL (01)
440
// |- RE_NODE_LITERAL (02)
441
// |- RE_NODE_LITERAL (03)
442
//
443
// While remainder_re_ast will be:
444
//
445
// RE_NODE_CONCAT
446
// |
447
// |- RE_NODE_LITERAL (04)
448
// |- RE_NODE_LITERAL (05)
449
// |- RE_NODE_LITERAL (06)
450
// |- RE_NODE_RANGE_ANY (start=500, end=2000)
451
// |- RE_NODE_LITERAL (07)
452
// |- RE_NODE_LITERAL (08)
453
// |- RE_NODE_LITERAL (09)
454
//
455
// The caller is responsible for freeing the new AST in remainder_re_ast by
456
// calling yr_re_ast_destroy.
457
//
458
// The integers pointed to by min_gap and max_gap will be filled with the
459
// minimum and maximum gap size between the sub-strings represented by the
460
// two ASTs.
461
//
462
int yr_re_ast_split_at_chaining_point(
463
    RE_AST* re_ast,
464
    RE_AST** remainder_re_ast,
465
    int32_t* min_gap,
466
    int32_t* max_gap)
467
0
{
468
0
  RE_NODE* child;
469
0
  RE_NODE* concat;
470
471
0
  int result;
472
473
0
  *remainder_re_ast = NULL;
474
0
  *min_gap = 0;
475
0
  *max_gap = 0;
476
477
0
  if (re_ast->root_node->type != RE_NODE_CONCAT)
478
0
    return ERROR_SUCCESS;
479
480
0
  child = re_ast->root_node->children_head;
481
482
0
  while (child != NULL)
483
0
  {
484
0
    if (!child->greedy && child->type == RE_NODE_RANGE_ANY &&
485
0
        child->prev_sibling != NULL && child->next_sibling != NULL &&
486
0
        (child->start > YR_STRING_CHAINING_THRESHOLD ||
487
0
         child->end > YR_STRING_CHAINING_THRESHOLD))
488
0
    {
489
0
      result = yr_re_ast_create(remainder_re_ast);
490
491
0
      if (result != ERROR_SUCCESS)
492
0
        return result;
493
494
0
      concat = yr_re_node_create(RE_NODE_CONCAT);
495
496
0
      if (concat == NULL)
497
0
        return ERROR_INSUFFICIENT_MEMORY;
498
499
0
      concat->children_head = child->next_sibling;
500
0
      concat->children_tail = re_ast->root_node->children_tail;
501
502
0
      re_ast->root_node->children_tail = child->prev_sibling;
503
504
0
      child->prev_sibling->next_sibling = NULL;
505
0
      child->next_sibling->prev_sibling = NULL;
506
507
0
      *min_gap = child->start;
508
0
      *max_gap = child->end;
509
510
0
      (*remainder_re_ast)->root_node = concat;
511
0
      (*remainder_re_ast)->flags = re_ast->flags;
512
513
0
      yr_re_node_destroy(child);
514
515
0
      return ERROR_SUCCESS;
516
0
    }
517
518
0
    child = child->next_sibling;
519
0
  }
520
521
0
  return ERROR_SUCCESS;
522
0
}
523
524
int _yr_emit_inst(
525
    RE_EMIT_CONTEXT* emit_context,
526
    uint8_t opcode,
527
    YR_ARENA_REF* instruction_ref)
528
0
{
529
0
  FAIL_ON_ERROR(yr_arena_write_data(
530
0
      emit_context->arena,
531
0
      YR_RE_CODE_SECTION,
532
0
      &opcode,
533
0
      sizeof(uint8_t),
534
0
      instruction_ref));
535
536
0
  return ERROR_SUCCESS;
537
0
}
538
539
int _yr_emit_inst_arg_uint8(
540
    RE_EMIT_CONTEXT* emit_context,
541
    uint8_t opcode,
542
    uint8_t argument,
543
    YR_ARENA_REF* instruction_ref,
544
    YR_ARENA_REF* argument_ref)
545
0
{
546
0
  FAIL_ON_ERROR(yr_arena_write_data(
547
0
      emit_context->arena,
548
0
      YR_RE_CODE_SECTION,
549
0
      &opcode,
550
0
      sizeof(uint8_t),
551
0
      instruction_ref));
552
553
0
  FAIL_ON_ERROR(yr_arena_write_data(
554
0
      emit_context->arena,
555
0
      YR_RE_CODE_SECTION,
556
0
      &argument,
557
0
      sizeof(uint8_t),
558
0
      argument_ref));
559
560
0
  return ERROR_SUCCESS;
561
0
}
562
563
int _yr_emit_inst_arg_uint16(
564
    RE_EMIT_CONTEXT* emit_context,
565
    uint8_t opcode,
566
    uint16_t argument,
567
    YR_ARENA_REF* instruction_ref,
568
    YR_ARENA_REF* argument_ref)
569
0
{
570
0
  FAIL_ON_ERROR(yr_arena_write_data(
571
0
      emit_context->arena,
572
0
      YR_RE_CODE_SECTION,
573
0
      &opcode,
574
0
      sizeof(uint8_t),
575
0
      instruction_ref));
576
577
0
  FAIL_ON_ERROR(yr_arena_write_data(
578
0
      emit_context->arena,
579
0
      YR_RE_CODE_SECTION,
580
0
      &argument,
581
0
      sizeof(uint16_t),
582
0
      argument_ref));
583
584
0
  return ERROR_SUCCESS;
585
0
}
586
587
int _yr_emit_inst_arg_uint32(
588
    RE_EMIT_CONTEXT* emit_context,
589
    uint8_t opcode,
590
    uint32_t argument,
591
    YR_ARENA_REF* instruction_ref,
592
    YR_ARENA_REF* argument_ref)
593
0
{
594
0
  FAIL_ON_ERROR(yr_arena_write_data(
595
0
      emit_context->arena,
596
0
      YR_RE_CODE_SECTION,
597
0
      &opcode,
598
0
      sizeof(uint8_t),
599
0
      instruction_ref));
600
601
0
  FAIL_ON_ERROR(yr_arena_write_data(
602
0
      emit_context->arena,
603
0
      YR_RE_CODE_SECTION,
604
0
      &argument,
605
0
      sizeof(uint32_t),
606
0
      argument_ref));
607
608
0
  return ERROR_SUCCESS;
609
0
}
610
611
int _yr_emit_inst_arg_int16(
612
    RE_EMIT_CONTEXT* emit_context,
613
    uint8_t opcode,
614
    int16_t argument,
615
    YR_ARENA_REF* instruction_ref,
616
    YR_ARENA_REF* argument_ref)
617
0
{
618
0
  FAIL_ON_ERROR(yr_arena_write_data(
619
0
      emit_context->arena,
620
0
      YR_RE_CODE_SECTION,
621
0
      &opcode,
622
0
      sizeof(uint8_t),
623
0
      instruction_ref));
624
625
0
  FAIL_ON_ERROR(yr_arena_write_data(
626
0
      emit_context->arena,
627
0
      YR_RE_CODE_SECTION,
628
0
      &argument,
629
0
      sizeof(int16_t),
630
0
      argument_ref));
631
632
0
  return ERROR_SUCCESS;
633
0
}
634
635
int _yr_emit_inst_arg_struct(
636
    RE_EMIT_CONTEXT* emit_context,
637
    uint8_t opcode,
638
    void* structure,
639
    size_t structure_size,
640
    YR_ARENA_REF* instruction_ref,
641
    YR_ARENA_REF* argument_ref)
642
0
{
643
0
  FAIL_ON_ERROR(yr_arena_write_data(
644
0
      emit_context->arena,
645
0
      YR_RE_CODE_SECTION,
646
0
      &opcode,
647
0
      sizeof(uint8_t),
648
0
      instruction_ref));
649
650
0
  FAIL_ON_ERROR(yr_arena_write_data(
651
0
      emit_context->arena,
652
0
      YR_RE_CODE_SECTION,
653
0
      structure,
654
0
      structure_size,
655
0
      argument_ref));
656
657
0
  return ERROR_SUCCESS;
658
0
}
659
660
int _yr_emit_split(
661
    RE_EMIT_CONTEXT* emit_context,
662
    uint8_t opcode,
663
    int16_t argument,
664
    YR_ARENA_REF* instruction_ref,
665
    YR_ARENA_REF* argument_ref)
666
0
{
667
0
  assert(opcode == RE_OPCODE_SPLIT_A || opcode == RE_OPCODE_SPLIT_B);
668
669
0
  if (emit_context->next_split_id == RE_MAX_SPLIT_ID)
670
0
    return ERROR_REGULAR_EXPRESSION_TOO_COMPLEX;
671
672
0
  FAIL_ON_ERROR(yr_arena_write_data(
673
0
      emit_context->arena,
674
0
      YR_RE_CODE_SECTION,
675
0
      &opcode,
676
0
      sizeof(uint8_t),
677
0
      instruction_ref));
678
679
0
  FAIL_ON_ERROR(yr_arena_write_data(
680
0
      emit_context->arena,
681
0
      YR_RE_CODE_SECTION,
682
0
      &emit_context->next_split_id,
683
0
      sizeof(RE_SPLIT_ID_TYPE),
684
0
      NULL));
685
686
0
  emit_context->next_split_id++;
687
688
0
  FAIL_ON_ERROR(yr_arena_write_data(
689
0
      emit_context->arena,
690
0
      YR_RE_CODE_SECTION,
691
0
      &argument,
692
0
      sizeof(int16_t),
693
0
      argument_ref));
694
695
0
  return ERROR_SUCCESS;
696
0
}
697
698
static int _yr_re_emit(
699
    RE_EMIT_CONTEXT* emit_context,
700
    RE_NODE* re_node,
701
    int flags,
702
    YR_ARENA_REF* code_ref)
703
0
{
704
0
  int16_t jmp_offset;
705
706
0
  yr_arena_off_t bookmark_1 = 0;
707
0
  yr_arena_off_t bookmark_2 = 0;
708
0
  yr_arena_off_t bookmark_3 = 0;
709
0
  yr_arena_off_t bookmark_4 = 0;
710
711
0
  bool emit_split;
712
0
  bool emit_repeat;
713
0
  bool emit_prolog;
714
0
  bool emit_epilog;
715
716
0
  RE_REPEAT_ARGS repeat_args;
717
0
  RE_REPEAT_ARGS* repeat_start_args_addr;
718
0
  RE_REPEAT_ANY_ARGS repeat_any_args;
719
720
0
  RE_NODE* child;
721
722
0
  void* split_offset_addr = NULL;
723
0
  void* jmp_offset_addr = NULL;
724
725
0
  YR_ARENA_REF instruction_ref = YR_ARENA_NULL_REF;
726
0
  YR_ARENA_REF split_offset_ref;
727
0
  YR_ARENA_REF jmp_instruction_ref;
728
0
  YR_ARENA_REF jmp_offset_ref;
729
0
  YR_ARENA_REF repeat_start_args_ref;
730
731
0
  switch (re_node->type)
732
0
  {
733
0
  case RE_NODE_LITERAL:
734
0
    FAIL_ON_ERROR(_yr_emit_inst_arg_uint8(
735
0
        emit_context,
736
0
        RE_OPCODE_LITERAL,
737
0
        re_node->value,
738
0
        &instruction_ref,
739
0
        NULL));
740
0
    break;
741
742
0
  case RE_NODE_NOT_LITERAL:
743
0
    FAIL_ON_ERROR(_yr_emit_inst_arg_uint8(
744
0
        emit_context,
745
0
        RE_OPCODE_NOT_LITERAL,
746
0
        re_node->value,
747
0
        &instruction_ref,
748
0
        NULL));
749
0
    break;
750
751
0
  case RE_NODE_MASKED_LITERAL:
752
0
    FAIL_ON_ERROR(_yr_emit_inst_arg_uint16(
753
0
        emit_context,
754
0
        RE_OPCODE_MASKED_LITERAL,
755
0
        re_node->mask << 8 | re_node->value,
756
0
        &instruction_ref,
757
0
        NULL));
758
0
    break;
759
760
0
  case RE_NODE_MASKED_NOT_LITERAL:
761
0
    FAIL_ON_ERROR(_yr_emit_inst_arg_uint16(
762
0
        emit_context,
763
0
        RE_OPCODE_MASKED_NOT_LITERAL,
764
0
        re_node->mask << 8 | re_node->value,
765
0
        &instruction_ref,
766
0
        NULL));
767
0
    break;
768
769
0
  case RE_NODE_WORD_CHAR:
770
0
    FAIL_ON_ERROR(
771
0
        _yr_emit_inst(emit_context, RE_OPCODE_WORD_CHAR, &instruction_ref));
772
0
    break;
773
774
0
  case RE_NODE_NON_WORD_CHAR:
775
0
    FAIL_ON_ERROR(
776
0
        _yr_emit_inst(emit_context, RE_OPCODE_NON_WORD_CHAR, &instruction_ref));
777
0
    break;
778
779
0
  case RE_NODE_WORD_BOUNDARY:
780
0
    FAIL_ON_ERROR(
781
0
        _yr_emit_inst(emit_context, RE_OPCODE_WORD_BOUNDARY, &instruction_ref));
782
0
    break;
783
784
0
  case RE_NODE_NON_WORD_BOUNDARY:
785
0
    FAIL_ON_ERROR(_yr_emit_inst(
786
0
        emit_context, RE_OPCODE_NON_WORD_BOUNDARY, &instruction_ref));
787
0
    break;
788
789
0
  case RE_NODE_SPACE:
790
0
    FAIL_ON_ERROR(
791
0
        _yr_emit_inst(emit_context, RE_OPCODE_SPACE, &instruction_ref));
792
0
    break;
793
794
0
  case RE_NODE_NON_SPACE:
795
0
    FAIL_ON_ERROR(
796
0
        _yr_emit_inst(emit_context, RE_OPCODE_NON_SPACE, &instruction_ref));
797
0
    break;
798
799
0
  case RE_NODE_DIGIT:
800
0
    FAIL_ON_ERROR(
801
0
        _yr_emit_inst(emit_context, RE_OPCODE_DIGIT, &instruction_ref));
802
0
    break;
803
804
0
  case RE_NODE_NON_DIGIT:
805
0
    FAIL_ON_ERROR(
806
0
        _yr_emit_inst(emit_context, RE_OPCODE_NON_DIGIT, &instruction_ref));
807
0
    break;
808
809
0
  case RE_NODE_ANY:
810
0
    FAIL_ON_ERROR(_yr_emit_inst(emit_context, RE_OPCODE_ANY, &instruction_ref));
811
0
    break;
812
813
0
  case RE_NODE_CLASS:
814
0
    FAIL_ON_ERROR(
815
0
        _yr_emit_inst(emit_context, RE_OPCODE_CLASS, &instruction_ref));
816
817
0
    FAIL_ON_ERROR(yr_arena_write_data(
818
0
        emit_context->arena,
819
0
        YR_RE_CODE_SECTION,
820
0
        re_node->re_class,
821
0
        sizeof(*re_node->re_class),
822
0
        NULL));
823
0
    break;
824
825
0
  case RE_NODE_ANCHOR_START:
826
0
    FAIL_ON_ERROR(_yr_emit_inst(
827
0
        emit_context, RE_OPCODE_MATCH_AT_START, &instruction_ref));
828
0
    break;
829
830
0
  case RE_NODE_ANCHOR_END:
831
0
    FAIL_ON_ERROR(
832
0
        _yr_emit_inst(emit_context, RE_OPCODE_MATCH_AT_END, &instruction_ref));
833
0
    break;
834
835
0
  case RE_NODE_CONCAT:
836
0
    FAIL_ON_ERROR(_yr_re_emit(
837
0
        emit_context,
838
0
        (flags & EMIT_BACKWARDS) ? re_node->children_tail
839
0
                                 : re_node->children_head,
840
0
        flags,
841
0
        &instruction_ref));
842
843
0
    if (flags & EMIT_BACKWARDS)
844
0
      child = re_node->children_tail->prev_sibling;
845
0
    else
846
0
      child = re_node->children_head->next_sibling;
847
848
0
    while (child != NULL)
849
0
    {
850
0
      FAIL_ON_ERROR(_yr_re_emit(emit_context, child, flags, NULL));
851
852
0
      child = (flags & EMIT_BACKWARDS) ? child->prev_sibling
853
0
                                       : child->next_sibling;
854
0
    }
855
0
    break;
856
857
0
  case RE_NODE_PLUS:
858
    // Code for e+ looks like:
859
    //
860
    //          L1: code for e
861
    //              split L1, L2
862
    //          L2:
863
    //
864
0
    FAIL_ON_ERROR(_yr_re_emit(
865
0
        emit_context, re_node->children_head, flags, &instruction_ref));
866
867
0
    bookmark_1 = yr_arena_get_current_offset(
868
0
        emit_context->arena, YR_RE_CODE_SECTION);
869
870
0
    if (instruction_ref.offset - bookmark_1 < INT16_MIN)
871
0
      return ERROR_REGULAR_EXPRESSION_TOO_LARGE;
872
873
0
    jmp_offset = (int16_t) (instruction_ref.offset - bookmark_1);
874
875
0
    FAIL_ON_ERROR(_yr_emit_split(
876
0
        emit_context,
877
0
        re_node->greedy ? RE_OPCODE_SPLIT_B : RE_OPCODE_SPLIT_A,
878
0
        jmp_offset,
879
0
        NULL,
880
0
        NULL));
881
882
0
    break;
883
884
0
  case RE_NODE_STAR:
885
    // Code for e* looks like:
886
    //
887
    //          L1: split L1, L2
888
    //              code for e
889
    //              jmp L1
890
    //          L2:
891
0
    FAIL_ON_ERROR(_yr_emit_split(
892
0
        emit_context,
893
0
        re_node->greedy ? RE_OPCODE_SPLIT_A : RE_OPCODE_SPLIT_B,
894
0
        0,
895
0
        &instruction_ref,
896
0
        &split_offset_ref));
897
898
0
    FAIL_ON_ERROR(
899
0
        _yr_re_emit(emit_context, re_node->children_head, flags, NULL));
900
901
0
    bookmark_1 = yr_arena_get_current_offset(
902
0
        emit_context->arena, YR_RE_CODE_SECTION);
903
904
0
    if (instruction_ref.offset - bookmark_1 < INT16_MIN)
905
0
      return ERROR_REGULAR_EXPRESSION_TOO_LARGE;
906
907
0
    jmp_offset = (int16_t) (instruction_ref.offset - bookmark_1);
908
909
    // Emit jump with offset set to 0.
910
911
0
    FAIL_ON_ERROR(_yr_emit_inst_arg_int16(
912
0
        emit_context, RE_OPCODE_JUMP, jmp_offset, NULL, NULL));
913
914
0
    bookmark_1 = yr_arena_get_current_offset(
915
0
        emit_context->arena, YR_RE_CODE_SECTION);
916
917
0
    if (bookmark_1 - instruction_ref.offset > INT16_MAX)
918
0
      return ERROR_REGULAR_EXPRESSION_TOO_LARGE;
919
920
0
    jmp_offset = (int16_t) (bookmark_1 - instruction_ref.offset);
921
922
    // Update split offset.
923
0
    split_offset_addr =
924
0
        yr_arena_ref_to_ptr(emit_context->arena, &split_offset_ref);
925
926
0
    memcpy(split_offset_addr, &jmp_offset, sizeof(jmp_offset));
927
0
    break;
928
929
0
  case RE_NODE_ALT:
930
    // Code for e1|e2 looks like:
931
    //
932
    //              split L1, L2
933
    //          L1: code for e1
934
    //              jmp L3
935
    //          L2: code for e2
936
    //          L3:
937
938
    // Emit a split instruction with offset set to 0 temporarily. Offset
939
    // will be updated after we know the size of the code generated for
940
    // the left node (e1).
941
942
0
    FAIL_ON_ERROR(_yr_emit_split(
943
0
        emit_context,
944
0
        RE_OPCODE_SPLIT_A,
945
0
        0,
946
0
        &instruction_ref,
947
0
        &split_offset_ref));
948
949
0
    FAIL_ON_ERROR(
950
0
        _yr_re_emit(emit_context, re_node->children_head, flags, NULL));
951
952
    // Emit jump with offset set to 0.
953
954
0
    FAIL_ON_ERROR(_yr_emit_inst_arg_int16(
955
0
        emit_context,
956
0
        RE_OPCODE_JUMP,
957
0
        0,
958
0
        &jmp_instruction_ref,
959
0
        &jmp_offset_ref));
960
961
0
    bookmark_1 = yr_arena_get_current_offset(
962
0
        emit_context->arena, YR_RE_CODE_SECTION);
963
964
0
    if (bookmark_1 - instruction_ref.offset > INT16_MAX)
965
0
      return ERROR_REGULAR_EXPRESSION_TOO_LARGE;
966
967
0
    jmp_offset = (int16_t) (bookmark_1 - instruction_ref.offset);
968
969
    // Update split offset.
970
0
    split_offset_addr =
971
0
        yr_arena_ref_to_ptr(emit_context->arena, &split_offset_ref);
972
973
0
    memcpy(split_offset_addr, &jmp_offset, sizeof(jmp_offset));
974
975
0
    FAIL_ON_ERROR(
976
0
        _yr_re_emit(emit_context, re_node->children_tail, flags, NULL));
977
978
0
    bookmark_1 = yr_arena_get_current_offset(
979
0
        emit_context->arena, YR_RE_CODE_SECTION);
980
981
0
    if (bookmark_1 - jmp_instruction_ref.offset > INT16_MAX)
982
0
      return ERROR_REGULAR_EXPRESSION_TOO_LARGE;
983
984
0
    jmp_offset = (int16_t) (bookmark_1 - jmp_instruction_ref.offset);
985
986
    // Update offset for jmp instruction.
987
0
    jmp_offset_addr = yr_arena_ref_to_ptr(emit_context->arena, &jmp_offset_ref);
988
989
0
    memcpy(jmp_offset_addr, &jmp_offset, sizeof(jmp_offset));
990
0
    break;
991
992
0
  case RE_NODE_RANGE_ANY:
993
0
    repeat_any_args.min = re_node->start;
994
0
    repeat_any_args.max = re_node->end;
995
996
0
    FAIL_ON_ERROR(_yr_emit_inst_arg_struct(
997
0
        emit_context,
998
0
        re_node->greedy ? RE_OPCODE_REPEAT_ANY_GREEDY
999
0
                        : RE_OPCODE_REPEAT_ANY_UNGREEDY,
1000
0
        &repeat_any_args,
1001
0
        sizeof(repeat_any_args),
1002
0
        &instruction_ref,
1003
0
        NULL));
1004
1005
0
    break;
1006
1007
0
  case RE_NODE_RANGE:
1008
    // Code for e{n,m} looks like:
1009
    //
1010
    //            code for e              ---   prolog
1011
    //            repeat_start n, m, L1   --+
1012
    //        L0: code for e                |   repeat
1013
    //            repeat_end n, m, L0     --+
1014
    //        L1: split L2, L3            ---   split
1015
    //        L2: code for e              ---   epilog
1016
    //        L3:
1017
    //
1018
    // Not all sections (prolog, repeat, split and epilog) are generated in all
1019
    // cases, it depends on the values of n and m. The following table shows
1020
    // which sections are generated for the first few values of n and m.
1021
    //
1022
    //        n,m   prolog  repeat      split  epilog
1023
    //                      (min,max)
1024
    //        ---------------------------------------
1025
    //        0,0     -       -           -      -
1026
    //        0,1     -       -           X      X
1027
    //        0,2     -       0,1         X      X
1028
    //        0,3     -       0,2         X      X
1029
    //        0,M     -       0,M-1       X      X
1030
    //
1031
    //        1,1     X       -           -      -
1032
    //        1,2     X       -           X      X
1033
    //        1,3     X       0,1         X      X
1034
    //        1,4     X       1,2         X      X
1035
    //        1,M     X       1,M-2       X      X
1036
    //
1037
    //        2,2     X       -           -      X
1038
    //        2,3     X       1,1         X      X
1039
    //        2,4     X       1,2         X      X
1040
    //        2,M     X       1,M-2       X      X
1041
    //
1042
    //        3,3     X       1,1         -      X
1043
    //        3,4     X       2,2         X      X
1044
    //        3,M     X       2,M-2       X      X
1045
    //
1046
    //        4,4     X       2,2         -      X
1047
    //        4,5     X       3,3         X      X
1048
    //        4,M     X       3,M-2       X      X
1049
    //
1050
    // The code can't consists simply in the repeat section, the prolog and
1051
    // epilog are required because we can't have atoms pointing to code inside
1052
    // the repeat loop. Atoms' forwards_code will point to code in the prolog
1053
    // and backwards_code will point to code in the epilog (or in prolog if
1054
    // epilog wasn't generated, like in n=1,m=1)
1055
1056
0
    emit_prolog = re_node->start > 0;
1057
0
    emit_repeat = re_node->end > re_node->start + 1 || re_node->end > 2;
1058
0
    emit_split = re_node->end > re_node->start;
1059
0
    emit_epilog = re_node->end > re_node->start || re_node->end > 1;
1060
1061
0
    if (emit_prolog)
1062
0
    {
1063
0
      FAIL_ON_ERROR(_yr_re_emit(
1064
0
          emit_context, re_node->children_head, flags, &instruction_ref));
1065
0
    }
1066
1067
0
    if (emit_repeat)
1068
0
    {
1069
0
      repeat_args.min = re_node->start;
1070
0
      repeat_args.max = re_node->end;
1071
1072
0
      if (emit_prolog)
1073
0
      {
1074
0
        repeat_args.max--;
1075
0
        repeat_args.min--;
1076
0
      }
1077
1078
0
      if (emit_split)
1079
0
      {
1080
0
        repeat_args.max--;
1081
0
      }
1082
0
      else
1083
0
      {
1084
0
        repeat_args.min--;
1085
0
        repeat_args.max--;
1086
0
      }
1087
1088
0
      repeat_args.offset = 0;
1089
1090
0
      bookmark_1 = yr_arena_get_current_offset(
1091
0
          emit_context->arena, YR_RE_CODE_SECTION);
1092
1093
0
      FAIL_ON_ERROR(_yr_emit_inst_arg_struct(
1094
0
          emit_context,
1095
0
          re_node->greedy ? RE_OPCODE_REPEAT_START_GREEDY
1096
0
                          : RE_OPCODE_REPEAT_START_UNGREEDY,
1097
0
          &repeat_args,
1098
0
          sizeof(repeat_args),
1099
0
          emit_prolog ? NULL : &instruction_ref,
1100
0
          &repeat_start_args_ref));
1101
1102
0
      bookmark_2 = yr_arena_get_current_offset(
1103
0
          emit_context->arena, YR_RE_CODE_SECTION);
1104
1105
0
      FAIL_ON_ERROR(_yr_re_emit(
1106
0
          emit_context,
1107
0
          re_node->children_head,
1108
0
          flags | EMIT_DONT_SET_FORWARDS_CODE | EMIT_DONT_SET_BACKWARDS_CODE,
1109
0
          NULL));
1110
1111
0
      bookmark_3 = yr_arena_get_current_offset(
1112
0
          emit_context->arena, YR_RE_CODE_SECTION);
1113
1114
0
      if (bookmark_2 - bookmark_3 < INT32_MIN)
1115
0
        return ERROR_REGULAR_EXPRESSION_TOO_LARGE;
1116
1117
0
      repeat_args.offset = (int32_t) (bookmark_2 - bookmark_3);
1118
1119
0
      FAIL_ON_ERROR(_yr_emit_inst_arg_struct(
1120
0
          emit_context,
1121
0
          re_node->greedy ? RE_OPCODE_REPEAT_END_GREEDY
1122
0
                          : RE_OPCODE_REPEAT_END_UNGREEDY,
1123
0
          &repeat_args,
1124
0
          sizeof(repeat_args),
1125
0
          NULL,
1126
0
          NULL));
1127
1128
0
      bookmark_4 = yr_arena_get_current_offset(
1129
0
          emit_context->arena, YR_RE_CODE_SECTION);
1130
1131
0
      repeat_start_args_addr = (RE_REPEAT_ARGS*) yr_arena_ref_to_ptr(
1132
0
          emit_context->arena, &repeat_start_args_ref);
1133
1134
0
      if (bookmark_4 - bookmark_1 > INT32_MAX)
1135
0
        return ERROR_REGULAR_EXPRESSION_TOO_LARGE;
1136
1137
0
      repeat_start_args_addr->offset = (int32_t) (bookmark_4 - bookmark_1);
1138
0
    }
1139
1140
0
    if (emit_split)
1141
0
    {
1142
0
      bookmark_1 = yr_arena_get_current_offset(
1143
0
          emit_context->arena, YR_RE_CODE_SECTION);
1144
1145
0
      FAIL_ON_ERROR(_yr_emit_split(
1146
0
          emit_context,
1147
0
          re_node->greedy ? RE_OPCODE_SPLIT_A : RE_OPCODE_SPLIT_B,
1148
0
          0,
1149
0
          NULL,
1150
0
          &split_offset_ref));
1151
0
    }
1152
1153
0
    if (emit_epilog)
1154
0
    {
1155
0
      FAIL_ON_ERROR(_yr_re_emit(
1156
0
          emit_context,
1157
0
          re_node->children_head,
1158
0
          emit_prolog ? flags | EMIT_DONT_SET_FORWARDS_CODE : flags,
1159
0
          emit_prolog || emit_repeat ? NULL : &instruction_ref));
1160
0
    }
1161
1162
0
    if (emit_split)
1163
0
    {
1164
0
      bookmark_2 = yr_arena_get_current_offset(
1165
0
          emit_context->arena, YR_RE_CODE_SECTION);
1166
1167
0
      if (bookmark_2 - bookmark_1 > INT16_MAX)
1168
0
        return ERROR_REGULAR_EXPRESSION_TOO_LARGE;
1169
1170
0
      split_offset_addr =
1171
0
          yr_arena_ref_to_ptr(emit_context->arena, &split_offset_ref);
1172
1173
0
      jmp_offset = (int16_t) (bookmark_2 - bookmark_1);
1174
1175
0
      memcpy(split_offset_addr, &jmp_offset, sizeof(jmp_offset));
1176
0
    }
1177
1178
0
    break;
1179
0
  }
1180
1181
0
  if (flags & EMIT_BACKWARDS)
1182
0
  {
1183
0
    if (!(flags & EMIT_DONT_SET_BACKWARDS_CODE))
1184
0
    {
1185
0
      re_node->backward_code_ref.buffer_id = YR_RE_CODE_SECTION;
1186
0
      re_node->backward_code_ref.offset = yr_arena_get_current_offset(
1187
0
          emit_context->arena, YR_RE_CODE_SECTION);
1188
0
    }
1189
0
  }
1190
0
  else
1191
0
  {
1192
0
    if (!(flags & EMIT_DONT_SET_FORWARDS_CODE))
1193
0
    {
1194
0
      re_node->forward_code_ref = instruction_ref;
1195
0
    }
1196
0
  }
1197
1198
0
  if (code_ref != NULL)
1199
0
    *code_ref = instruction_ref;
1200
1201
0
  return ERROR_SUCCESS;
1202
0
}
1203
1204
int yr_re_ast_emit_code(RE_AST* re_ast, YR_ARENA* arena, int backwards_code)
1205
0
{
1206
0
  RE_EMIT_CONTEXT emit_context;
1207
1208
  // Emit code for matching the regular expressions forwards.
1209
0
  emit_context.arena = arena;
1210
0
  emit_context.next_split_id = 0;
1211
1212
0
  FAIL_ON_ERROR(_yr_re_emit(
1213
0
      &emit_context,
1214
0
      re_ast->root_node,
1215
0
      backwards_code ? EMIT_BACKWARDS : 0,
1216
0
      NULL));
1217
1218
0
  FAIL_ON_ERROR(_yr_emit_inst(&emit_context, RE_OPCODE_MATCH, NULL));
1219
1220
0
  return ERROR_SUCCESS;
1221
0
}
1222
1223
static int _yr_re_fiber_create(RE_FIBER_POOL* fiber_pool, RE_FIBER** new_fiber)
1224
0
{
1225
0
  RE_FIBER* fiber;
1226
1227
0
  if (fiber_pool->fibers.head != NULL)
1228
0
  {
1229
0
    fiber = fiber_pool->fibers.head;
1230
0
    fiber_pool->fibers.head = fiber->next;
1231
1232
0
    if (fiber_pool->fibers.tail == fiber)
1233
0
      fiber_pool->fibers.tail = NULL;
1234
0
  }
1235
0
  else
1236
0
  {
1237
0
    if (fiber_pool->fiber_count == RE_MAX_FIBERS)
1238
0
      return ERROR_TOO_MANY_RE_FIBERS;
1239
1240
0
    fiber = (RE_FIBER*) yr_malloc(sizeof(RE_FIBER));
1241
1242
0
    if (fiber == NULL)
1243
0
      return ERROR_INSUFFICIENT_MEMORY;
1244
1245
0
    fiber_pool->fiber_count++;
1246
0
  }
1247
1248
0
  fiber->ip = NULL;
1249
0
  fiber->sp = -1;
1250
0
  fiber->rc = -1;
1251
0
  fiber->next = NULL;
1252
0
  fiber->prev = NULL;
1253
1254
0
  *new_fiber = fiber;
1255
1256
0
  return ERROR_SUCCESS;
1257
0
}
1258
1259
////////////////////////////////////////////////////////////////////////////////
1260
// Appends 'fiber' to 'fiber_list'
1261
//
1262
static void _yr_re_fiber_append(RE_FIBER_LIST* fiber_list, RE_FIBER* fiber)
1263
0
{
1264
0
  assert(fiber->prev == NULL);
1265
0
  assert(fiber->next == NULL);
1266
1267
0
  fiber->prev = fiber_list->tail;
1268
1269
0
  if (fiber_list->tail != NULL)
1270
0
    fiber_list->tail->next = fiber;
1271
1272
0
  fiber_list->tail = fiber;
1273
1274
0
  if (fiber_list->head == NULL)
1275
0
    fiber_list->head = fiber;
1276
1277
0
  assert(fiber_list->tail->next == NULL);
1278
0
  assert(fiber_list->head->prev == NULL);
1279
0
}
1280
1281
////////////////////////////////////////////////////////////////////////////////
1282
// Verifies if a fiber with the same properties (ip, rc, sp, and stack values)
1283
// than 'target_fiber' exists in 'fiber_list'. The list is iterated from
1284
// the start until 'last_fiber' (inclusive). Fibers past 'last_fiber' are not
1285
// taken into account.
1286
//
1287
static int _yr_re_fiber_exists(
1288
    RE_FIBER_LIST* fiber_list,
1289
    RE_FIBER* target_fiber,
1290
    RE_FIBER* last_fiber)
1291
0
{
1292
0
  RE_FIBER* fiber = fiber_list->head;
1293
1294
0
  int equal_stacks;
1295
0
  int i;
1296
1297
0
  if (last_fiber == NULL)
1298
0
    return false;
1299
1300
0
  while (fiber != last_fiber->next)
1301
0
  {
1302
0
    if (fiber->ip == target_fiber->ip && fiber->sp == target_fiber->sp &&
1303
0
        fiber->rc == target_fiber->rc)
1304
0
    {
1305
0
      equal_stacks = true;
1306
1307
0
      for (i = 0; i <= fiber->sp; i++)
1308
0
      {
1309
0
        if (fiber->stack[i] != target_fiber->stack[i])
1310
0
        {
1311
0
          equal_stacks = false;
1312
0
          break;
1313
0
        }
1314
0
      }
1315
1316
0
      if (equal_stacks)
1317
0
        return true;
1318
0
    }
1319
1320
0
    fiber = fiber->next;
1321
0
  }
1322
1323
0
  return false;
1324
0
}
1325
1326
////////////////////////////////////////////////////////////////////////////////
1327
// Clones a fiber in fiber_list and inserts the cloned fiber just after.
1328
// the original one. If fiber_list is:
1329
//
1330
//   f1 -> f2 -> f3 -> f4
1331
//
1332
// Splitting f2 will result in:
1333
//
1334
//   f1 -> f2 -> cloned f2 -> f3 -> f4
1335
//
1336
static int _yr_re_fiber_split(
1337
    RE_FIBER_LIST* fiber_list,
1338
    RE_FIBER_POOL* fiber_pool,
1339
    RE_FIBER* fiber,
1340
    RE_FIBER** new_fiber)
1341
0
{
1342
0
  int32_t i;
1343
1344
0
  FAIL_ON_ERROR(_yr_re_fiber_create(fiber_pool, new_fiber));
1345
1346
0
  (*new_fiber)->sp = fiber->sp;
1347
0
  (*new_fiber)->ip = fiber->ip;
1348
0
  (*new_fiber)->rc = fiber->rc;
1349
1350
0
  for (i = 0; i <= fiber->sp; i++) (*new_fiber)->stack[i] = fiber->stack[i];
1351
1352
0
  (*new_fiber)->next = fiber->next;
1353
0
  (*new_fiber)->prev = fiber;
1354
1355
0
  if (fiber->next != NULL)
1356
0
    fiber->next->prev = *new_fiber;
1357
1358
0
  fiber->next = *new_fiber;
1359
1360
0
  if (fiber_list->tail == fiber)
1361
0
    fiber_list->tail = *new_fiber;
1362
1363
0
  assert(fiber_list->tail->next == NULL);
1364
0
  assert(fiber_list->head->prev == NULL);
1365
1366
0
  return ERROR_SUCCESS;
1367
0
}
1368
1369
////////////////////////////////////////////////////////////////////////////////
1370
// Kills a given fiber by removing it from the fiber list and putting it in the
1371
// fiber pool.
1372
//
1373
static RE_FIBER* _yr_re_fiber_kill(
1374
    RE_FIBER_LIST* fiber_list,
1375
    RE_FIBER_POOL* fiber_pool,
1376
    RE_FIBER* fiber)
1377
0
{
1378
0
  RE_FIBER* next_fiber = fiber->next;
1379
1380
0
  if (fiber->prev != NULL)
1381
0
    fiber->prev->next = next_fiber;
1382
1383
0
  if (next_fiber != NULL)
1384
0
    next_fiber->prev = fiber->prev;
1385
1386
0
  if (fiber_pool->fibers.tail != NULL)
1387
0
    fiber_pool->fibers.tail->next = fiber;
1388
1389
0
  if (fiber_list->tail == fiber)
1390
0
    fiber_list->tail = fiber->prev;
1391
1392
0
  if (fiber_list->head == fiber)
1393
0
    fiber_list->head = next_fiber;
1394
1395
0
  fiber->next = NULL;
1396
0
  fiber->prev = fiber_pool->fibers.tail;
1397
0
  fiber_pool->fibers.tail = fiber;
1398
1399
0
  if (fiber_pool->fibers.head == NULL)
1400
0
    fiber_pool->fibers.head = fiber;
1401
1402
0
  return next_fiber;
1403
0
}
1404
1405
////////////////////////////////////////////////////////////////////////////////
1406
// Kills all fibers from the given one up to the end of the fiber list.
1407
//
1408
static void _yr_re_fiber_kill_tail(
1409
    RE_FIBER_LIST* fiber_list,
1410
    RE_FIBER_POOL* fiber_pool,
1411
    RE_FIBER* fiber)
1412
0
{
1413
0
  RE_FIBER* prev_fiber = fiber->prev;
1414
1415
0
  if (prev_fiber != NULL)
1416
0
    prev_fiber->next = NULL;
1417
1418
0
  fiber->prev = fiber_pool->fibers.tail;
1419
1420
0
  if (fiber_pool->fibers.tail != NULL)
1421
0
    fiber_pool->fibers.tail->next = fiber;
1422
1423
0
  fiber_pool->fibers.tail = fiber_list->tail;
1424
0
  fiber_list->tail = prev_fiber;
1425
1426
0
  if (fiber_list->head == fiber)
1427
0
    fiber_list->head = NULL;
1428
1429
0
  if (fiber_pool->fibers.head == NULL)
1430
0
    fiber_pool->fibers.head = fiber;
1431
0
}
1432
1433
////////////////////////////////////////////////////////////////////////////////
1434
// Kills all fibers in the fiber list.
1435
//
1436
static void _yr_re_fiber_kill_all(
1437
    RE_FIBER_LIST* fiber_list,
1438
    RE_FIBER_POOL* fiber_pool)
1439
0
{
1440
0
  if (fiber_list->head != NULL)
1441
0
    _yr_re_fiber_kill_tail(fiber_list, fiber_pool, fiber_list->head);
1442
0
}
1443
1444
////////////////////////////////////////////////////////////////////////////////
1445
// Executes a fiber until reaching an "matching" instruction. A "matching"
1446
// instruction is one that actually reads a byte from the input and performs
1447
// some matching. If the fiber reaches a split instruction, the new fiber is
1448
// also synced.
1449
//
1450
static int _yr_re_fiber_sync(
1451
    RE_FIBER_LIST* fiber_list,
1452
    RE_FIBER_POOL* fiber_pool,
1453
    RE_FIBER* fiber_to_sync)
1454
0
{
1455
  // A array for keeping track of which split instructions has been already
1456
  // executed. Each split instruction within a regexp has an associated ID
1457
  // between 0 and RE_MAX_SPLIT_ID-1. Keeping track of executed splits is
1458
  // required to avoid infinite loops in regexps like (a*)* or (a|)*
1459
1460
0
  RE_SPLIT_ID_TYPE splits_executed[RE_MAX_SPLIT_ID];
1461
0
  RE_SPLIT_ID_TYPE splits_executed_count = 0;
1462
0
  RE_SPLIT_ID_TYPE split_id, splits_executed_idx;
1463
1464
0
  int split_already_executed;
1465
1466
0
  RE_REPEAT_ARGS* repeat_args;
1467
0
  RE_REPEAT_ANY_ARGS* repeat_any_args;
1468
1469
0
  RE_FIBER* fiber;
1470
0
  RE_FIBER* last;
1471
0
  RE_FIBER* next;
1472
0
  RE_FIBER* branch_a;
1473
0
  RE_FIBER* branch_b;
1474
1475
0
  fiber = fiber_to_sync;
1476
0
  last = fiber_to_sync->next;
1477
1478
0
  while (fiber != last)
1479
0
  {
1480
0
    int16_t jmp_len;
1481
0
    uint8_t opcode = *fiber->ip;
1482
1483
0
    switch (opcode)
1484
0
    {
1485
0
    case RE_OPCODE_SPLIT_A:
1486
0
    case RE_OPCODE_SPLIT_B:
1487
1488
0
      split_id = *(RE_SPLIT_ID_TYPE*) (fiber->ip + 1);
1489
0
      split_already_executed = false;
1490
1491
0
      for (splits_executed_idx = 0; splits_executed_idx < splits_executed_count;
1492
0
           splits_executed_idx++)
1493
0
      {
1494
0
        if (split_id == splits_executed[splits_executed_idx])
1495
0
        {
1496
0
          split_already_executed = true;
1497
0
          break;
1498
0
        }
1499
0
      }
1500
1501
0
      if (split_already_executed)
1502
0
      {
1503
0
        fiber = _yr_re_fiber_kill(fiber_list, fiber_pool, fiber);
1504
0
      }
1505
0
      else
1506
0
      {
1507
0
        branch_a = fiber;
1508
1509
0
        FAIL_ON_ERROR(
1510
0
            _yr_re_fiber_split(fiber_list, fiber_pool, branch_a, &branch_b));
1511
1512
        // With RE_OPCODE_SPLIT_A the current fiber continues at the next
1513
        // instruction in the stream (branch A), while the newly created
1514
        // fiber starts at the address indicated by the instruction (branch B)
1515
        // RE_OPCODE_SPLIT_B has the opposite behavior.
1516
1517
0
        if (opcode == RE_OPCODE_SPLIT_B)
1518
0
          yr_swap(branch_a, branch_b, RE_FIBER*);
1519
1520
        // Branch A continues at the next instruction
1521
0
        branch_a->ip += (sizeof(RE_SPLIT_ID_TYPE) + 3);
1522
1523
        // Branch B adds the offset indicated by the split instruction.
1524
0
        jmp_len = yr_unaligned_i16(branch_b->ip + 1 + sizeof(RE_SPLIT_ID_TYPE));
1525
1526
0
        branch_b->ip += jmp_len;
1527
1528
0
#if YR_PARANOID_EXEC
1529
        // In normal conditions this should never happen. But with compiled
1530
        // rules that has been hand-crafted by a malicious actor this could
1531
        // happen.
1532
0
        if (splits_executed_count >= RE_MAX_SPLIT_ID)
1533
0
          return ERROR_INTERNAL_FATAL_ERROR;
1534
0
#endif
1535
1536
0
        splits_executed[splits_executed_count] = split_id;
1537
0
        splits_executed_count++;
1538
0
      }
1539
1540
0
      break;
1541
1542
0
    case RE_OPCODE_REPEAT_START_GREEDY:
1543
0
    case RE_OPCODE_REPEAT_START_UNGREEDY:
1544
1545
0
      repeat_args = (RE_REPEAT_ARGS*) (fiber->ip + 1);
1546
0
      assert(repeat_args->max > 0);
1547
0
      branch_a = fiber;
1548
1549
0
      if (repeat_args->min == 0)
1550
0
      {
1551
0
        FAIL_ON_ERROR(
1552
0
            _yr_re_fiber_split(fiber_list, fiber_pool, branch_a, &branch_b));
1553
1554
0
        if (opcode == RE_OPCODE_REPEAT_START_UNGREEDY)
1555
0
          yr_swap(branch_a, branch_b, RE_FIBER*);
1556
1557
0
        branch_b->ip += repeat_args->offset;
1558
0
      }
1559
1560
0
#if YR_PARANOID_EXEC
1561
      // In normal conditions this should never happen. But with compiled
1562
      // rules that has been hand-crafted by a malicious actor this could
1563
      // happen.
1564
0
      if (branch_a->sp >= RE_MAX_STACK - 1)
1565
0
        return ERROR_INTERNAL_FATAL_ERROR;
1566
0
#endif
1567
1568
0
      branch_a->stack[++branch_a->sp] = 0;
1569
0
      branch_a->ip += (1 + sizeof(RE_REPEAT_ARGS));
1570
0
      break;
1571
1572
0
    case RE_OPCODE_REPEAT_END_GREEDY:
1573
0
    case RE_OPCODE_REPEAT_END_UNGREEDY:
1574
1575
0
      repeat_args = (RE_REPEAT_ARGS*) (fiber->ip + 1);
1576
1577
0
#if YR_PARANOID_EXEC
1578
      // A REPEAT_END with no matching REPEAT_START leaves sp at -1 and the
1579
      // access below would read and write before the stack. In normal
1580
      // conditions this never happens, but it can with compiled rules that
1581
      // have been hand-crafted by a malicious actor.
1582
0
      if (fiber->sp < 0)
1583
0
        return ERROR_INTERNAL_FATAL_ERROR;
1584
0
#endif
1585
1586
0
      fiber->stack[fiber->sp]++;
1587
1588
0
      if (fiber->stack[fiber->sp] < repeat_args->min)
1589
0
      {
1590
0
        fiber->ip += repeat_args->offset;
1591
0
        break;
1592
0
      }
1593
1594
0
      branch_a = fiber;
1595
1596
0
      if (fiber->stack[fiber->sp] < repeat_args->max)
1597
0
      {
1598
0
        FAIL_ON_ERROR(
1599
0
            _yr_re_fiber_split(fiber_list, fiber_pool, branch_a, &branch_b));
1600
1601
0
        if (opcode == RE_OPCODE_REPEAT_END_GREEDY)
1602
0
          yr_swap(branch_a, branch_b, RE_FIBER*);
1603
1604
0
        branch_b->ip += repeat_args->offset;
1605
0
      }
1606
1607
0
      branch_a->sp--;
1608
0
      branch_a->ip += (1 + sizeof(RE_REPEAT_ARGS));
1609
0
      break;
1610
1611
0
    case RE_OPCODE_REPEAT_ANY_GREEDY:
1612
0
    case RE_OPCODE_REPEAT_ANY_UNGREEDY:
1613
1614
0
      repeat_any_args = (RE_REPEAT_ANY_ARGS*) (fiber->ip + 1);
1615
1616
      // If repetition counter (rc) is -1 it means that we are reaching this
1617
      // instruction from the previous one in the instructions stream. In
1618
      // this case let's initialize the counter to 0 and start looping.
1619
1620
0
      if (fiber->rc == -1)
1621
0
        fiber->rc = 0;
1622
1623
0
      if (fiber->rc < repeat_any_args->min)
1624
0
      {
1625
        // Increase repetition counter and continue with next fiber. The
1626
        // instruction pointer for this fiber is not incremented yet, this
1627
        // fiber spins in this same instruction until reaching the minimum
1628
        // number of repetitions.
1629
1630
0
        fiber->rc++;
1631
0
        fiber = fiber->next;
1632
0
      }
1633
0
      else if (fiber->rc < repeat_any_args->max)
1634
0
      {
1635
        // Once the minimum number of repetitions are matched one fiber
1636
        // remains spinning in this instruction until reaching the maximum
1637
        // number of repetitions while new fibers are created. New fibers
1638
        // start executing at the next instruction.
1639
1640
0
        next = fiber->next;
1641
0
        branch_a = fiber;
1642
1643
0
        FAIL_ON_ERROR(
1644
0
            _yr_re_fiber_split(fiber_list, fiber_pool, branch_a, &branch_b));
1645
1646
0
        if (opcode == RE_OPCODE_REPEAT_ANY_UNGREEDY)
1647
0
          yr_swap(branch_a, branch_b, RE_FIBER*);
1648
1649
0
        branch_a->rc++;
1650
0
        branch_b->ip += (1 + sizeof(RE_REPEAT_ANY_ARGS));
1651
0
        branch_b->rc = -1;
1652
1653
0
        FAIL_ON_ERROR(_yr_re_fiber_sync(fiber_list, fiber_pool, branch_b));
1654
1655
0
        fiber = next;
1656
0
      }
1657
0
      else
1658
0
      {
1659
        // When the maximum number of repetitions is reached the fiber keeps
1660
        // executing at the next instruction. The repetition counter is set
1661
        // to -1 indicating that we are not spinning in a repeat instruction
1662
        // anymore.
1663
1664
0
        fiber->ip += (1 + sizeof(RE_REPEAT_ANY_ARGS));
1665
0
        fiber->rc = -1;
1666
0
      }
1667
1668
0
      break;
1669
1670
0
    case RE_OPCODE_JUMP:
1671
0
      jmp_len = yr_unaligned_i16(fiber->ip + 1);
1672
0
      fiber->ip += jmp_len;
1673
0
      break;
1674
1675
0
    default:
1676
0
      fiber = fiber->next;
1677
0
    }
1678
0
  }
1679
1680
0
  return ERROR_SUCCESS;
1681
0
}
1682
1683
////////////////////////////////////////////////////////////////////////////////
1684
// Executes a regular expression. The specified regular expression will try to
1685
// match the data starting at the address specified by "input". The "input"
1686
// pointer can point to any address inside a memory buffer. Arguments
1687
// "input_forwards_size" and "input_backwards_size" indicate how many bytes
1688
// can be accessible starting at "input" and going forwards and backwards
1689
// respectively.
1690
//
1691
//   <--- input_backwards_size -->|<----------- input_forwards_size -------->
1692
//  |--------  memory buffer  -----------------------------------------------|
1693
//                                ^
1694
//                              input
1695
//
1696
// Args:
1697
//   YR_SCAN_CONTEXT *context         - Scan context.
1698
//   const uint8_t* code              - Regexp code be executed
1699
//   const uint8_t* input             - Pointer to input data
1700
//   size_t input_forwards_size       - Number of accessible bytes starting at
1701
//                                      "input" and going forwards.
1702
//   size_t input_backwards_size      - Number of accessible bytes starting at
1703
//                                      "input" and going backwards
1704
//   int flags                        - Flags:
1705
//      RE_FLAGS_SCAN
1706
//      RE_FLAGS_BACKWARDS
1707
//      RE_FLAGS_EXHAUSTIVE
1708
//      RE_FLAGS_WIDE
1709
//      RE_FLAGS_NO_CASE
1710
//      RE_FLAGS_DOT_ALL
1711
//   RE_MATCH_CALLBACK_FUNC callback  - Callback function
1712
//   void* callback_args              - Callback argument
1713
//   int*  matches                    - Pointer to an integer receiving the
1714
//                                      number of matching bytes. Notice that
1715
//                                      0 means a zero-length match, while no
1716
//                                      matches is -1.
1717
// Returns:
1718
//    ERROR_SUCCESS or any other error code.
1719
1720
int yr_re_exec(
1721
    YR_SCAN_CONTEXT* context,
1722
    const uint8_t* code,
1723
    const uint8_t* input_data,
1724
    size_t input_forwards_size,
1725
    size_t input_backwards_size,
1726
    int flags,
1727
    RE_MATCH_CALLBACK_FUNC callback,
1728
    void* callback_args,
1729
    int* matches)
1730
0
{
1731
0
  const uint8_t* input;
1732
0
  const uint8_t* ip;
1733
1734
0
  uint16_t opcode_args;
1735
0
  uint8_t mask;
1736
0
  uint8_t value;
1737
0
  uint8_t character_size;
1738
1739
0
  RE_FIBER_LIST fibers;
1740
0
  RE_FIBER* fiber;
1741
0
  RE_FIBER* next_fiber;
1742
1743
0
  int bytes_matched;
1744
0
  int max_bytes_matched;
1745
1746
0
  int match;
1747
0
  int input_incr;
1748
0
  int kill;
1749
0
  int action;
1750
1751
0
  bool prev_is_word_char = false;
1752
0
  bool input_is_word_char = false;
1753
1754
0
#define ACTION_NONE      0
1755
0
#define ACTION_CONTINUE  1
1756
0
#define ACTION_KILL      2
1757
0
#define ACTION_KILL_TAIL 3
1758
1759
0
#define prolog                                      \
1760
0
  {                                                 \
1761
0
    if ((bytes_matched >= max_bytes_matched) ||     \
1762
0
        (character_size == 2 && *(input + 1) != 0)) \
1763
0
    {                                               \
1764
0
      action = ACTION_KILL;                         \
1765
0
      break;                                        \
1766
0
    }                                               \
1767
0
  }
1768
1769
0
  if (matches != NULL)
1770
0
    *matches = -1;
1771
1772
0
  if (flags & RE_FLAGS_WIDE)
1773
0
    character_size = 2;
1774
0
  else
1775
0
    character_size = 1;
1776
1777
0
  input = input_data;
1778
0
  input_incr = character_size;
1779
1780
0
  if (flags & RE_FLAGS_BACKWARDS)
1781
0
  {
1782
    // Signedness conversion is sound as long as YR_RE_SCAN_LIMIT <= INT_MAX
1783
0
    max_bytes_matched = (int) yr_min(input_backwards_size, YR_RE_SCAN_LIMIT);
1784
0
    input -= character_size;
1785
0
    input_incr = -input_incr;
1786
0
  }
1787
0
  else
1788
0
  {
1789
    // Signedness conversion is sound as long as YR_RE_SCAN_LIMIT <= INT_MAX
1790
0
    max_bytes_matched = (int) yr_min(input_forwards_size, YR_RE_SCAN_LIMIT);
1791
0
  }
1792
1793
  // Round down max_bytes_matched to a multiple of character_size, this way if
1794
  // character_size is 2 and max_bytes_matched is odd we are ignoring the
1795
  // extra byte which can't match anyways.
1796
1797
0
  max_bytes_matched = max_bytes_matched - max_bytes_matched % character_size;
1798
0
  bytes_matched = 0;
1799
1800
0
  FAIL_ON_ERROR(_yr_re_fiber_create(&context->re_fiber_pool, &fiber));
1801
1802
0
  fiber->ip = code;
1803
0
  fibers.head = fiber;
1804
0
  fibers.tail = fiber;
1805
1806
0
  FAIL_ON_ERROR_WITH_CLEANUP(
1807
0
      _yr_re_fiber_sync(&fibers, &context->re_fiber_pool, fiber),
1808
0
      _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
1809
1810
0
  while (fibers.head != NULL)
1811
0
  {
1812
0
    fiber = fibers.head;
1813
1814
0
    while (fiber != NULL)
1815
0
    {
1816
0
      next_fiber = fiber->next;
1817
1818
0
      if (_yr_re_fiber_exists(&fibers, fiber, fiber->prev))
1819
0
        _yr_re_fiber_kill(&fibers, &context->re_fiber_pool, fiber);
1820
1821
0
      fiber = next_fiber;
1822
0
    }
1823
1824
0
    fiber = fibers.head;
1825
1826
0
    while (fiber != NULL)
1827
0
    {
1828
0
      ip = fiber->ip;
1829
0
      action = ACTION_NONE;
1830
1831
0
      switch (*ip)
1832
0
      {
1833
0
      case RE_OPCODE_ANY:
1834
0
        prolog;
1835
0
        match = (flags & RE_FLAGS_DOT_ALL) || (*input != 0x0A);
1836
0
        action = match ? ACTION_NONE : ACTION_KILL;
1837
0
        fiber->ip += 1;
1838
0
        break;
1839
1840
0
      case RE_OPCODE_REPEAT_ANY_GREEDY:
1841
0
      case RE_OPCODE_REPEAT_ANY_UNGREEDY:
1842
0
        prolog;
1843
0
        match = (flags & RE_FLAGS_DOT_ALL) || (*input != 0x0A);
1844
0
        action = match ? ACTION_NONE : ACTION_KILL;
1845
1846
        // The instruction pointer is not incremented here. The current fiber
1847
        // spins in this instruction until reaching the required number of
1848
        // repetitions. The code controlling the number of repetitions is in
1849
        // _yr_re_fiber_sync.
1850
1851
0
        break;
1852
1853
0
      case RE_OPCODE_LITERAL:
1854
0
        prolog;
1855
0
        if (flags & RE_FLAGS_NO_CASE)
1856
0
          match = yr_lowercase[*input] == yr_lowercase[*(ip + 1)];
1857
0
        else
1858
0
          match = (*input == *(ip + 1));
1859
0
        action = match ? ACTION_NONE : ACTION_KILL;
1860
0
        fiber->ip += 2;
1861
0
        break;
1862
1863
0
      case RE_OPCODE_NOT_LITERAL:
1864
0
        prolog;
1865
1866
        // We don't need to take into account the case-insensitive
1867
        // case because this opcode is only used with hex strings,
1868
        // which can't be case-insensitive.
1869
1870
0
        match = (*input != *(ip + 1));
1871
0
        action = match ? ACTION_NONE : ACTION_KILL;
1872
0
        fiber->ip += 2;
1873
0
        break;
1874
1875
0
      case RE_OPCODE_MASKED_LITERAL:
1876
0
        prolog;
1877
0
        opcode_args = yr_unaligned_u16(ip + 1);
1878
0
        mask = opcode_args >> 8;
1879
0
        value = opcode_args & 0xFF;
1880
1881
        // We don't need to take into account the case-insensitive
1882
        // case because this opcode is only used with hex strings,
1883
        // which can't be case-insensitive.
1884
1885
0
        match = ((*input & mask) == value);
1886
0
        action = match ? ACTION_NONE : ACTION_KILL;
1887
0
        fiber->ip += 3;
1888
0
        break;
1889
1890
0
      case RE_OPCODE_MASKED_NOT_LITERAL:
1891
0
        prolog;
1892
0
        opcode_args = yr_unaligned_u16(ip + 1);
1893
0
        mask = opcode_args >> 8;
1894
0
        value = opcode_args & 0xFF;
1895
1896
        // We don't need to take into account the case-insensitive
1897
        // case because this opcode is only used with hex strings,
1898
        // which can't be case-insensitive.
1899
1900
0
        match = ((*input & mask) != value);
1901
0
        action = match ? ACTION_NONE : ACTION_KILL;
1902
0
        fiber->ip += 3;
1903
0
        break;
1904
1905
0
      case RE_OPCODE_CLASS:
1906
0
        prolog;
1907
0
        match = _yr_re_is_char_in_class(
1908
0
            (RE_CLASS*) (ip + 1), *input, flags & RE_FLAGS_NO_CASE);
1909
0
        action = match ? ACTION_NONE : ACTION_KILL;
1910
0
        fiber->ip += (sizeof(RE_CLASS) + 1);
1911
0
        break;
1912
1913
0
      case RE_OPCODE_WORD_CHAR:
1914
0
        prolog;
1915
0
        match = _yr_re_is_word_char(input, character_size);
1916
0
        action = match ? ACTION_NONE : ACTION_KILL;
1917
0
        fiber->ip += 1;
1918
0
        break;
1919
1920
0
      case RE_OPCODE_NON_WORD_CHAR:
1921
0
        prolog;
1922
0
        match = !_yr_re_is_word_char(input, character_size);
1923
0
        action = match ? ACTION_NONE : ACTION_KILL;
1924
0
        fiber->ip += 1;
1925
0
        break;
1926
1927
0
      case RE_OPCODE_SPACE:
1928
0
      case RE_OPCODE_NON_SPACE:
1929
1930
0
        prolog;
1931
1932
0
        switch (*input)
1933
0
        {
1934
0
        case ' ':
1935
0
        case '\t':
1936
0
        case '\r':
1937
0
        case '\n':
1938
0
        case '\v':
1939
0
        case '\f':
1940
0
          match = true;
1941
0
          break;
1942
0
        default:
1943
0
          match = false;
1944
0
        }
1945
1946
0
        if (*ip == RE_OPCODE_NON_SPACE)
1947
0
          match = !match;
1948
1949
0
        action = match ? ACTION_NONE : ACTION_KILL;
1950
0
        fiber->ip += 1;
1951
0
        break;
1952
1953
0
      case RE_OPCODE_DIGIT:
1954
0
        prolog;
1955
0
        match = isdigit(*input);
1956
0
        action = match ? ACTION_NONE : ACTION_KILL;
1957
0
        fiber->ip += 1;
1958
0
        break;
1959
1960
0
      case RE_OPCODE_NON_DIGIT:
1961
0
        prolog;
1962
0
        match = !isdigit(*input);
1963
0
        action = match ? ACTION_NONE : ACTION_KILL;
1964
0
        fiber->ip += 1;
1965
0
        break;
1966
1967
0
      case RE_OPCODE_WORD_BOUNDARY:
1968
0
      case RE_OPCODE_NON_WORD_BOUNDARY:
1969
0
        if (input - input_incr + character_size <=
1970
0
                input_data + input_forwards_size &&
1971
0
            input - input_incr >= input_data - input_backwards_size)
1972
0
        {
1973
0
          prev_is_word_char = _yr_re_is_word_char(
1974
0
              input - input_incr, character_size);
1975
0
        }
1976
0
        else
1977
0
        {
1978
0
          prev_is_word_char = false;
1979
0
        }
1980
1981
0
        if (input + character_size <= input_data + input_forwards_size &&
1982
0
            input >= input_data - input_backwards_size)
1983
0
        {
1984
0
          input_is_word_char = _yr_re_is_word_char(input, character_size);
1985
0
        }
1986
0
        else
1987
0
        {
1988
0
          input_is_word_char = false;
1989
0
        }
1990
1991
0
        match = (prev_is_word_char && !input_is_word_char) ||
1992
0
                (!prev_is_word_char && input_is_word_char);
1993
1994
0
        if (*ip == RE_OPCODE_NON_WORD_BOUNDARY)
1995
0
          match = !match;
1996
1997
0
        action = match ? ACTION_CONTINUE : ACTION_KILL;
1998
0
        fiber->ip += 1;
1999
0
        break;
2000
2001
0
      case RE_OPCODE_MATCH_AT_START:
2002
0
        if (flags & RE_FLAGS_BACKWARDS)
2003
0
          kill = input_backwards_size > (size_t) bytes_matched;
2004
0
        else
2005
0
          kill = input_backwards_size > 0 || (bytes_matched != 0);
2006
0
        action = kill ? ACTION_KILL : ACTION_CONTINUE;
2007
0
        fiber->ip += 1;
2008
0
        break;
2009
2010
0
      case RE_OPCODE_MATCH_AT_END:
2011
0
        kill = flags & RE_FLAGS_BACKWARDS ||
2012
0
               input_forwards_size > (size_t) bytes_matched;
2013
0
        action = kill ? ACTION_KILL : ACTION_CONTINUE;
2014
0
        fiber->ip += 1;
2015
0
        break;
2016
2017
0
      case RE_OPCODE_MATCH:
2018
2019
0
        if (matches != NULL)
2020
0
          *matches = bytes_matched;
2021
2022
0
        if (flags & RE_FLAGS_EXHAUSTIVE)
2023
0
        {
2024
0
          if (callback != NULL)
2025
0
          {
2026
0
            if (flags & RE_FLAGS_BACKWARDS)
2027
0
            {
2028
0
              FAIL_ON_ERROR_WITH_CLEANUP(
2029
0
                  callback(
2030
0
                      input + character_size,
2031
0
                      bytes_matched,
2032
0
                      flags,
2033
0
                      callback_args),
2034
0
                  _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2035
0
            }
2036
0
            else
2037
0
            {
2038
0
              FAIL_ON_ERROR_WITH_CLEANUP(
2039
0
                  callback(input_data, bytes_matched, flags, callback_args),
2040
0
                  _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2041
0
            }
2042
0
          }
2043
2044
0
          action = ACTION_KILL;
2045
0
        }
2046
0
        else
2047
0
        {
2048
0
          action = ACTION_KILL_TAIL;
2049
0
        }
2050
2051
0
        break;
2052
2053
0
      default:
2054
0
        assert(false);
2055
0
      }
2056
2057
0
      switch (action)
2058
0
      {
2059
0
      case ACTION_KILL:
2060
0
        fiber = _yr_re_fiber_kill(&fibers, &context->re_fiber_pool, fiber);
2061
0
        break;
2062
2063
0
      case ACTION_KILL_TAIL:
2064
0
        _yr_re_fiber_kill_tail(&fibers, &context->re_fiber_pool, fiber);
2065
0
        fiber = NULL;
2066
0
        break;
2067
2068
0
      case ACTION_CONTINUE:
2069
0
        FAIL_ON_ERROR_WITH_CLEANUP(
2070
0
            _yr_re_fiber_sync(&fibers, &context->re_fiber_pool, fiber),
2071
0
            _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2072
0
        break;
2073
2074
0
      default:
2075
0
        next_fiber = fiber->next;
2076
0
        FAIL_ON_ERROR_WITH_CLEANUP(
2077
0
            _yr_re_fiber_sync(&fibers, &context->re_fiber_pool, fiber),
2078
0
            _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2079
0
        fiber = next_fiber;
2080
0
      }
2081
0
    }
2082
2083
0
    input += input_incr;
2084
0
    bytes_matched += character_size;
2085
2086
0
    if (flags & RE_FLAGS_SCAN && bytes_matched < max_bytes_matched)
2087
0
    {
2088
0
      FAIL_ON_ERROR_WITH_CLEANUP(
2089
0
          _yr_re_fiber_create(&context->re_fiber_pool, &fiber),
2090
0
          _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2091
2092
0
      fiber->ip = code;
2093
0
      _yr_re_fiber_append(&fibers, fiber);
2094
2095
0
      FAIL_ON_ERROR_WITH_CLEANUP(
2096
0
          _yr_re_fiber_sync(&fibers, &context->re_fiber_pool, fiber),
2097
0
          _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2098
0
    }
2099
0
  }
2100
2101
0
  return ERROR_SUCCESS;
2102
0
}
2103
2104
////////////////////////////////////////////////////////////////////////////////
2105
// Helper function that creates a RE_FAST_EXEC_POSITION by either allocating it
2106
// or reusing a previously allocated one from a pool.
2107
//
2108
static int _yr_re_fast_exec_position_create(
2109
    RE_FAST_EXEC_POSITION_POOL* pool,
2110
    RE_FAST_EXEC_POSITION** new_position)
2111
0
{
2112
0
  RE_FAST_EXEC_POSITION* position;
2113
2114
0
  if (pool->head != NULL)
2115
0
  {
2116
0
    position = pool->head;
2117
0
    pool->head = position->next;
2118
0
  }
2119
0
  else
2120
0
  {
2121
0
    position = (RE_FAST_EXEC_POSITION*) yr_malloc(
2122
0
        sizeof(RE_FAST_EXEC_POSITION));
2123
2124
0
    if (position == NULL)
2125
0
      return ERROR_INSUFFICIENT_MEMORY;
2126
0
  }
2127
2128
0
  position->input = NULL;
2129
0
  position->round = 0;
2130
0
  position->next = NULL;
2131
0
  position->prev = NULL;
2132
2133
0
  *new_position = position;
2134
2135
0
  return ERROR_SUCCESS;
2136
0
}
2137
2138
////////////////////////////////////////////////////////////////////////////////
2139
// Helper function that moves a list of RE_FAST_EXEC_POSITION structures to a
2140
// pool represented by a RE_FAST_EXEC_POSITION_POOL. Receives pointers to the
2141
// pool, the first item, and last item in the list.
2142
//
2143
static void _yr_re_fast_exec_destroy_position_list(
2144
    RE_FAST_EXEC_POSITION_POOL* pool,
2145
    RE_FAST_EXEC_POSITION* first,
2146
    RE_FAST_EXEC_POSITION* last)
2147
0
{
2148
0
  last->next = pool->head;
2149
2150
0
  if (pool->head != NULL)
2151
0
    pool->head->prev = last;
2152
2153
0
  pool->head = first;
2154
0
}
2155
2156
////////////////////////////////////////////////////////////////////////////////
2157
// This function replaces yr_re_exec for regular expressions marked with flag
2158
// RE_FLAGS_FAST_REGEXP. These regular expressions are derived from hex strings
2159
// that don't contain alternatives, like for example:
2160
//
2161
//   { 01 02 03 04 [0-2] 04 05 06 07 }
2162
//
2163
// The regexp's code produced by such strings can be matched by a faster, less
2164
// general algorithm, and it contains only the following opcodes:
2165
//
2166
//   * RE_OPCODE_LITERAL
2167
//   * RE_OPCODE_MASKED_LITERAL,
2168
//   * RE_OPCODE_NOT_LITERAL
2169
//   * RE_OPCODE_MASKED_NOT_LITERAL
2170
//   * RE_OPCODE_ANY
2171
//   * RE_OPCODE_REPEAT_ANY_UNGREEDY
2172
//   * RE_OPCODE_MATCH.
2173
//
2174
// The regexp's code is executed one instruction at time, and the function
2175
// maintains a list of positions within the input for tracking different
2176
// matching alternatives, these positions are described by an instance of
2177
// RE_FAST_EXEC_POSITION. With each instruction the list of positions is
2178
// updated, removing those where the input data doesn't match the current
2179
// instruction, or adding new positions if the instruction is
2180
// RE_OPCODE_REPEAT_ANY_UNGREEDY. The list of positions is maintained sorted
2181
// by the value of the pointer they hold to the input, and it doesn't contain
2182
// duplicated pointer values.
2183
//
2184
int yr_re_fast_exec(
2185
    YR_SCAN_CONTEXT* context,
2186
    const uint8_t* code,
2187
    const uint8_t* input_data,
2188
    size_t input_forwards_size,
2189
    size_t input_backwards_size,
2190
    int flags,
2191
    RE_MATCH_CALLBACK_FUNC callback,
2192
    void* callback_args,
2193
    int* matches)
2194
0
{
2195
0
  RE_REPEAT_ANY_ARGS* repeat_any_args;
2196
2197
  // Pointers to the first and last position in the list.
2198
0
  RE_FAST_EXEC_POSITION* first;
2199
0
  RE_FAST_EXEC_POSITION* last;
2200
2201
0
  int input_incr = flags & RE_FLAGS_BACKWARDS ? -1 : 1;
2202
0
  int bytes_matched;
2203
0
  int max_bytes_matched;
2204
2205
0
  if (flags & RE_FLAGS_BACKWARDS)
2206
0
    max_bytes_matched = (int) yr_min(input_backwards_size, YR_RE_SCAN_LIMIT);
2207
0
  else
2208
0
    max_bytes_matched = (int) yr_min(input_forwards_size, YR_RE_SCAN_LIMIT);
2209
2210
0
  const uint8_t* ip = code;
2211
2212
  // Create the first position in the list, which points to the start of the
2213
  // input data. Intially this is the only position, more positions will be
2214
  // created every time RE_OPCODE_REPEAT_ANY_UNGREEDY is executed.
2215
0
  FAIL_ON_ERROR(_yr_re_fast_exec_position_create(
2216
0
      &context->re_fast_exec_position_pool, &first));
2217
2218
0
  first->round = 0;
2219
0
  first->input = input_data;
2220
0
  first->prev = NULL;
2221
0
  first->next = NULL;
2222
2223
0
  if (flags & RE_FLAGS_BACKWARDS)
2224
0
    first->input--;
2225
2226
  // As we are starting with a single position, the last one and the first one
2227
  // are the same.
2228
0
  last = first;
2229
2230
  // Round is incremented with every regxp instruction.
2231
0
  int round = 0;
2232
2233
  // Keep in the loop until the list of positions gets empty. Positions are
2234
  // removed from the list when they don't match the current instruction in
2235
  // the code.
2236
0
  while (first != NULL)
2237
0
  {
2238
0
    RE_FAST_EXEC_POSITION* current = first;
2239
2240
    // Iterate over all the positions, executing the current instruction at
2241
    // all of them.
2242
0
    while (current != NULL)
2243
0
    {
2244
0
      RE_FAST_EXEC_POSITION* next = current->next;
2245
2246
      // Ignore any position in the list whose round number is different from
2247
      // the current round. This prevents new positions added to the list in
2248
      // this round from being taken into account in this same round.
2249
0
      if (current->round != round)
2250
0
      {
2251
0
        current = next;
2252
0
        continue;
2253
0
      }
2254
2255
0
      bytes_matched = flags & RE_FLAGS_BACKWARDS
2256
0
                          ? (int) (input_data - current->input - 1)
2257
0
                          : (int) (current->input - input_data);
2258
2259
0
      uint16_t opcode_args;
2260
0
      uint8_t mask;
2261
0
      uint8_t value;
2262
2263
0
      bool match = false;
2264
2265
0
      switch (*ip)
2266
0
      {
2267
0
      case RE_OPCODE_ANY:
2268
0
        if (bytes_matched >= max_bytes_matched)
2269
0
          break;
2270
2271
0
        match = true;
2272
0
        current->input += input_incr;
2273
0
        break;
2274
2275
0
      case RE_OPCODE_LITERAL:
2276
0
        if (bytes_matched >= max_bytes_matched)
2277
0
          break;
2278
2279
0
        if (*current->input == *(ip + 1))
2280
0
        {
2281
0
          match = true;
2282
0
          current->input += input_incr;
2283
0
        }
2284
0
        break;
2285
2286
0
      case RE_OPCODE_NOT_LITERAL:
2287
0
        if (bytes_matched >= max_bytes_matched)
2288
0
          break;
2289
2290
0
        if (*current->input != *(ip + 1))
2291
0
        {
2292
0
          match = true;
2293
0
          current->input += input_incr;
2294
0
        }
2295
0
        break;
2296
2297
0
      case RE_OPCODE_MASKED_LITERAL:
2298
0
        if (bytes_matched >= max_bytes_matched)
2299
0
          break;
2300
2301
0
        opcode_args = yr_unaligned_u16(ip + 1);
2302
0
        mask = opcode_args >> 8;
2303
0
        value = opcode_args & 0xFF;
2304
2305
0
        if ((*current->input & mask) == value)
2306
0
        {
2307
0
          match = true;
2308
0
          current->input += input_incr;
2309
0
        }
2310
0
        break;
2311
2312
0
      case RE_OPCODE_MASKED_NOT_LITERAL:
2313
0
        if (bytes_matched >= max_bytes_matched)
2314
0
          break;
2315
2316
0
        opcode_args = yr_unaligned_u16(ip + 1);
2317
0
        mask = opcode_args >> 8;
2318
0
        value = opcode_args & 0xFF;
2319
2320
0
        if ((*current->input & mask) != value)
2321
0
        {
2322
0
          match = true;
2323
0
          current->input += input_incr;
2324
0
        }
2325
0
        break;
2326
2327
0
      case RE_OPCODE_REPEAT_ANY_UNGREEDY:
2328
0
        repeat_any_args = (RE_REPEAT_ANY_ARGS*) (ip + 1);
2329
2330
0
        if (bytes_matched + repeat_any_args->min >= max_bytes_matched)
2331
0
          break;
2332
2333
0
        match = true;
2334
2335
0
        const uint8_t* next_opcode = ip + 1 + sizeof(RE_REPEAT_ANY_ARGS);
2336
2337
        // insertion_point indicates the item in the list of inputs after which
2338
        // the newly created inputs will be inserted.
2339
0
        RE_FAST_EXEC_POSITION* insertion_point = current;
2340
2341
0
        for (int j = repeat_any_args->min + 1; j <= repeat_any_args->max; j++)
2342
0
        {
2343
          // bytes_matched is the number of bytes matched so far, and j is the
2344
          // minimum number of bytes that are still pending to match. If these
2345
          // two numbers sum more than the maximum number of bytes that can be
2346
          // matched the loop can be aborted. The position that we were about
2347
          // to create can't lead to a match without exceeding
2348
          // max_bytes_matched.
2349
0
          if (bytes_matched + j >= max_bytes_matched)
2350
0
            break;
2351
2352
0
          const uint8_t* next_input = current->input + j * input_incr;
2353
2354
          // Find the point where next_input should be inserted. The list is
2355
          // kept sorted by pointer in increasing order, the insertion point is
2356
          // an item that has a pointer lower or equal than next_input, but
2357
          // whose next item have a pointer that is larger.
2358
0
          while (insertion_point->next != NULL &&
2359
0
                 insertion_point->next->input <= next_input)
2360
0
          {
2361
0
            insertion_point = insertion_point->next;
2362
0
          }
2363
2364
          // If the input already exists for the next round, we don't need to
2365
          // insert it.
2366
0
          if (insertion_point->round == round + 1 &&
2367
0
              insertion_point->input == next_input)
2368
0
            continue;
2369
2370
          // The next opcode is RE_OPCODE_LITERAL, but the literal doesn't
2371
          // match with the byte at next_input, we don't need to add this
2372
          // input to the list as we already know that it won't match in the
2373
          // next round and will be deleted from the list anyways.
2374
0
          if (*(next_opcode) == RE_OPCODE_LITERAL &&
2375
0
              *(next_opcode + 1) != *next_input)
2376
0
            continue;
2377
2378
0
          RE_FAST_EXEC_POSITION* new_input;
2379
2380
0
          FAIL_ON_ERROR_WITH_CLEANUP(
2381
0
              _yr_re_fast_exec_position_create(
2382
0
                  &context->re_fast_exec_position_pool, &new_input),
2383
              // Cleanup
2384
0
              _yr_re_fast_exec_destroy_position_list(
2385
0
                  &context->re_fast_exec_position_pool, first, last));
2386
2387
0
          new_input->input = next_input;
2388
0
          new_input->round = round + 1;
2389
0
          new_input->prev = insertion_point;
2390
0
          new_input->next = insertion_point->next;
2391
0
          insertion_point->next = new_input;
2392
2393
0
          if (new_input->next != NULL)
2394
0
            new_input->next->prev = new_input;
2395
2396
0
          if (insertion_point == last)
2397
0
            last = new_input;
2398
0
        }
2399
2400
0
        current->input += input_incr * repeat_any_args->min;
2401
0
        break;
2402
2403
0
      case RE_OPCODE_MATCH:
2404
2405
0
        if (flags & RE_FLAGS_EXHAUSTIVE)
2406
0
        {
2407
0
          FAIL_ON_ERROR_WITH_CLEANUP(
2408
0
              callback(
2409
                  // When matching forwards the matching data always starts at
2410
                  // input_data, when matching backwards it starts at input + 1
2411
                  // or input_data - input_backwards_size if input + 1 is
2412
                  // outside the buffer.
2413
0
                  flags & RE_FLAGS_BACKWARDS
2414
0
                      ? yr_max(
2415
0
                            current->input + 1,
2416
0
                            input_data - input_backwards_size)
2417
0
                      : input_data,
2418
                  // The number of matched bytes should not be larger than
2419
                  // max_bytes_matched.
2420
0
                  yr_min(bytes_matched, max_bytes_matched),
2421
0
                  flags,
2422
0
                  callback_args),
2423
              // Cleanup
2424
0
              _yr_re_fast_exec_destroy_position_list(
2425
0
                  &context->re_fast_exec_position_pool, first, last));
2426
0
        }
2427
0
        else
2428
0
        {
2429
0
          if (matches != NULL)
2430
0
            *matches = bytes_matched;
2431
2432
0
          _yr_re_fast_exec_destroy_position_list(
2433
0
              &context->re_fast_exec_position_pool, first, last);
2434
2435
0
          return ERROR_SUCCESS;
2436
0
        }
2437
0
        break;
2438
2439
0
      default:
2440
0
        printf("non-supported opcode: %d\n", *ip);
2441
0
        assert(false);
2442
0
      }
2443
2444
0
      if (match)
2445
0
      {
2446
0
        current->round = round + 1;
2447
0
      }
2448
0
      else
2449
0
      {
2450
        // Remove current from the list. If the item being removed is the first
2451
        // one or the last one, the first and last pointers should be updated.
2452
        // The removed item is put into the pool for later reuse.
2453
2454
0
        if (current == first)
2455
0
          first = current->next;
2456
2457
0
        if (current == last)
2458
0
          last = current->prev;
2459
2460
0
        if (current->prev != NULL)
2461
0
          current->prev->next = current->next;
2462
2463
0
        if (current->next != NULL)
2464
0
          current->next->prev = current->prev;
2465
2466
0
        current->prev = NULL;
2467
0
        current->next = context->re_fast_exec_position_pool.head;
2468
2469
0
        if (current->next != NULL)
2470
0
          current->next->prev = current;
2471
2472
0
        context->re_fast_exec_position_pool.head = current;
2473
0
      }
2474
2475
0
      current = next;
2476
2477
0
    }  // while (current != NULL)
2478
2479
    // Move instruction pointer (ip) to next instruction. Each opcode has
2480
    // a different size.
2481
0
    switch (*ip)
2482
0
    {
2483
0
    case RE_OPCODE_ANY:
2484
0
      ip += 1;
2485
0
      break;
2486
0
    case RE_OPCODE_LITERAL:
2487
0
    case RE_OPCODE_NOT_LITERAL:
2488
0
      ip += 2;
2489
0
      break;
2490
0
    case RE_OPCODE_MASKED_LITERAL:
2491
0
    case RE_OPCODE_MASKED_NOT_LITERAL:
2492
0
      ip += 3;
2493
0
      break;
2494
0
    case RE_OPCODE_REPEAT_ANY_UNGREEDY:
2495
0
      ip += 1 + sizeof(RE_REPEAT_ANY_ARGS);
2496
0
      break;
2497
0
    case RE_OPCODE_MATCH:
2498
0
      break;
2499
0
    default:
2500
0
      assert(false);
2501
0
    }
2502
2503
0
    round++;
2504
0
  }
2505
2506
  // If this point is reached no matches were found.
2507
2508
0
  if (matches != NULL)
2509
0
    *matches = -1;
2510
2511
0
  return ERROR_SUCCESS;
2512
0
}
2513
2514
static void _yr_re_print_node(RE_NODE* re_node, uint32_t indent)
2515
0
{
2516
0
  RE_NODE* child;
2517
0
  int i;
2518
2519
0
  if (re_node == NULL)
2520
0
    return;
2521
2522
0
  if (indent > 0)
2523
0
    printf("\n%*s", indent, " ");
2524
0
  switch (re_node->type)
2525
0
  {
2526
0
  case RE_NODE_ALT:
2527
0
    printf("Alt(");
2528
0
    _yr_re_print_node(re_node->children_head, indent + 4);
2529
0
    printf(",");
2530
0
    _yr_re_print_node(re_node->children_tail, indent + 4);
2531
0
    printf("\n%*s%s", indent, " ", ")");
2532
0
    break;
2533
2534
0
  case RE_NODE_CONCAT:
2535
0
    printf("Cat(");
2536
0
    child = re_node->children_head;
2537
0
    while (child != NULL)
2538
0
    {
2539
0
      _yr_re_print_node(child, indent + 4);
2540
0
      printf(",");
2541
0
      child = child->next_sibling;
2542
0
    }
2543
0
    printf("\n%*s%s", indent, " ", ")");
2544
0
    break;
2545
2546
0
  case RE_NODE_STAR:
2547
0
    printf("Star(");
2548
0
    _yr_re_print_node(re_node->children_head, indent + 4);
2549
0
    printf(")");
2550
0
    break;
2551
2552
0
  case RE_NODE_PLUS:
2553
0
    printf("Plus(");
2554
0
    _yr_re_print_node(re_node->children_head, indent + 4);
2555
0
    printf(")");
2556
0
    break;
2557
2558
0
  case RE_NODE_LITERAL:
2559
0
    printf("Lit(%c)", re_node->value);
2560
0
    break;
2561
2562
0
  case RE_NODE_NOT_LITERAL:
2563
0
    printf("NotLit(%c)", re_node->value);
2564
0
    break;
2565
2566
0
  case RE_NODE_MASKED_LITERAL:
2567
0
    printf("MaskedLit(%02X,%02X)", re_node->value, re_node->mask);
2568
0
    break;
2569
2570
0
  case RE_NODE_WORD_CHAR:
2571
0
    printf("WordChar");
2572
0
    break;
2573
2574
0
  case RE_NODE_NON_WORD_CHAR:
2575
0
    printf("NonWordChar");
2576
0
    break;
2577
2578
0
  case RE_NODE_SPACE:
2579
0
    printf("Space");
2580
0
    break;
2581
2582
0
  case RE_NODE_NON_SPACE:
2583
0
    printf("NonSpace");
2584
0
    break;
2585
2586
0
  case RE_NODE_DIGIT:
2587
0
    printf("Digit");
2588
0
    break;
2589
2590
0
  case RE_NODE_NON_DIGIT:
2591
0
    printf("NonDigit");
2592
0
    break;
2593
2594
0
  case RE_NODE_ANY:
2595
0
    printf("Any");
2596
0
    break;
2597
2598
0
  case RE_NODE_RANGE:
2599
0
    printf("Range(%d-%d, ", re_node->start, re_node->end);
2600
0
    _yr_re_print_node(re_node->children_head, indent + 4);
2601
0
    printf("\n%*s%s", indent, " ", ")");
2602
0
    break;
2603
2604
0
  case RE_NODE_CLASS:
2605
0
    printf("Class(");
2606
0
    for (i = 0; i < 256; i++)
2607
0
      if (_yr_re_is_char_in_class(re_node->re_class, i, false))
2608
0
        printf("%02X,", i);
2609
0
    printf(")");
2610
0
    break;
2611
2612
0
  case RE_NODE_EMPTY:
2613
0
    printf("Empty");
2614
0
    break;
2615
2616
0
  case RE_NODE_ANCHOR_START:
2617
0
    printf("AnchorStart");
2618
0
    break;
2619
2620
0
  case RE_NODE_ANCHOR_END:
2621
0
    printf("AnchorEnd");
2622
0
    break;
2623
2624
0
  case RE_NODE_WORD_BOUNDARY:
2625
0
    printf("WordBoundary");
2626
0
    break;
2627
2628
0
  case RE_NODE_NON_WORD_BOUNDARY:
2629
0
    printf("NonWordBoundary");
2630
0
    break;
2631
2632
0
  case RE_NODE_RANGE_ANY:
2633
0
    printf("RangeAny");
2634
0
    break;
2635
2636
0
  default:
2637
0
    printf("???");
2638
0
    break;
2639
0
  }
2640
0
}
2641
2642
void yr_re_print(RE_AST* re_ast)
2643
0
{
2644
0
  _yr_re_print_node(re_ast->root_node, 0);
2645
0
}