Coverage Report

Created: 2023-06-07 07:19

/src/yara/libyara/object.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
Copyright (c) 2014. 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
#include <assert.h>
31
#include <ctype.h>
32
#include <math.h>
33
#include <stdarg.h>
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <string.h>
37
#include <yara/error.h>
38
#include <yara/exec.h>
39
#include <yara/globals.h>
40
#include <yara/mem.h>
41
#include <yara/object.h>
42
#include <yara/strutils.h>
43
#include <yara/utils.h>
44
45
////////////////////////////////////////////////////////////////////////////////
46
// Creates a new object with the given type and identifier. If a parent is
47
// specified the new object is owned by the parent and it will be destroyed when
48
// the parent is destroyed. You must not call yr_object_destroy on an objected
49
// that has a parent, you should destroy the parent instead.
50
//
51
int yr_object_create(
52
    int8_t type,
53
    const char* identifier,
54
    YR_OBJECT* parent,
55
    YR_OBJECT** object)
56
40.5M
{
57
40.5M
  YR_OBJECT* obj;
58
40.5M
  size_t object_size = 0;
59
60
40.5M
  assert(parent != NULL || object != NULL);
61
40.5M
  assert(identifier != NULL);
62
63
40.5M
  switch (type)
64
40.5M
  {
65
7.55M
  case OBJECT_TYPE_STRUCTURE:
66
7.55M
    object_size = sizeof(YR_OBJECT_STRUCTURE);
67
7.55M
    break;
68
88.4k
  case OBJECT_TYPE_ARRAY:
69
88.4k
    object_size = sizeof(YR_OBJECT_ARRAY);
70
88.4k
    break;
71
6.57k
  case OBJECT_TYPE_DICTIONARY:
72
6.57k
    object_size = sizeof(YR_OBJECT_DICTIONARY);
73
6.57k
    break;
74
22.0M
  case OBJECT_TYPE_INTEGER:
75
22.0M
    object_size = sizeof(YR_OBJECT);
76
22.0M
    break;
77
0
  case OBJECT_TYPE_FLOAT:
78
0
    object_size = sizeof(YR_OBJECT);
79
0
    break;
80
10.7M
  case OBJECT_TYPE_STRING:
81
10.7M
    object_size = sizeof(YR_OBJECT);
82
10.7M
    break;
83
98.5k
  case OBJECT_TYPE_FUNCTION:
84
98.5k
    object_size = sizeof(YR_OBJECT_FUNCTION);
85
98.5k
    break;
86
0
  default:
87
0
    assert(false);
88
40.5M
  }
89
90
40.5M
  obj = (YR_OBJECT*) yr_malloc(object_size);
91
92
40.5M
  if (obj == NULL)
93
0
    return ERROR_INSUFFICIENT_MEMORY;
94
95
40.5M
  obj->type = type;
96
40.5M
  obj->identifier = yr_strdup(identifier);
97
40.5M
  obj->parent = parent;
98
40.5M
  obj->data = NULL;
99
100
40.5M
  switch (type)
101
40.5M
  {
102
22.0M
  case OBJECT_TYPE_INTEGER:
103
22.0M
    obj->value.i = YR_UNDEFINED;
104
22.0M
    break;
105
0
  case OBJECT_TYPE_FLOAT:
106
0
    obj->value.d = NAN;
107
0
    break;
108
10.7M
  case OBJECT_TYPE_STRING:
109
10.7M
    obj->value.ss = NULL;
110
10.7M
    break;
111
7.55M
  case OBJECT_TYPE_STRUCTURE:
112
7.55M
    object_as_structure(obj)->members = NULL;
113
7.55M
    break;
114
88.4k
  case OBJECT_TYPE_ARRAY:
115
88.4k
    object_as_array(obj)->items = NULL;
116
88.4k
    object_as_array(obj)->prototype_item = NULL;
117
88.4k
    break;
118
6.57k
  case OBJECT_TYPE_DICTIONARY:
119
6.57k
    object_as_dictionary(obj)->items = NULL;
120
6.57k
    object_as_dictionary(obj)->prototype_item = NULL;
121
6.57k
    break;
122
98.5k
  case OBJECT_TYPE_FUNCTION:
123
98.5k
    object_as_function(obj)->return_obj = NULL;
124
1.08M
    for (int i = 0; i < YR_MAX_OVERLOADED_FUNCTIONS; i++)
125
985k
    {
126
985k
      object_as_function(obj)->prototypes[i].arguments_fmt = NULL;
127
985k
      object_as_function(obj)->prototypes[i].code = NULL;
128
985k
    }
129
98.5k
    break;
130
40.5M
  }
131
132
40.5M
  if (obj->identifier == NULL)
133
0
  {
134
0
    yr_free(obj);
135
0
    return ERROR_INSUFFICIENT_MEMORY;
136
0
  }
137
138
40.5M
  if (parent != NULL)
139
2.14M
  {
140
2.14M
    assert(
141
2.14M
        parent->type == OBJECT_TYPE_STRUCTURE ||
142
2.14M
        parent->type == OBJECT_TYPE_ARRAY ||
143
2.14M
        parent->type == OBJECT_TYPE_DICTIONARY ||
144
2.14M
        parent->type == OBJECT_TYPE_FUNCTION);
145
146
    // Objects with a parent take the canary from it.
147
2.14M
    obj->canary = parent->canary;
148
149
2.14M
    switch (parent->type)
150
2.14M
    {
151
1.97M
    case OBJECT_TYPE_STRUCTURE:
152
1.97M
      FAIL_ON_ERROR_WITH_CLEANUP(yr_object_structure_set_member(parent, obj), {
153
1.97M
        yr_free((void*) obj->identifier);
154
1.97M
        yr_free(obj);
155
1.97M
      });
156
1.97M
      break;
157
158
59.1k
    case OBJECT_TYPE_ARRAY:
159
59.1k
      object_as_array(parent)->prototype_item = obj;
160
59.1k
      break;
161
162
6.57k
    case OBJECT_TYPE_DICTIONARY:
163
6.57k
      object_as_dictionary(parent)->prototype_item = obj;
164
6.57k
      break;
165
166
98.5k
    case OBJECT_TYPE_FUNCTION:
167
98.5k
      object_as_function(parent)->return_obj = obj;
168
98.5k
      break;
169
2.14M
    }
170
2.14M
  }
171
172
40.5M
  if (object != NULL)
173
38.7M
    *object = obj;
174
175
40.5M
  return ERROR_SUCCESS;
176
40.5M
}
177
178
void yr_object_set_canary(YR_OBJECT* object, int canary)
179
6.57k
{
180
6.57k
  object->canary = canary;
181
6.57k
}
182
183
int yr_object_function_create(
184
    const char* identifier,
185
    const char* arguments_fmt,
186
    const char* return_fmt,
187
    YR_MODULE_FUNC code,
188
    YR_OBJECT* parent,
189
    YR_OBJECT** function)
190
203k
{
191
203k
  YR_OBJECT* return_obj;
192
203k
  YR_OBJECT* o = NULL;
193
203k
  YR_OBJECT_FUNCTION* f = NULL;
194
195
203k
  int8_t return_type;
196
197
  // The parent of a function must be a structure.
198
203k
  assert(parent != NULL && parent->type == OBJECT_TYPE_STRUCTURE);
199
200
203k
  switch (*return_fmt)
201
203k
  {
202
203k
  case 'i':
203
203k
    return_type = OBJECT_TYPE_INTEGER;
204
203k
    break;
205
0
  case 's':
206
0
    return_type = OBJECT_TYPE_STRING;
207
0
    break;
208
0
  case 'f':
209
0
    return_type = OBJECT_TYPE_FLOAT;
210
0
    break;
211
0
  default:
212
0
    return ERROR_INVALID_FORMAT;
213
203k
  }
214
215
  // Try to find if the structure already has a function
216
  // with that name. In that case this is a function overload.
217
203k
  f = object_as_function(yr_object_lookup_field(parent, identifier));
218
219
  // Overloaded functions must have the same return type.
220
203k
  if (f != NULL && return_type != f->return_obj->type)
221
0
    return ERROR_WRONG_RETURN_TYPE;
222
223
203k
  if (f == NULL)  // Function doesn't exist yet
224
98.5k
  {
225
98.5k
    FAIL_ON_ERROR(
226
98.5k
        yr_object_create(OBJECT_TYPE_FUNCTION, identifier, parent, &o));
227
228
    // In case of failure while creating return_obj we don't need to free the
229
    // previously created "o" object, as it is already associated with its
230
    // parent and will be destroyed when the parent is destroyed.
231
98.5k
    FAIL_ON_ERROR(yr_object_create(return_type, "result", o, &return_obj));
232
233
98.5k
    f = object_as_function(o);
234
98.5k
  }
235
236
460k
  for (int i = 0; i < YR_MAX_OVERLOADED_FUNCTIONS; i++)
237
460k
  {
238
460k
    if (f->prototypes[i].arguments_fmt == NULL)
239
203k
    {
240
203k
      f->prototypes[i].arguments_fmt = arguments_fmt;
241
203k
      f->prototypes[i].code = code;
242
243
203k
      break;
244
203k
    }
245
460k
  }
246
247
203k
  if (function != NULL)
248
203k
    *function = (YR_OBJECT*) f;
249
250
203k
  return ERROR_SUCCESS;
251
203k
}
252
253
int yr_object_from_external_variable(
254
    YR_EXTERNAL_VARIABLE* external,
255
    YR_OBJECT** object)
256
0
{
257
0
  YR_OBJECT* obj;
258
0
  int result;
259
0
  uint8_t obj_type = 0;
260
261
0
  switch (external->type)
262
0
  {
263
0
  case EXTERNAL_VARIABLE_TYPE_INTEGER:
264
0
  case EXTERNAL_VARIABLE_TYPE_BOOLEAN:
265
0
    obj_type = OBJECT_TYPE_INTEGER;
266
0
    break;
267
268
0
  case EXTERNAL_VARIABLE_TYPE_FLOAT:
269
0
    obj_type = OBJECT_TYPE_FLOAT;
270
0
    break;
271
272
0
  case EXTERNAL_VARIABLE_TYPE_STRING:
273
0
  case EXTERNAL_VARIABLE_TYPE_MALLOC_STRING:
274
0
    obj_type = OBJECT_TYPE_STRING;
275
0
    break;
276
277
0
  default:
278
0
    assert(false);
279
0
  }
280
281
0
  result = yr_object_create(obj_type, external->identifier, NULL, &obj);
282
283
0
  if (result == ERROR_SUCCESS)
284
0
  {
285
0
    switch (external->type)
286
0
    {
287
0
    case EXTERNAL_VARIABLE_TYPE_INTEGER:
288
0
    case EXTERNAL_VARIABLE_TYPE_BOOLEAN:
289
0
      result = yr_object_set_integer(external->value.i, obj, NULL);
290
0
      break;
291
292
0
    case EXTERNAL_VARIABLE_TYPE_FLOAT:
293
0
      result = yr_object_set_float(external->value.f, obj, NULL);
294
0
      break;
295
296
0
    case EXTERNAL_VARIABLE_TYPE_STRING:
297
0
    case EXTERNAL_VARIABLE_TYPE_MALLOC_STRING:
298
0
      result = yr_object_set_string(
299
0
          external->value.s, strlen(external->value.s), obj, NULL);
300
0
      break;
301
0
    }
302
303
0
    if (result == ERROR_SUCCESS)
304
0
    {
305
0
      *object = obj;
306
0
    }
307
0
    else
308
0
    {
309
0
      yr_object_destroy(obj);
310
0
    }
311
0
  }
312
313
0
  return result;
314
0
}
315
316
////////////////////////////////////////////////////////////////////////////////
317
// Destroy an objects, and any other object that is a child of it. For example,
318
// destroying a struct will destroy all its members.
319
//
320
void yr_object_destroy(YR_OBJECT* object)
321
40.5M
{
322
40.5M
  YR_STRUCTURE_MEMBER* member;
323
40.5M
  YR_STRUCTURE_MEMBER* next_member;
324
40.5M
  YR_ARRAY_ITEMS* array_items;
325
40.5M
  YR_DICTIONARY_ITEMS* dict_items;
326
327
40.5M
  if (object == NULL)
328
0
    return;
329
330
40.5M
  switch (object->type)
331
40.5M
  {
332
7.55M
  case OBJECT_TYPE_STRUCTURE:
333
7.55M
    member = object_as_structure(object)->members;
334
335
40.4M
    while (member != NULL)
336
32.8M
    {
337
32.8M
      next_member = member->next;
338
32.8M
      yr_object_destroy(member->object);
339
32.8M
      yr_free(member);
340
32.8M
      member = next_member;
341
32.8M
    }
342
7.55M
    break;
343
344
10.7M
  case OBJECT_TYPE_STRING:
345
10.7M
    if (object->value.ss != NULL)
346
6.14M
      yr_free(object->value.ss);
347
10.7M
    break;
348
349
88.4k
  case OBJECT_TYPE_ARRAY:
350
88.4k
    if (object_as_array(object)->prototype_item != NULL)
351
88.4k
      yr_object_destroy(object_as_array(object)->prototype_item);
352
353
88.4k
    array_items = object_as_array(object)->items;
354
355
88.4k
    if (array_items != NULL)
356
35.7k
    {
357
7.45M
      for (int i = 0; i < array_items->length; i++)
358
7.41M
        if (array_items->objects[i] != NULL)
359
7.41M
          yr_object_destroy(array_items->objects[i]);
360
35.7k
    }
361
362
88.4k
    yr_free(array_items);
363
88.4k
    break;
364
365
6.57k
  case OBJECT_TYPE_DICTIONARY:
366
6.57k
    if (object_as_dictionary(object)->prototype_item != NULL)
367
6.57k
      yr_object_destroy(object_as_dictionary(object)->prototype_item);
368
369
6.57k
    dict_items = object_as_dictionary(object)->items;
370
371
6.57k
    if (dict_items != NULL)
372
240
    {
373
2.59k
      for (int i = 0; i < dict_items->used; i++)
374
2.35k
      {
375
2.35k
        if (dict_items->objects[i].key != NULL)
376
2.35k
          yr_free(dict_items->objects[i].key);
377
378
2.35k
        if (dict_items->objects[i].obj != NULL)
379
2.35k
          yr_object_destroy(dict_items->objects[i].obj);
380
2.35k
      }
381
240
    }
382
383
6.57k
    yr_free(dict_items);
384
6.57k
    break;
385
386
98.5k
  case OBJECT_TYPE_FUNCTION:
387
98.5k
    yr_object_destroy(object_as_function(object)->return_obj);
388
98.5k
    break;
389
40.5M
  }
390
391
40.5M
  yr_free((void*) object->identifier);
392
40.5M
  yr_free(object);
393
40.5M
}
394
395
YR_OBJECT* yr_object_lookup_field(YR_OBJECT* object, const char* field_name)
396
102M
{
397
102M
  YR_STRUCTURE_MEMBER* member;
398
399
102M
  assert(object != NULL);
400
102M
  assert(object->type == OBJECT_TYPE_STRUCTURE);
401
402
102M
  member = object_as_structure(object)->members;
403
404
784M
  while (member != NULL)
405
751M
  {
406
751M
    if (strcmp(member->object->identifier, field_name) == 0)
407
69.5M
      return member->object;
408
409
681M
    member = member->next;
410
681M
  }
411
412
32.9M
  return NULL;
413
102M
}
414
415
static YR_OBJECT* _yr_object_lookup(
416
    YR_OBJECT* object,
417
    int flags,
418
    const char* pattern,
419
    va_list args)
420
27.1M
{
421
27.1M
  YR_OBJECT* obj = object;
422
423
27.1M
  const char* p = pattern;
424
27.1M
  const char* key = NULL;
425
426
27.1M
  char str[256];
427
428
27.1M
  int i;
429
27.1M
  int index = -1;
430
431
69.4M
  while (obj != NULL)
432
69.4M
  {
433
69.4M
    i = 0;
434
435
783M
    while (*p != '\0' && *p != '.' && *p != '[' && i < sizeof(str) - 1)
436
713M
    {
437
713M
      str[i++] = *p++;
438
713M
    }
439
440
69.4M
    str[i] = '\0';
441
442
69.4M
    if (obj->type != OBJECT_TYPE_STRUCTURE)
443
0
      return NULL;
444
445
69.4M
    obj = yr_object_lookup_field(obj, str);
446
447
69.4M
    if (obj == NULL)
448
0
      return NULL;
449
450
69.4M
    if (*p == '[')
451
42.2M
    {
452
42.2M
      p++;
453
454
42.2M
      if (*p == '%')
455
42.2M
      {
456
42.2M
        p++;
457
458
42.2M
        switch (*p++)
459
42.2M
        {
460
42.1M
        case 'i':
461
42.1M
          index = va_arg(args, int);
462
42.1M
          break;
463
7.45k
        case 's':
464
7.45k
          key = va_arg(args, const char*);
465
7.45k
          break;
466
467
0
        default:
468
0
          return NULL;
469
42.2M
        }
470
42.2M
      }
471
0
      else if (*p >= '0' && *p <= '9')
472
0
      {
473
0
        index = (int) strtol(p, (char**) &p, 10);
474
0
      }
475
0
      else if (*p == '"')
476
0
      {
477
0
        i = 0;
478
0
        p++;  // skip the opening quotation mark
479
480
0
        while (*p != '"' && *p != '\0' && i < sizeof(str) - 1) str[i++] = *p++;
481
482
0
        str[i] = '\0';
483
0
        p++;  // skip the closing quotation mark
484
0
        key = str;
485
0
      }
486
0
      else
487
0
      {
488
0
        return NULL;
489
0
      }
490
491
42.2M
      assert(*p == ']');
492
42.2M
      p++;
493
42.2M
      assert(*p == '.' || *p == '\0');
494
495
42.2M
      switch (obj->type)
496
42.2M
      {
497
42.1M
      case OBJECT_TYPE_ARRAY:
498
42.1M
        assert(index != -1);
499
42.1M
        obj = yr_object_array_get_item(obj, flags, index);
500
42.1M
        break;
501
502
7.45k
      case OBJECT_TYPE_DICTIONARY:
503
7.45k
        assert(key != NULL);
504
7.45k
        obj = yr_object_dict_get_item(obj, flags, key);
505
7.45k
        break;
506
42.2M
      }
507
42.2M
    }
508
509
69.4M
    if (*p == '\0')
510
27.1M
      break;
511
512
42.2M
    p++;
513
42.2M
  }
514
515
27.1M
  return obj;
516
27.1M
}
517
518
YR_OBJECT* yr_object_lookup(
519
    YR_OBJECT* object,
520
    int flags,
521
    const char* pattern,
522
    ...)
523
0
{
524
0
  YR_OBJECT* result;
525
526
0
  va_list args;
527
0
  va_start(args, pattern);
528
529
0
  result = _yr_object_lookup(object, flags, pattern, args);
530
531
0
  va_end(args);
532
533
0
  return result;
534
0
}
535
536
int yr_object_copy(YR_OBJECT* object, YR_OBJECT** object_copy)
537
38.3M
{
538
38.3M
  YR_OBJECT* copy;
539
38.3M
  YR_OBJECT* o;
540
541
38.3M
  YR_STRUCTURE_MEMBER* structure_member;
542
543
38.3M
  *object_copy = NULL;
544
545
38.3M
  FAIL_ON_ERROR(
546
38.3M
      yr_object_create(object->type, object->identifier, NULL, &copy));
547
548
38.3M
  copy->canary = object->canary;
549
550
38.3M
  switch (object->type)
551
38.3M
  {
552
20.2M
  case OBJECT_TYPE_INTEGER:
553
20.2M
    copy->value.i = object->value.i;
554
20.2M
    break;
555
556
0
  case OBJECT_TYPE_FLOAT:
557
0
    copy->value.d = object->value.d;
558
0
    break;
559
560
10.6M
  case OBJECT_TYPE_STRING:
561
562
10.6M
    if (object->value.ss != NULL)
563
0
      copy->value.ss = ss_dup(object->value.ss);
564
10.6M
    else
565
10.6M
      copy->value.ss = NULL;
566
567
10.6M
    break;
568
569
0
  case OBJECT_TYPE_FUNCTION:
570
571
0
    FAIL_ON_ERROR_WITH_CLEANUP(
572
0
        yr_object_copy(
573
0
            object_as_function(object)->return_obj,
574
0
            &object_as_function(copy)->return_obj),
575
        // cleanup
576
0
        yr_object_destroy(copy));
577
578
0
    for (int i = 0; i < YR_MAX_OVERLOADED_FUNCTIONS; i++)
579
0
      object_as_function(copy)->prototypes[i] =
580
0
          object_as_function(object)->prototypes[i];
581
582
0
    break;
583
584
7.44M
  case OBJECT_TYPE_STRUCTURE:
585
586
7.44M
    structure_member = object_as_structure(object)->members;
587
588
38.3M
    while (structure_member != NULL)
589
30.9M
    {
590
30.9M
      FAIL_ON_ERROR_WITH_CLEANUP(
591
30.9M
          yr_object_copy(structure_member->object, &o),
592
30.9M
          yr_object_destroy(copy));
593
594
30.9M
      FAIL_ON_ERROR_WITH_CLEANUP(yr_object_structure_set_member(copy, o),
595
                                 // cleanup
596
30.9M
                                 yr_free(o);
597
30.9M
                                 yr_object_destroy(copy));
598
599
30.9M
      structure_member = structure_member->next;
600
30.9M
    }
601
602
7.44M
    break;
603
604
7.44M
  case OBJECT_TYPE_ARRAY:
605
606
29.3k
    FAIL_ON_ERROR_WITH_CLEANUP(
607
29.3k
        yr_object_copy(object_as_array(object)->prototype_item, &o),
608
29.3k
        yr_object_destroy(copy));
609
610
29.3k
    object_as_array(copy)->prototype_item = o;
611
612
29.3k
    break;
613
614
0
  case OBJECT_TYPE_DICTIONARY:
615
616
0
    FAIL_ON_ERROR_WITH_CLEANUP(
617
0
        yr_object_copy(object_as_dictionary(object)->prototype_item, &o),
618
0
        yr_object_destroy(copy));
619
620
0
    object_as_dictionary(copy)->prototype_item = o;
621
622
0
    break;
623
624
0
  default:
625
0
    assert(false);
626
38.3M
  }
627
628
38.3M
  *object_copy = copy;
629
630
38.3M
  return ERROR_SUCCESS;
631
38.3M
}
632
633
int yr_object_structure_set_member(YR_OBJECT* object, YR_OBJECT* member)
634
32.8M
{
635
32.8M
  YR_STRUCTURE_MEMBER* sm;
636
637
32.8M
  assert(object->type == OBJECT_TYPE_STRUCTURE);
638
639
  // Check if the object already have a member with the same identifier
640
641
32.8M
  if (yr_object_lookup_field(object, member->identifier) != NULL)
642
0
    return ERROR_DUPLICATED_STRUCTURE_MEMBER;
643
644
32.8M
  sm = (YR_STRUCTURE_MEMBER*) yr_malloc(sizeof(YR_STRUCTURE_MEMBER));
645
646
32.8M
  if (sm == NULL)
647
0
    return ERROR_INSUFFICIENT_MEMORY;
648
649
32.8M
  member->parent = object;
650
32.8M
  sm->object = member;
651
32.8M
  sm->next = object_as_structure(object)->members;
652
653
32.8M
  object_as_structure(object)->members = sm;
654
655
32.8M
  return ERROR_SUCCESS;
656
32.8M
}
657
658
int yr_object_array_length(YR_OBJECT* object)
659
0
{
660
0
  YR_OBJECT_ARRAY* array;
661
662
0
  assert(object->type == OBJECT_TYPE_ARRAY);
663
0
  array = object_as_array(object);
664
665
0
  if (array->items == NULL)
666
0
    return 0;
667
668
0
  return array->items->length;
669
0
}
670
671
YR_OBJECT* yr_object_array_get_item(YR_OBJECT* object, int flags, int index)
672
42.2M
{
673
42.2M
  YR_OBJECT* result = NULL;
674
42.2M
  YR_OBJECT_ARRAY* array;
675
676
42.2M
  assert(object->type == OBJECT_TYPE_ARRAY);
677
678
42.2M
  if (index < 0)
679
0
    return NULL;
680
681
42.2M
  array = object_as_array(object);
682
683
42.2M
  if (array->items != NULL && array->items->capacity > index)
684
42.1M
    result = array->items->objects[index];
685
686
42.2M
  if (result == NULL && flags & OBJECT_CREATE)
687
7.41M
  {
688
7.41M
    yr_object_copy(array->prototype_item, &result);
689
690
7.41M
    if (result != NULL)
691
7.41M
      yr_object_array_set_item(object, result, index);
692
7.41M
  }
693
694
42.2M
  return result;
695
42.2M
}
696
697
int yr_object_array_set_item(YR_OBJECT* object, YR_OBJECT* item, int index)
698
7.41M
{
699
7.41M
  YR_OBJECT_ARRAY* array;
700
701
7.41M
  int capacity;
702
703
7.41M
  assert(index >= 0);
704
7.41M
  assert(object->type == OBJECT_TYPE_ARRAY);
705
706
7.41M
  array = object_as_array(object);
707
708
7.41M
  if (array->items == NULL)
709
35.7k
  {
710
35.7k
    capacity = 64;
711
712
35.7k
    while (capacity <= index) capacity *= 2;
713
714
35.7k
    array->items = (YR_ARRAY_ITEMS*) yr_malloc(
715
35.7k
        sizeof(YR_ARRAY_ITEMS) + capacity * sizeof(YR_OBJECT*));
716
717
35.7k
    if (array->items == NULL)
718
0
      return ERROR_INSUFFICIENT_MEMORY;
719
720
35.7k
    memset(array->items->objects, 0, capacity * sizeof(YR_OBJECT*));
721
722
35.7k
    array->items->capacity = capacity;
723
35.7k
    array->items->length = 0;
724
35.7k
  }
725
7.37M
  else if (index >= array->items->capacity)
726
16.7k
  {
727
16.7k
    capacity = array->items->capacity * 2;
728
729
16.7k
    while (capacity <= index) capacity *= 2;
730
731
16.7k
    array->items = (YR_ARRAY_ITEMS*) yr_realloc(
732
16.7k
        array->items, sizeof(YR_ARRAY_ITEMS) + capacity * sizeof(YR_OBJECT*));
733
734
16.7k
    if (array->items == NULL)
735
0
      return ERROR_INSUFFICIENT_MEMORY;
736
737
8.54M
    for (int i = array->items->capacity; i < capacity; i++)
738
8.52M
      array->items->objects[i] = NULL;
739
740
16.7k
    array->items->capacity = capacity;
741
16.7k
  }
742
743
7.41M
  item->parent = object;
744
7.41M
  array->items->objects[index] = item;
745
746
7.41M
  if (index >= array->items->length)
747
7.41M
    array->items->length = index + 1;
748
749
7.41M
  return ERROR_SUCCESS;
750
7.41M
}
751
752
YR_OBJECT* yr_object_dict_get_item(
753
    YR_OBJECT* object,
754
    int flags,
755
    const char* key)
756
7.45k
{
757
7.45k
  YR_OBJECT* result = NULL;
758
7.45k
  YR_OBJECT_DICTIONARY* dict;
759
760
7.45k
  assert(object->type == OBJECT_TYPE_DICTIONARY);
761
762
7.45k
  dict = object_as_dictionary(object);
763
764
7.45k
  if (dict->items != NULL)
765
7.21k
  {
766
147k
    for (int i = 0; i < dict->items->used; i++)
767
139k
    {
768
139k
      if (strcmp(dict->items->objects[i].key->c_string, key) == 0)
769
5.09k
        result = dict->items->objects[i].obj;
770
139k
    }
771
7.21k
  }
772
773
7.45k
  if (result == NULL && flags & OBJECT_CREATE)
774
2.35k
  {
775
2.35k
    yr_object_copy(dict->prototype_item, &result);
776
777
2.35k
    if (result != NULL)
778
2.35k
      yr_object_dict_set_item(object, result, key);
779
2.35k
  }
780
781
7.45k
  return result;
782
7.45k
}
783
784
int yr_object_dict_set_item(YR_OBJECT* object, YR_OBJECT* item, const char* key)
785
2.35k
{
786
2.35k
  YR_OBJECT_DICTIONARY* dict;
787
788
2.35k
  int count;
789
790
2.35k
  assert(object->type == OBJECT_TYPE_DICTIONARY);
791
792
2.35k
  dict = object_as_dictionary(object);
793
794
2.35k
  if (dict->items == NULL)
795
240
  {
796
240
    count = 64;
797
798
240
    dict->items = (YR_DICTIONARY_ITEMS*) yr_malloc(
799
240
        sizeof(YR_DICTIONARY_ITEMS) + count * sizeof(dict->items->objects[0]));
800
801
240
    if (dict->items == NULL)
802
0
      return ERROR_INSUFFICIENT_MEMORY;
803
804
240
    memset(dict->items->objects, 0, count * sizeof(dict->items->objects[0]));
805
806
240
    dict->items->free = count;
807
240
    dict->items->used = 0;
808
240
  }
809
2.11k
  else if (dict->items->free == 0)
810
8
  {
811
8
    count = dict->items->used * 2;
812
8
    dict->items = (YR_DICTIONARY_ITEMS*) yr_realloc(
813
8
        dict->items,
814
8
        sizeof(YR_DICTIONARY_ITEMS) + count * sizeof(dict->items->objects[0]));
815
816
8
    if (dict->items == NULL)
817
0
      return ERROR_INSUFFICIENT_MEMORY;
818
819
840
    for (int i = dict->items->used; i < count; i++)
820
832
    {
821
832
      dict->items->objects[i].key = NULL;
822
832
      dict->items->objects[i].obj = NULL;
823
832
    }
824
825
8
    dict->items->free = dict->items->used;
826
8
  }
827
828
2.35k
  item->parent = object;
829
830
2.35k
  dict->items->objects[dict->items->used].key = ss_new(key);
831
2.35k
  dict->items->objects[dict->items->used].obj = item;
832
833
2.35k
  dict->items->used++;
834
2.35k
  dict->items->free--;
835
836
2.35k
  return ERROR_SUCCESS;
837
2.35k
}
838
839
bool yr_object_has_undefined_value(YR_OBJECT* object, const char* field, ...)
840
0
{
841
0
  YR_OBJECT* field_obj;
842
843
0
  va_list args;
844
0
  va_start(args, field);
845
846
0
  if (field != NULL)
847
0
    field_obj = _yr_object_lookup(object, 0, field, args);
848
0
  else
849
0
    field_obj = object;
850
851
0
  va_end(args);
852
853
0
  if (field_obj == NULL)
854
0
    return true;
855
856
0
  switch (field_obj->type)
857
0
  {
858
0
  case OBJECT_TYPE_FLOAT:
859
0
    return yr_isnan(field_obj->value.d);
860
0
  case OBJECT_TYPE_STRING:
861
0
    return field_obj->value.ss == NULL;
862
0
  case OBJECT_TYPE_INTEGER:
863
0
    return field_obj->value.i == YR_UNDEFINED;
864
0
  }
865
866
0
  return false;
867
0
}
868
869
int64_t yr_object_get_integer(YR_OBJECT* object, const char* field, ...)
870
0
{
871
0
  YR_OBJECT* integer_obj;
872
873
0
  va_list args;
874
0
  va_start(args, field);
875
876
0
  if (field != NULL)
877
0
    integer_obj = _yr_object_lookup(object, 0, field, args);
878
0
  else
879
0
    integer_obj = object;
880
881
0
  va_end(args);
882
883
0
  if (integer_obj == NULL)
884
0
    return YR_UNDEFINED;
885
886
0
  assertf(
887
0
      integer_obj->type == OBJECT_TYPE_INTEGER,
888
0
      "type of \"%s\" is not integer\n",
889
0
      field);
890
891
0
  return integer_obj->value.i;
892
0
}
893
894
double yr_object_get_float(YR_OBJECT* object, const char* field, ...)
895
0
{
896
0
  YR_OBJECT* double_obj;
897
898
0
  va_list args;
899
0
  va_start(args, field);
900
901
0
  if (field != NULL)
902
0
    double_obj = _yr_object_lookup(object, 0, field, args);
903
0
  else
904
0
    double_obj = object;
905
906
0
  va_end(args);
907
908
0
  if (double_obj == NULL)
909
0
    return NAN;
910
911
0
  assertf(
912
0
      double_obj->type == OBJECT_TYPE_FLOAT,
913
0
      "type of \"%s\" is not double\n",
914
0
      field);
915
916
0
  return double_obj->value.d;
917
0
}
918
919
SIZED_STRING* yr_object_get_string(YR_OBJECT* object, const char* field, ...)
920
0
{
921
0
  YR_OBJECT* string_obj;
922
923
0
  va_list args;
924
0
  va_start(args, field);
925
926
0
  if (field != NULL)
927
0
    string_obj = _yr_object_lookup(object, 0, field, args);
928
0
  else
929
0
    string_obj = object;
930
931
0
  va_end(args);
932
933
0
  if (string_obj == NULL)
934
0
    return NULL;
935
936
0
  assertf(
937
0
      string_obj->type == OBJECT_TYPE_STRING,
938
0
      "type of \"%s\" is not string\n",
939
0
      field);
940
941
0
  return string_obj->value.ss;
942
0
}
943
944
int yr_object_set_integer(
945
    int64_t value,
946
    YR_OBJECT* object,
947
    const char* field,
948
    ...)
949
21.0M
{
950
21.0M
  YR_OBJECT* integer_obj;
951
952
21.0M
  va_list args;
953
21.0M
  va_start(args, field);
954
955
21.0M
  if (field != NULL)
956
21.0M
    integer_obj = _yr_object_lookup(object, OBJECT_CREATE, field, args);
957
1.76k
  else
958
1.76k
    integer_obj = object;
959
960
21.0M
  va_end(args);
961
962
21.0M
  if (integer_obj == NULL)
963
0
  {
964
0
    if (field != NULL)
965
0
      return ERROR_INSUFFICIENT_MEMORY;
966
0
    else
967
0
      return ERROR_INVALID_ARGUMENT;
968
0
  }
969
970
21.0M
  assert(integer_obj->type == OBJECT_TYPE_INTEGER);
971
972
21.0M
  integer_obj->value.i = value;
973
974
21.0M
  return ERROR_SUCCESS;
975
21.0M
}
976
977
int yr_object_set_float(double value, YR_OBJECT* object, const char* field, ...)
978
0
{
979
0
  YR_OBJECT* double_obj;
980
981
0
  va_list args;
982
0
  va_start(args, field);
983
984
0
  if (field != NULL)
985
0
    double_obj = _yr_object_lookup(object, OBJECT_CREATE, field, args);
986
0
  else
987
0
    double_obj = object;
988
989
0
  va_end(args);
990
991
0
  if (double_obj == NULL)
992
0
  {
993
0
    if (field != NULL)
994
0
      return ERROR_INSUFFICIENT_MEMORY;
995
0
    else
996
0
      return ERROR_INVALID_ARGUMENT;
997
0
  }
998
999
0
  assert(double_obj->type == OBJECT_TYPE_FLOAT);
1000
1001
0
  double_obj->value.d = value;
1002
1003
0
  return ERROR_SUCCESS;
1004
0
}
1005
1006
int yr_object_set_string(
1007
    const char* value,
1008
    size_t len,
1009
    YR_OBJECT* object,
1010
    const char* field,
1011
    ...)
1012
6.15M
{
1013
6.15M
  YR_OBJECT* string_obj;
1014
1015
6.15M
  va_list args;
1016
6.15M
  va_start(args, field);
1017
1018
6.15M
  if (field != NULL)
1019
6.15M
    string_obj = _yr_object_lookup(object, OBJECT_CREATE, field, args);
1020
0
  else
1021
0
    string_obj = object;
1022
1023
6.15M
  va_end(args);
1024
1025
6.15M
  if (string_obj == NULL)
1026
0
  {
1027
0
    if (field != NULL)
1028
0
      return ERROR_INSUFFICIENT_MEMORY;
1029
0
    else
1030
0
      return ERROR_INVALID_ARGUMENT;
1031
0
  }
1032
1033
6.15M
  assert(string_obj->type == OBJECT_TYPE_STRING);
1034
1035
6.15M
  if (string_obj->value.ss != NULL)
1036
5.09k
    yr_free(string_obj->value.ss);
1037
1038
6.15M
  if (value != NULL)
1039
6.15M
  {
1040
6.15M
    string_obj->value.ss = (SIZED_STRING*) yr_malloc(
1041
6.15M
        len + sizeof(SIZED_STRING));
1042
1043
6.15M
    if (string_obj->value.ss == NULL)
1044
0
      return ERROR_INSUFFICIENT_MEMORY;
1045
1046
6.15M
    string_obj->value.ss->length = (uint32_t) len;
1047
6.15M
    string_obj->value.ss->flags = 0;
1048
1049
6.15M
    memcpy(string_obj->value.ss->c_string, value, len);
1050
6.15M
    string_obj->value.ss->c_string[len] = '\0';
1051
6.15M
  }
1052
648
  else
1053
648
  {
1054
648
    string_obj->value.ss = NULL;
1055
648
  }
1056
1057
6.15M
  return ERROR_SUCCESS;
1058
6.15M
}
1059
1060
YR_OBJECT* yr_object_get_root(YR_OBJECT* object)
1061
1.76k
{
1062
1.76k
  YR_OBJECT* o = object;
1063
1064
3.52k
  while (o->parent != NULL) o = o->parent;
1065
1066
1.76k
  return o;
1067
1.76k
}
1068
1069
YR_API void yr_object_print_data(
1070
    YR_OBJECT* object,
1071
    int indent,
1072
    int print_identifier)
1073
0
{
1074
0
  YR_DICTIONARY_ITEMS* dict_items;
1075
0
  YR_STRUCTURE_MEMBER* member;
1076
1077
0
  char indent_spaces[32];
1078
1079
0
  indent = yr_min(indent, sizeof(indent_spaces) - 1);
1080
1081
0
  memset(indent_spaces, '\t', indent);
1082
0
  indent_spaces[indent] = '\0';
1083
1084
0
  if (print_identifier && object->type != OBJECT_TYPE_FUNCTION)
1085
0
    printf("%s%s", indent_spaces, object->identifier);
1086
1087
0
  switch (object->type)
1088
0
  {
1089
0
  case OBJECT_TYPE_FLOAT:
1090
0
    if (object->value.i != YR_UNDEFINED)
1091
0
      printf(" = %f", object->value.d);
1092
0
    else
1093
0
      printf(" = YR_UNDEFINED");
1094
1095
0
    break;
1096
1097
0
  case OBJECT_TYPE_INTEGER:
1098
1099
0
    if (object->value.i != YR_UNDEFINED)
1100
0
      printf(" = %" PRId64, object->value.i);
1101
0
    else
1102
0
      printf(" = YR_UNDEFINED");
1103
1104
0
    break;
1105
1106
0
  case OBJECT_TYPE_STRING:
1107
1108
0
    if (object->value.ss != NULL)
1109
0
    {
1110
0
      printf(" = \"");
1111
1112
0
      for (size_t l = 0; l < object->value.ss->length; l++)
1113
0
      {
1114
0
        char c = object->value.ss->c_string[l];
1115
1116
0
        if (isprint((unsigned char) c))
1117
0
          printf("%c", c);
1118
0
        else
1119
0
          printf("\\x%02x", (unsigned char) c);
1120
0
      }
1121
1122
0
      printf("\"");
1123
0
    }
1124
0
    else
1125
0
    {
1126
0
      printf(" = YR_UNDEFINED");
1127
0
    }
1128
1129
0
    break;
1130
1131
0
  case OBJECT_TYPE_STRUCTURE:
1132
1133
0
    member = object_as_structure(object)->members;
1134
1135
0
    while (member != NULL)
1136
0
    {
1137
0
      if (member->object->type != OBJECT_TYPE_FUNCTION)
1138
0
      {
1139
0
        printf("\n");
1140
0
        yr_object_print_data(member->object, indent + 1, 1);
1141
0
      }
1142
0
      member = member->next;
1143
0
    }
1144
1145
0
    break;
1146
1147
0
  case OBJECT_TYPE_ARRAY:
1148
0
    for (int i = 0; i < yr_object_array_length(object); i++)
1149
0
    {
1150
0
      YR_OBJECT* o = yr_object_array_get_item(object, 0, i);
1151
1152
0
      if (o != NULL)
1153
0
      {
1154
0
        printf("\n%s\t[%d]", indent_spaces, i);
1155
0
        yr_object_print_data(o, indent + 1, 0);
1156
0
      }
1157
0
    }
1158
0
    break;
1159
1160
0
  case OBJECT_TYPE_DICTIONARY:
1161
1162
0
    dict_items = object_as_dictionary(object)->items;
1163
1164
0
    if (dict_items != NULL)
1165
0
    {
1166
0
      for (int i = 0; i < dict_items->used; i++)
1167
0
      {
1168
0
        printf("\n%s\t%s", indent_spaces, dict_items->objects[i].key->c_string);
1169
1170
0
        yr_object_print_data(dict_items->objects[i].obj, indent + 1, 0);
1171
0
      }
1172
0
    }
1173
1174
0
    break;
1175
0
  }
1176
0
}