Coverage Report

Created: 2026-07-10 06:40

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
      branch_a->stack[++branch_a->sp] = 0;
1561
0
      branch_a->ip += (1 + sizeof(RE_REPEAT_ARGS));
1562
0
      break;
1563
1564
0
    case RE_OPCODE_REPEAT_END_GREEDY:
1565
0
    case RE_OPCODE_REPEAT_END_UNGREEDY:
1566
1567
0
      repeat_args = (RE_REPEAT_ARGS*) (fiber->ip + 1);
1568
0
      fiber->stack[fiber->sp]++;
1569
1570
0
      if (fiber->stack[fiber->sp] < repeat_args->min)
1571
0
      {
1572
0
        fiber->ip += repeat_args->offset;
1573
0
        break;
1574
0
      }
1575
1576
0
      branch_a = fiber;
1577
1578
0
      if (fiber->stack[fiber->sp] < repeat_args->max)
1579
0
      {
1580
0
        FAIL_ON_ERROR(
1581
0
            _yr_re_fiber_split(fiber_list, fiber_pool, branch_a, &branch_b));
1582
1583
0
        if (opcode == RE_OPCODE_REPEAT_END_GREEDY)
1584
0
          yr_swap(branch_a, branch_b, RE_FIBER*);
1585
1586
0
        branch_b->ip += repeat_args->offset;
1587
0
      }
1588
1589
0
      branch_a->sp--;
1590
0
      branch_a->ip += (1 + sizeof(RE_REPEAT_ARGS));
1591
0
      break;
1592
1593
0
    case RE_OPCODE_REPEAT_ANY_GREEDY:
1594
0
    case RE_OPCODE_REPEAT_ANY_UNGREEDY:
1595
1596
0
      repeat_any_args = (RE_REPEAT_ANY_ARGS*) (fiber->ip + 1);
1597
1598
      // If repetition counter (rc) is -1 it means that we are reaching this
1599
      // instruction from the previous one in the instructions stream. In
1600
      // this case let's initialize the counter to 0 and start looping.
1601
1602
0
      if (fiber->rc == -1)
1603
0
        fiber->rc = 0;
1604
1605
0
      if (fiber->rc < repeat_any_args->min)
1606
0
      {
1607
        // Increase repetition counter and continue with next fiber. The
1608
        // instruction pointer for this fiber is not incremented yet, this
1609
        // fiber spins in this same instruction until reaching the minimum
1610
        // number of repetitions.
1611
1612
0
        fiber->rc++;
1613
0
        fiber = fiber->next;
1614
0
      }
1615
0
      else if (fiber->rc < repeat_any_args->max)
1616
0
      {
1617
        // Once the minimum number of repetitions are matched one fiber
1618
        // remains spinning in this instruction until reaching the maximum
1619
        // number of repetitions while new fibers are created. New fibers
1620
        // start executing at the next instruction.
1621
1622
0
        next = fiber->next;
1623
0
        branch_a = fiber;
1624
1625
0
        FAIL_ON_ERROR(
1626
0
            _yr_re_fiber_split(fiber_list, fiber_pool, branch_a, &branch_b));
1627
1628
0
        if (opcode == RE_OPCODE_REPEAT_ANY_UNGREEDY)
1629
0
          yr_swap(branch_a, branch_b, RE_FIBER*);
1630
1631
0
        branch_a->rc++;
1632
0
        branch_b->ip += (1 + sizeof(RE_REPEAT_ANY_ARGS));
1633
0
        branch_b->rc = -1;
1634
1635
0
        FAIL_ON_ERROR(_yr_re_fiber_sync(fiber_list, fiber_pool, branch_b));
1636
1637
0
        fiber = next;
1638
0
      }
1639
0
      else
1640
0
      {
1641
        // When the maximum number of repetitions is reached the fiber keeps
1642
        // executing at the next instruction. The repetition counter is set
1643
        // to -1 indicating that we are not spinning in a repeat instruction
1644
        // anymore.
1645
1646
0
        fiber->ip += (1 + sizeof(RE_REPEAT_ANY_ARGS));
1647
0
        fiber->rc = -1;
1648
0
      }
1649
1650
0
      break;
1651
1652
0
    case RE_OPCODE_JUMP:
1653
0
      jmp_len = yr_unaligned_i16(fiber->ip + 1);
1654
0
      fiber->ip += jmp_len;
1655
0
      break;
1656
1657
0
    default:
1658
0
      fiber = fiber->next;
1659
0
    }
1660
0
  }
1661
1662
0
  return ERROR_SUCCESS;
1663
0
}
1664
1665
////////////////////////////////////////////////////////////////////////////////
1666
// Executes a regular expression. The specified regular expression will try to
1667
// match the data starting at the address specified by "input". The "input"
1668
// pointer can point to any address inside a memory buffer. Arguments
1669
// "input_forwards_size" and "input_backwards_size" indicate how many bytes
1670
// can be accessible starting at "input" and going forwards and backwards
1671
// respectively.
1672
//
1673
//   <--- input_backwards_size -->|<----------- input_forwards_size -------->
1674
//  |--------  memory buffer  -----------------------------------------------|
1675
//                                ^
1676
//                              input
1677
//
1678
// Args:
1679
//   YR_SCAN_CONTEXT *context         - Scan context.
1680
//   const uint8_t* code              - Regexp code be executed
1681
//   const uint8_t* input             - Pointer to input data
1682
//   size_t input_forwards_size       - Number of accessible bytes starting at
1683
//                                      "input" and going forwards.
1684
//   size_t input_backwards_size      - Number of accessible bytes starting at
1685
//                                      "input" and going backwards
1686
//   int flags                        - Flags:
1687
//      RE_FLAGS_SCAN
1688
//      RE_FLAGS_BACKWARDS
1689
//      RE_FLAGS_EXHAUSTIVE
1690
//      RE_FLAGS_WIDE
1691
//      RE_FLAGS_NO_CASE
1692
//      RE_FLAGS_DOT_ALL
1693
//   RE_MATCH_CALLBACK_FUNC callback  - Callback function
1694
//   void* callback_args              - Callback argument
1695
//   int*  matches                    - Pointer to an integer receiving the
1696
//                                      number of matching bytes. Notice that
1697
//                                      0 means a zero-length match, while no
1698
//                                      matches is -1.
1699
// Returns:
1700
//    ERROR_SUCCESS or any other error code.
1701
1702
int yr_re_exec(
1703
    YR_SCAN_CONTEXT* context,
1704
    const uint8_t* code,
1705
    const uint8_t* input_data,
1706
    size_t input_forwards_size,
1707
    size_t input_backwards_size,
1708
    int flags,
1709
    RE_MATCH_CALLBACK_FUNC callback,
1710
    void* callback_args,
1711
    int* matches)
1712
0
{
1713
0
  const uint8_t* input;
1714
0
  const uint8_t* ip;
1715
1716
0
  uint16_t opcode_args;
1717
0
  uint8_t mask;
1718
0
  uint8_t value;
1719
0
  uint8_t character_size;
1720
1721
0
  RE_FIBER_LIST fibers;
1722
0
  RE_FIBER* fiber;
1723
0
  RE_FIBER* next_fiber;
1724
1725
0
  int bytes_matched;
1726
0
  int max_bytes_matched;
1727
1728
0
  int match;
1729
0
  int input_incr;
1730
0
  int kill;
1731
0
  int action;
1732
1733
0
  bool prev_is_word_char = false;
1734
0
  bool input_is_word_char = false;
1735
1736
0
#define ACTION_NONE      0
1737
0
#define ACTION_CONTINUE  1
1738
0
#define ACTION_KILL      2
1739
0
#define ACTION_KILL_TAIL 3
1740
1741
0
#define prolog                                      \
1742
0
  {                                                 \
1743
0
    if ((bytes_matched >= max_bytes_matched) ||     \
1744
0
        (character_size == 2 && *(input + 1) != 0)) \
1745
0
    {                                               \
1746
0
      action = ACTION_KILL;                         \
1747
0
      break;                                        \
1748
0
    }                                               \
1749
0
  }
1750
1751
0
  if (matches != NULL)
1752
0
    *matches = -1;
1753
1754
0
  if (flags & RE_FLAGS_WIDE)
1755
0
    character_size = 2;
1756
0
  else
1757
0
    character_size = 1;
1758
1759
0
  input = input_data;
1760
0
  input_incr = character_size;
1761
1762
0
  if (flags & RE_FLAGS_BACKWARDS)
1763
0
  {
1764
    // Signedness conversion is sound as long as YR_RE_SCAN_LIMIT <= INT_MAX
1765
0
    max_bytes_matched = (int) yr_min(input_backwards_size, YR_RE_SCAN_LIMIT);
1766
0
    input -= character_size;
1767
0
    input_incr = -input_incr;
1768
0
  }
1769
0
  else
1770
0
  {
1771
    // Signedness conversion is sound as long as YR_RE_SCAN_LIMIT <= INT_MAX
1772
0
    max_bytes_matched = (int) yr_min(input_forwards_size, YR_RE_SCAN_LIMIT);
1773
0
  }
1774
1775
  // Round down max_bytes_matched to a multiple of character_size, this way if
1776
  // character_size is 2 and max_bytes_matched is odd we are ignoring the
1777
  // extra byte which can't match anyways.
1778
1779
0
  max_bytes_matched = max_bytes_matched - max_bytes_matched % character_size;
1780
0
  bytes_matched = 0;
1781
1782
0
  FAIL_ON_ERROR(_yr_re_fiber_create(&context->re_fiber_pool, &fiber));
1783
1784
0
  fiber->ip = code;
1785
0
  fibers.head = fiber;
1786
0
  fibers.tail = fiber;
1787
1788
0
  FAIL_ON_ERROR_WITH_CLEANUP(
1789
0
      _yr_re_fiber_sync(&fibers, &context->re_fiber_pool, fiber),
1790
0
      _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
1791
1792
0
  while (fibers.head != NULL)
1793
0
  {
1794
0
    fiber = fibers.head;
1795
1796
0
    while (fiber != NULL)
1797
0
    {
1798
0
      next_fiber = fiber->next;
1799
1800
0
      if (_yr_re_fiber_exists(&fibers, fiber, fiber->prev))
1801
0
        _yr_re_fiber_kill(&fibers, &context->re_fiber_pool, fiber);
1802
1803
0
      fiber = next_fiber;
1804
0
    }
1805
1806
0
    fiber = fibers.head;
1807
1808
0
    while (fiber != NULL)
1809
0
    {
1810
0
      ip = fiber->ip;
1811
0
      action = ACTION_NONE;
1812
1813
0
      switch (*ip)
1814
0
      {
1815
0
      case RE_OPCODE_ANY:
1816
0
        prolog;
1817
0
        match = (flags & RE_FLAGS_DOT_ALL) || (*input != 0x0A);
1818
0
        action = match ? ACTION_NONE : ACTION_KILL;
1819
0
        fiber->ip += 1;
1820
0
        break;
1821
1822
0
      case RE_OPCODE_REPEAT_ANY_GREEDY:
1823
0
      case RE_OPCODE_REPEAT_ANY_UNGREEDY:
1824
0
        prolog;
1825
0
        match = (flags & RE_FLAGS_DOT_ALL) || (*input != 0x0A);
1826
0
        action = match ? ACTION_NONE : ACTION_KILL;
1827
1828
        // The instruction pointer is not incremented here. The current fiber
1829
        // spins in this instruction until reaching the required number of
1830
        // repetitions. The code controlling the number of repetitions is in
1831
        // _yr_re_fiber_sync.
1832
1833
0
        break;
1834
1835
0
      case RE_OPCODE_LITERAL:
1836
0
        prolog;
1837
0
        if (flags & RE_FLAGS_NO_CASE)
1838
0
          match = yr_lowercase[*input] == yr_lowercase[*(ip + 1)];
1839
0
        else
1840
0
          match = (*input == *(ip + 1));
1841
0
        action = match ? ACTION_NONE : ACTION_KILL;
1842
0
        fiber->ip += 2;
1843
0
        break;
1844
1845
0
      case RE_OPCODE_NOT_LITERAL:
1846
0
        prolog;
1847
1848
        // We don't need to take into account the case-insensitive
1849
        // case because this opcode is only used with hex strings,
1850
        // which can't be case-insensitive.
1851
1852
0
        match = (*input != *(ip + 1));
1853
0
        action = match ? ACTION_NONE : ACTION_KILL;
1854
0
        fiber->ip += 2;
1855
0
        break;
1856
1857
0
      case RE_OPCODE_MASKED_LITERAL:
1858
0
        prolog;
1859
0
        opcode_args = yr_unaligned_u16(ip + 1);
1860
0
        mask = opcode_args >> 8;
1861
0
        value = opcode_args & 0xFF;
1862
1863
        // We don't need to take into account the case-insensitive
1864
        // case because this opcode is only used with hex strings,
1865
        // which can't be case-insensitive.
1866
1867
0
        match = ((*input & mask) == value);
1868
0
        action = match ? ACTION_NONE : ACTION_KILL;
1869
0
        fiber->ip += 3;
1870
0
        break;
1871
1872
0
      case RE_OPCODE_MASKED_NOT_LITERAL:
1873
0
        prolog;
1874
0
        opcode_args = yr_unaligned_u16(ip + 1);
1875
0
        mask = opcode_args >> 8;
1876
0
        value = opcode_args & 0xFF;
1877
1878
        // We don't need to take into account the case-insensitive
1879
        // case because this opcode is only used with hex strings,
1880
        // which can't be case-insensitive.
1881
1882
0
        match = ((*input & mask) != value);
1883
0
        action = match ? ACTION_NONE : ACTION_KILL;
1884
0
        fiber->ip += 3;
1885
0
        break;
1886
1887
0
      case RE_OPCODE_CLASS:
1888
0
        prolog;
1889
0
        match = _yr_re_is_char_in_class(
1890
0
            (RE_CLASS*) (ip + 1), *input, flags & RE_FLAGS_NO_CASE);
1891
0
        action = match ? ACTION_NONE : ACTION_KILL;
1892
0
        fiber->ip += (sizeof(RE_CLASS) + 1);
1893
0
        break;
1894
1895
0
      case RE_OPCODE_WORD_CHAR:
1896
0
        prolog;
1897
0
        match = _yr_re_is_word_char(input, character_size);
1898
0
        action = match ? ACTION_NONE : ACTION_KILL;
1899
0
        fiber->ip += 1;
1900
0
        break;
1901
1902
0
      case RE_OPCODE_NON_WORD_CHAR:
1903
0
        prolog;
1904
0
        match = !_yr_re_is_word_char(input, character_size);
1905
0
        action = match ? ACTION_NONE : ACTION_KILL;
1906
0
        fiber->ip += 1;
1907
0
        break;
1908
1909
0
      case RE_OPCODE_SPACE:
1910
0
      case RE_OPCODE_NON_SPACE:
1911
1912
0
        prolog;
1913
1914
0
        switch (*input)
1915
0
        {
1916
0
        case ' ':
1917
0
        case '\t':
1918
0
        case '\r':
1919
0
        case '\n':
1920
0
        case '\v':
1921
0
        case '\f':
1922
0
          match = true;
1923
0
          break;
1924
0
        default:
1925
0
          match = false;
1926
0
        }
1927
1928
0
        if (*ip == RE_OPCODE_NON_SPACE)
1929
0
          match = !match;
1930
1931
0
        action = match ? ACTION_NONE : ACTION_KILL;
1932
0
        fiber->ip += 1;
1933
0
        break;
1934
1935
0
      case RE_OPCODE_DIGIT:
1936
0
        prolog;
1937
0
        match = isdigit(*input);
1938
0
        action = match ? ACTION_NONE : ACTION_KILL;
1939
0
        fiber->ip += 1;
1940
0
        break;
1941
1942
0
      case RE_OPCODE_NON_DIGIT:
1943
0
        prolog;
1944
0
        match = !isdigit(*input);
1945
0
        action = match ? ACTION_NONE : ACTION_KILL;
1946
0
        fiber->ip += 1;
1947
0
        break;
1948
1949
0
      case RE_OPCODE_WORD_BOUNDARY:
1950
0
      case RE_OPCODE_NON_WORD_BOUNDARY:
1951
0
        if (input - input_incr + character_size <=
1952
0
                input_data + input_forwards_size &&
1953
0
            input - input_incr >= input_data - input_backwards_size)
1954
0
        {
1955
0
          prev_is_word_char = _yr_re_is_word_char(
1956
0
              input - input_incr, character_size);
1957
0
        }
1958
0
        else
1959
0
        {
1960
0
          prev_is_word_char = false;
1961
0
        }
1962
1963
0
        if (input + character_size <= input_data + input_forwards_size &&
1964
0
            input >= input_data - input_backwards_size)
1965
0
        {
1966
0
          input_is_word_char = _yr_re_is_word_char(input, character_size);
1967
0
        }
1968
0
        else
1969
0
        {
1970
0
          input_is_word_char = false;
1971
0
        }
1972
1973
0
        match = (prev_is_word_char && !input_is_word_char) ||
1974
0
                (!prev_is_word_char && input_is_word_char);
1975
1976
0
        if (*ip == RE_OPCODE_NON_WORD_BOUNDARY)
1977
0
          match = !match;
1978
1979
0
        action = match ? ACTION_CONTINUE : ACTION_KILL;
1980
0
        fiber->ip += 1;
1981
0
        break;
1982
1983
0
      case RE_OPCODE_MATCH_AT_START:
1984
0
        if (flags & RE_FLAGS_BACKWARDS)
1985
0
          kill = input_backwards_size > (size_t) bytes_matched;
1986
0
        else
1987
0
          kill = input_backwards_size > 0 || (bytes_matched != 0);
1988
0
        action = kill ? ACTION_KILL : ACTION_CONTINUE;
1989
0
        fiber->ip += 1;
1990
0
        break;
1991
1992
0
      case RE_OPCODE_MATCH_AT_END:
1993
0
        kill = flags & RE_FLAGS_BACKWARDS ||
1994
0
               input_forwards_size > (size_t) bytes_matched;
1995
0
        action = kill ? ACTION_KILL : ACTION_CONTINUE;
1996
0
        fiber->ip += 1;
1997
0
        break;
1998
1999
0
      case RE_OPCODE_MATCH:
2000
2001
0
        if (matches != NULL)
2002
0
          *matches = bytes_matched;
2003
2004
0
        if (flags & RE_FLAGS_EXHAUSTIVE)
2005
0
        {
2006
0
          if (callback != NULL)
2007
0
          {
2008
0
            if (flags & RE_FLAGS_BACKWARDS)
2009
0
            {
2010
0
              FAIL_ON_ERROR_WITH_CLEANUP(
2011
0
                  callback(
2012
0
                      input + character_size,
2013
0
                      bytes_matched,
2014
0
                      flags,
2015
0
                      callback_args),
2016
0
                  _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2017
0
            }
2018
0
            else
2019
0
            {
2020
0
              FAIL_ON_ERROR_WITH_CLEANUP(
2021
0
                  callback(input_data, bytes_matched, flags, callback_args),
2022
0
                  _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2023
0
            }
2024
0
          }
2025
2026
0
          action = ACTION_KILL;
2027
0
        }
2028
0
        else
2029
0
        {
2030
0
          action = ACTION_KILL_TAIL;
2031
0
        }
2032
2033
0
        break;
2034
2035
0
      default:
2036
0
        assert(false);
2037
0
      }
2038
2039
0
      switch (action)
2040
0
      {
2041
0
      case ACTION_KILL:
2042
0
        fiber = _yr_re_fiber_kill(&fibers, &context->re_fiber_pool, fiber);
2043
0
        break;
2044
2045
0
      case ACTION_KILL_TAIL:
2046
0
        _yr_re_fiber_kill_tail(&fibers, &context->re_fiber_pool, fiber);
2047
0
        fiber = NULL;
2048
0
        break;
2049
2050
0
      case ACTION_CONTINUE:
2051
0
        FAIL_ON_ERROR_WITH_CLEANUP(
2052
0
            _yr_re_fiber_sync(&fibers, &context->re_fiber_pool, fiber),
2053
0
            _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2054
0
        break;
2055
2056
0
      default:
2057
0
        next_fiber = fiber->next;
2058
0
        FAIL_ON_ERROR_WITH_CLEANUP(
2059
0
            _yr_re_fiber_sync(&fibers, &context->re_fiber_pool, fiber),
2060
0
            _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2061
0
        fiber = next_fiber;
2062
0
      }
2063
0
    }
2064
2065
0
    input += input_incr;
2066
0
    bytes_matched += character_size;
2067
2068
0
    if (flags & RE_FLAGS_SCAN && bytes_matched < max_bytes_matched)
2069
0
    {
2070
0
      FAIL_ON_ERROR_WITH_CLEANUP(
2071
0
          _yr_re_fiber_create(&context->re_fiber_pool, &fiber),
2072
0
          _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2073
2074
0
      fiber->ip = code;
2075
0
      _yr_re_fiber_append(&fibers, fiber);
2076
2077
0
      FAIL_ON_ERROR_WITH_CLEANUP(
2078
0
          _yr_re_fiber_sync(&fibers, &context->re_fiber_pool, fiber),
2079
0
          _yr_re_fiber_kill_all(&fibers, &context->re_fiber_pool));
2080
0
    }
2081
0
  }
2082
2083
0
  return ERROR_SUCCESS;
2084
0
}
2085
2086
////////////////////////////////////////////////////////////////////////////////
2087
// Helper function that creates a RE_FAST_EXEC_POSITION by either allocating it
2088
// or reusing a previously allocated one from a pool.
2089
//
2090
static int _yr_re_fast_exec_position_create(
2091
    RE_FAST_EXEC_POSITION_POOL* pool,
2092
    RE_FAST_EXEC_POSITION** new_position)
2093
0
{
2094
0
  RE_FAST_EXEC_POSITION* position;
2095
2096
0
  if (pool->head != NULL)
2097
0
  {
2098
0
    position = pool->head;
2099
0
    pool->head = position->next;
2100
0
  }
2101
0
  else
2102
0
  {
2103
0
    position = (RE_FAST_EXEC_POSITION*) yr_malloc(
2104
0
        sizeof(RE_FAST_EXEC_POSITION));
2105
2106
0
    if (position == NULL)
2107
0
      return ERROR_INSUFFICIENT_MEMORY;
2108
0
  }
2109
2110
0
  position->input = NULL;
2111
0
  position->round = 0;
2112
0
  position->next = NULL;
2113
0
  position->prev = NULL;
2114
2115
0
  *new_position = position;
2116
2117
0
  return ERROR_SUCCESS;
2118
0
}
2119
2120
////////////////////////////////////////////////////////////////////////////////
2121
// Helper function that moves a list of RE_FAST_EXEC_POSITION structures to a
2122
// pool represented by a RE_FAST_EXEC_POSITION_POOL. Receives pointers to the
2123
// pool, the first item, and last item in the list.
2124
//
2125
static void _yr_re_fast_exec_destroy_position_list(
2126
    RE_FAST_EXEC_POSITION_POOL* pool,
2127
    RE_FAST_EXEC_POSITION* first,
2128
    RE_FAST_EXEC_POSITION* last)
2129
0
{
2130
0
  last->next = pool->head;
2131
2132
0
  if (pool->head != NULL)
2133
0
    pool->head->prev = last;
2134
2135
0
  pool->head = first;
2136
0
}
2137
2138
////////////////////////////////////////////////////////////////////////////////
2139
// This function replaces yr_re_exec for regular expressions marked with flag
2140
// RE_FLAGS_FAST_REGEXP. These regular expressions are derived from hex strings
2141
// that don't contain alternatives, like for example:
2142
//
2143
//   { 01 02 03 04 [0-2] 04 05 06 07 }
2144
//
2145
// The regexp's code produced by such strings can be matched by a faster, less
2146
// general algorithm, and it contains only the following opcodes:
2147
//
2148
//   * RE_OPCODE_LITERAL
2149
//   * RE_OPCODE_MASKED_LITERAL,
2150
//   * RE_OPCODE_NOT_LITERAL
2151
//   * RE_OPCODE_MASKED_NOT_LITERAL
2152
//   * RE_OPCODE_ANY
2153
//   * RE_OPCODE_REPEAT_ANY_UNGREEDY
2154
//   * RE_OPCODE_MATCH.
2155
//
2156
// The regexp's code is executed one instruction at time, and the function
2157
// maintains a list of positions within the input for tracking different
2158
// matching alternatives, these positions are described by an instance of
2159
// RE_FAST_EXEC_POSITION. With each instruction the list of positions is
2160
// updated, removing those where the input data doesn't match the current
2161
// instruction, or adding new positions if the instruction is
2162
// RE_OPCODE_REPEAT_ANY_UNGREEDY. The list of positions is maintained sorted
2163
// by the value of the pointer they hold to the input, and it doesn't contain
2164
// duplicated pointer values.
2165
//
2166
int yr_re_fast_exec(
2167
    YR_SCAN_CONTEXT* context,
2168
    const uint8_t* code,
2169
    const uint8_t* input_data,
2170
    size_t input_forwards_size,
2171
    size_t input_backwards_size,
2172
    int flags,
2173
    RE_MATCH_CALLBACK_FUNC callback,
2174
    void* callback_args,
2175
    int* matches)
2176
0
{
2177
0
  RE_REPEAT_ANY_ARGS* repeat_any_args;
2178
2179
  // Pointers to the first and last position in the list.
2180
0
  RE_FAST_EXEC_POSITION* first;
2181
0
  RE_FAST_EXEC_POSITION* last;
2182
2183
0
  int input_incr = flags & RE_FLAGS_BACKWARDS ? -1 : 1;
2184
0
  int bytes_matched;
2185
0
  int max_bytes_matched;
2186
2187
0
  if (flags & RE_FLAGS_BACKWARDS)
2188
0
    max_bytes_matched = (int) yr_min(input_backwards_size, YR_RE_SCAN_LIMIT);
2189
0
  else
2190
0
    max_bytes_matched = (int) yr_min(input_forwards_size, YR_RE_SCAN_LIMIT);
2191
2192
0
  const uint8_t* ip = code;
2193
2194
  // Create the first position in the list, which points to the start of the
2195
  // input data. Intially this is the only position, more positions will be
2196
  // created every time RE_OPCODE_REPEAT_ANY_UNGREEDY is executed.
2197
0
  FAIL_ON_ERROR(_yr_re_fast_exec_position_create(
2198
0
      &context->re_fast_exec_position_pool, &first));
2199
2200
0
  first->round = 0;
2201
0
  first->input = input_data;
2202
0
  first->prev = NULL;
2203
0
  first->next = NULL;
2204
2205
0
  if (flags & RE_FLAGS_BACKWARDS)
2206
0
    first->input--;
2207
2208
  // As we are starting with a single position, the last one and the first one
2209
  // are the same.
2210
0
  last = first;
2211
2212
  // Round is incremented with every regxp instruction.
2213
0
  int round = 0;
2214
2215
  // Keep in the loop until the list of positions gets empty. Positions are
2216
  // removed from the list when they don't match the current instruction in
2217
  // the code.
2218
0
  while (first != NULL)
2219
0
  {
2220
0
    RE_FAST_EXEC_POSITION* current = first;
2221
2222
    // Iterate over all the positions, executing the current instruction at
2223
    // all of them.
2224
0
    while (current != NULL)
2225
0
    {
2226
0
      RE_FAST_EXEC_POSITION* next = current->next;
2227
2228
      // Ignore any position in the list whose round number is different from
2229
      // the current round. This prevents new positions added to the list in
2230
      // this round from being taken into account in this same round.
2231
0
      if (current->round != round)
2232
0
      {
2233
0
        current = next;
2234
0
        continue;
2235
0
      }
2236
2237
0
      bytes_matched = flags & RE_FLAGS_BACKWARDS
2238
0
                          ? (int) (input_data - current->input - 1)
2239
0
                          : (int) (current->input - input_data);
2240
2241
0
      uint16_t opcode_args;
2242
0
      uint8_t mask;
2243
0
      uint8_t value;
2244
2245
0
      bool match = false;
2246
2247
0
      switch (*ip)
2248
0
      {
2249
0
      case RE_OPCODE_ANY:
2250
0
        if (bytes_matched >= max_bytes_matched)
2251
0
          break;
2252
2253
0
        match = true;
2254
0
        current->input += input_incr;
2255
0
        break;
2256
2257
0
      case RE_OPCODE_LITERAL:
2258
0
        if (bytes_matched >= max_bytes_matched)
2259
0
          break;
2260
2261
0
        if (*current->input == *(ip + 1))
2262
0
        {
2263
0
          match = true;
2264
0
          current->input += input_incr;
2265
0
        }
2266
0
        break;
2267
2268
0
      case RE_OPCODE_NOT_LITERAL:
2269
0
        if (bytes_matched >= max_bytes_matched)
2270
0
          break;
2271
2272
0
        if (*current->input != *(ip + 1))
2273
0
        {
2274
0
          match = true;
2275
0
          current->input += input_incr;
2276
0
        }
2277
0
        break;
2278
2279
0
      case RE_OPCODE_MASKED_LITERAL:
2280
0
        if (bytes_matched >= max_bytes_matched)
2281
0
          break;
2282
2283
0
        opcode_args = yr_unaligned_u16(ip + 1);
2284
0
        mask = opcode_args >> 8;
2285
0
        value = opcode_args & 0xFF;
2286
2287
0
        if ((*current->input & mask) == value)
2288
0
        {
2289
0
          match = true;
2290
0
          current->input += input_incr;
2291
0
        }
2292
0
        break;
2293
2294
0
      case RE_OPCODE_MASKED_NOT_LITERAL:
2295
0
        if (bytes_matched >= max_bytes_matched)
2296
0
          break;
2297
2298
0
        opcode_args = yr_unaligned_u16(ip + 1);
2299
0
        mask = opcode_args >> 8;
2300
0
        value = opcode_args & 0xFF;
2301
2302
0
        if ((*current->input & mask) != value)
2303
0
        {
2304
0
          match = true;
2305
0
          current->input += input_incr;
2306
0
        }
2307
0
        break;
2308
2309
0
      case RE_OPCODE_REPEAT_ANY_UNGREEDY:
2310
0
        repeat_any_args = (RE_REPEAT_ANY_ARGS*) (ip + 1);
2311
2312
0
        if (bytes_matched + repeat_any_args->min >= max_bytes_matched)
2313
0
          break;
2314
2315
0
        match = true;
2316
2317
0
        const uint8_t* next_opcode = ip + 1 + sizeof(RE_REPEAT_ANY_ARGS);
2318
2319
        // insertion_point indicates the item in the list of inputs after which
2320
        // the newly created inputs will be inserted.
2321
0
        RE_FAST_EXEC_POSITION* insertion_point = current;
2322
2323
0
        for (int j = repeat_any_args->min + 1; j <= repeat_any_args->max; j++)
2324
0
        {
2325
          // bytes_matched is the number of bytes matched so far, and j is the
2326
          // minimum number of bytes that are still pending to match. If these
2327
          // two numbers sum more than the maximum number of bytes that can be
2328
          // matched the loop can be aborted. The position that we were about
2329
          // to create can't lead to a match without exceeding
2330
          // max_bytes_matched.
2331
0
          if (bytes_matched + j >= max_bytes_matched)
2332
0
            break;
2333
2334
0
          const uint8_t* next_input = current->input + j * input_incr;
2335
2336
          // Find the point where next_input should be inserted. The list is
2337
          // kept sorted by pointer in increasing order, the insertion point is
2338
          // an item that has a pointer lower or equal than next_input, but
2339
          // whose next item have a pointer that is larger.
2340
0
          while (insertion_point->next != NULL &&
2341
0
                 insertion_point->next->input <= next_input)
2342
0
          {
2343
0
            insertion_point = insertion_point->next;
2344
0
          }
2345
2346
          // If the input already exists for the next round, we don't need to
2347
          // insert it.
2348
0
          if (insertion_point->round == round + 1 &&
2349
0
              insertion_point->input == next_input)
2350
0
            continue;
2351
2352
          // The next opcode is RE_OPCODE_LITERAL, but the literal doesn't
2353
          // match with the byte at next_input, we don't need to add this
2354
          // input to the list as we already know that it won't match in the
2355
          // next round and will be deleted from the list anyways.
2356
0
          if (*(next_opcode) == RE_OPCODE_LITERAL &&
2357
0
              *(next_opcode + 1) != *next_input)
2358
0
            continue;
2359
2360
0
          RE_FAST_EXEC_POSITION* new_input;
2361
2362
0
          FAIL_ON_ERROR_WITH_CLEANUP(
2363
0
              _yr_re_fast_exec_position_create(
2364
0
                  &context->re_fast_exec_position_pool, &new_input),
2365
              // Cleanup
2366
0
              _yr_re_fast_exec_destroy_position_list(
2367
0
                  &context->re_fast_exec_position_pool, first, last));
2368
2369
0
          new_input->input = next_input;
2370
0
          new_input->round = round + 1;
2371
0
          new_input->prev = insertion_point;
2372
0
          new_input->next = insertion_point->next;
2373
0
          insertion_point->next = new_input;
2374
2375
0
          if (new_input->next != NULL)
2376
0
            new_input->next->prev = new_input;
2377
2378
0
          if (insertion_point == last)
2379
0
            last = new_input;
2380
0
        }
2381
2382
0
        current->input += input_incr * repeat_any_args->min;
2383
0
        break;
2384
2385
0
      case RE_OPCODE_MATCH:
2386
2387
0
        if (flags & RE_FLAGS_EXHAUSTIVE)
2388
0
        {
2389
0
          FAIL_ON_ERROR_WITH_CLEANUP(
2390
0
              callback(
2391
                  // When matching forwards the matching data always starts at
2392
                  // input_data, when matching backwards it starts at input + 1
2393
                  // or input_data - input_backwards_size if input + 1 is
2394
                  // outside the buffer.
2395
0
                  flags & RE_FLAGS_BACKWARDS
2396
0
                      ? yr_max(
2397
0
                            current->input + 1,
2398
0
                            input_data - input_backwards_size)
2399
0
                      : input_data,
2400
                  // The number of matched bytes should not be larger than
2401
                  // max_bytes_matched.
2402
0
                  yr_min(bytes_matched, max_bytes_matched),
2403
0
                  flags,
2404
0
                  callback_args),
2405
              // Cleanup
2406
0
              _yr_re_fast_exec_destroy_position_list(
2407
0
                  &context->re_fast_exec_position_pool, first, last));
2408
0
        }
2409
0
        else
2410
0
        {
2411
0
          if (matches != NULL)
2412
0
            *matches = bytes_matched;
2413
2414
0
          _yr_re_fast_exec_destroy_position_list(
2415
0
              &context->re_fast_exec_position_pool, first, last);
2416
2417
0
          return ERROR_SUCCESS;
2418
0
        }
2419
0
        break;
2420
2421
0
      default:
2422
0
        printf("non-supported opcode: %d\n", *ip);
2423
0
        assert(false);
2424
0
      }
2425
2426
0
      if (match)
2427
0
      {
2428
0
        current->round = round + 1;
2429
0
      }
2430
0
      else
2431
0
      {
2432
        // Remove current from the list. If the item being removed is the first
2433
        // one or the last one, the first and last pointers should be updated.
2434
        // The removed item is put into the pool for later reuse.
2435
2436
0
        if (current == first)
2437
0
          first = current->next;
2438
2439
0
        if (current == last)
2440
0
          last = current->prev;
2441
2442
0
        if (current->prev != NULL)
2443
0
          current->prev->next = current->next;
2444
2445
0
        if (current->next != NULL)
2446
0
          current->next->prev = current->prev;
2447
2448
0
        current->prev = NULL;
2449
0
        current->next = context->re_fast_exec_position_pool.head;
2450
2451
0
        if (current->next != NULL)
2452
0
          current->next->prev = current;
2453
2454
0
        context->re_fast_exec_position_pool.head = current;
2455
0
      }
2456
2457
0
      current = next;
2458
2459
0
    }  // while (current != NULL)
2460
2461
    // Move instruction pointer (ip) to next instruction. Each opcode has
2462
    // a different size.
2463
0
    switch (*ip)
2464
0
    {
2465
0
    case RE_OPCODE_ANY:
2466
0
      ip += 1;
2467
0
      break;
2468
0
    case RE_OPCODE_LITERAL:
2469
0
    case RE_OPCODE_NOT_LITERAL:
2470
0
      ip += 2;
2471
0
      break;
2472
0
    case RE_OPCODE_MASKED_LITERAL:
2473
0
    case RE_OPCODE_MASKED_NOT_LITERAL:
2474
0
      ip += 3;
2475
0
      break;
2476
0
    case RE_OPCODE_REPEAT_ANY_UNGREEDY:
2477
0
      ip += 1 + sizeof(RE_REPEAT_ANY_ARGS);
2478
0
      break;
2479
0
    case RE_OPCODE_MATCH:
2480
0
      break;
2481
0
    default:
2482
0
      assert(false);
2483
0
    }
2484
2485
0
    round++;
2486
0
  }
2487
2488
  // If this point is reached no matches were found.
2489
2490
0
  if (matches != NULL)
2491
0
    *matches = -1;
2492
2493
0
  return ERROR_SUCCESS;
2494
0
}
2495
2496
static void _yr_re_print_node(RE_NODE* re_node, uint32_t indent)
2497
0
{
2498
0
  RE_NODE* child;
2499
0
  int i;
2500
2501
0
  if (re_node == NULL)
2502
0
    return;
2503
2504
0
  if (indent > 0)
2505
0
    printf("\n%*s", indent, " ");
2506
0
  switch (re_node->type)
2507
0
  {
2508
0
  case RE_NODE_ALT:
2509
0
    printf("Alt(");
2510
0
    _yr_re_print_node(re_node->children_head, indent + 4);
2511
0
    printf(",");
2512
0
    _yr_re_print_node(re_node->children_tail, indent + 4);
2513
0
    printf("\n%*s%s", indent, " ", ")");
2514
0
    break;
2515
2516
0
  case RE_NODE_CONCAT:
2517
0
    printf("Cat(");
2518
0
    child = re_node->children_head;
2519
0
    while (child != NULL)
2520
0
    {
2521
0
      _yr_re_print_node(child, indent + 4);
2522
0
      printf(",");
2523
0
      child = child->next_sibling;
2524
0
    }
2525
0
    printf("\n%*s%s", indent, " ", ")");
2526
0
    break;
2527
2528
0
  case RE_NODE_STAR:
2529
0
    printf("Star(");
2530
0
    _yr_re_print_node(re_node->children_head, indent + 4);
2531
0
    printf(")");
2532
0
    break;
2533
2534
0
  case RE_NODE_PLUS:
2535
0
    printf("Plus(");
2536
0
    _yr_re_print_node(re_node->children_head, indent + 4);
2537
0
    printf(")");
2538
0
    break;
2539
2540
0
  case RE_NODE_LITERAL:
2541
0
    printf("Lit(%c)", re_node->value);
2542
0
    break;
2543
2544
0
  case RE_NODE_NOT_LITERAL:
2545
0
    printf("NotLit(%c)", re_node->value);
2546
0
    break;
2547
2548
0
  case RE_NODE_MASKED_LITERAL:
2549
0
    printf("MaskedLit(%02X,%02X)", re_node->value, re_node->mask);
2550
0
    break;
2551
2552
0
  case RE_NODE_WORD_CHAR:
2553
0
    printf("WordChar");
2554
0
    break;
2555
2556
0
  case RE_NODE_NON_WORD_CHAR:
2557
0
    printf("NonWordChar");
2558
0
    break;
2559
2560
0
  case RE_NODE_SPACE:
2561
0
    printf("Space");
2562
0
    break;
2563
2564
0
  case RE_NODE_NON_SPACE:
2565
0
    printf("NonSpace");
2566
0
    break;
2567
2568
0
  case RE_NODE_DIGIT:
2569
0
    printf("Digit");
2570
0
    break;
2571
2572
0
  case RE_NODE_NON_DIGIT:
2573
0
    printf("NonDigit");
2574
0
    break;
2575
2576
0
  case RE_NODE_ANY:
2577
0
    printf("Any");
2578
0
    break;
2579
2580
0
  case RE_NODE_RANGE:
2581
0
    printf("Range(%d-%d, ", re_node->start, re_node->end);
2582
0
    _yr_re_print_node(re_node->children_head, indent + 4);
2583
0
    printf("\n%*s%s", indent, " ", ")");
2584
0
    break;
2585
2586
0
  case RE_NODE_CLASS:
2587
0
    printf("Class(");
2588
0
    for (i = 0; i < 256; i++)
2589
0
      if (_yr_re_is_char_in_class(re_node->re_class, i, false))
2590
0
        printf("%02X,", i);
2591
0
    printf(")");
2592
0
    break;
2593
2594
0
  case RE_NODE_EMPTY:
2595
0
    printf("Empty");
2596
0
    break;
2597
2598
0
  case RE_NODE_ANCHOR_START:
2599
0
    printf("AnchorStart");
2600
0
    break;
2601
2602
0
  case RE_NODE_ANCHOR_END:
2603
0
    printf("AnchorEnd");
2604
0
    break;
2605
2606
0
  case RE_NODE_WORD_BOUNDARY:
2607
0
    printf("WordBoundary");
2608
0
    break;
2609
2610
0
  case RE_NODE_NON_WORD_BOUNDARY:
2611
0
    printf("NonWordBoundary");
2612
0
    break;
2613
2614
0
  case RE_NODE_RANGE_ANY:
2615
0
    printf("RangeAny");
2616
0
    break;
2617
2618
0
  default:
2619
0
    printf("???");
2620
0
    break;
2621
0
  }
2622
0
}
2623
2624
void yr_re_print(RE_AST* re_ast)
2625
0
{
2626
0
  _yr_re_print_node(re_ast->root_node, 0);
2627
0
}