Coverage Report

Created: 2023-03-26 07:37

/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
9.34M
{
57
9.34M
  YR_OBJECT* obj;
58
9.34M
  size_t object_size = 0;
59
60
9.34M
  assert(parent != NULL || object != NULL);
61
9.34M
  assert(identifier != NULL);
62
63
9.34M
  switch (type)
64
9.34M
  {
65
1.45M
  case OBJECT_TYPE_STRUCTURE:
66
1.45M
    object_size = sizeof(YR_OBJECT_STRUCTURE);
67
1.45M
    break;
68
40.0k
  case OBJECT_TYPE_ARRAY:
69
40.0k
    object_size = sizeof(YR_OBJECT_ARRAY);
70
40.0k
    break;
71
0
  case OBJECT_TYPE_DICTIONARY:
72
0
    object_size = sizeof(YR_OBJECT_DICTIONARY);
73
0
    break;
74
7.28M
  case OBJECT_TYPE_INTEGER:
75
7.28M
    object_size = sizeof(YR_OBJECT);
76
7.28M
    break;
77
0
  case OBJECT_TYPE_FLOAT:
78
0
    object_size = sizeof(YR_OBJECT);
79
0
    break;
80
557k
  case OBJECT_TYPE_STRING:
81
557k
    object_size = sizeof(YR_OBJECT);
82
557k
    break;
83
8.00k
  case OBJECT_TYPE_FUNCTION:
84
8.00k
    object_size = sizeof(YR_OBJECT_FUNCTION);
85
8.00k
    break;
86
0
  default:
87
0
    assert(false);
88
9.34M
  }
89
90
9.34M
  obj = (YR_OBJECT*) yr_malloc(object_size);
91
92
9.34M
  if (obj == NULL)
93
0
    return ERROR_INSUFFICIENT_MEMORY;
94
95
9.34M
  obj->type = type;
96
9.34M
  obj->identifier = yr_strdup(identifier);
97
9.34M
  obj->parent = parent;
98
9.34M
  obj->data = NULL;
99
100
9.34M
  switch (type)
101
9.34M
  {
102
7.28M
  case OBJECT_TYPE_INTEGER:
103
7.28M
    obj->value.i = YR_UNDEFINED;
104
7.28M
    break;
105
0
  case OBJECT_TYPE_FLOAT:
106
0
    obj->value.d = NAN;
107
0
    break;
108
557k
  case OBJECT_TYPE_STRING:
109
557k
    obj->value.ss = NULL;
110
557k
    break;
111
1.45M
  case OBJECT_TYPE_STRUCTURE:
112
1.45M
    object_as_structure(obj)->members = NULL;
113
1.45M
    break;
114
40.0k
  case OBJECT_TYPE_ARRAY:
115
40.0k
    object_as_array(obj)->items = NULL;
116
40.0k
    object_as_array(obj)->prototype_item = NULL;
117
40.0k
    break;
118
0
  case OBJECT_TYPE_DICTIONARY:
119
0
    object_as_dictionary(obj)->items = NULL;
120
0
    object_as_dictionary(obj)->prototype_item = NULL;
121
0
    break;
122
8.00k
  case OBJECT_TYPE_FUNCTION:
123
8.00k
    object_as_function(obj)->return_obj = NULL;
124
88.0k
    for (int i = 0; i < YR_MAX_OVERLOADED_FUNCTIONS; i++)
125
80.0k
    {
126
80.0k
      object_as_function(obj)->prototypes[i].arguments_fmt = NULL;
127
80.0k
      object_as_function(obj)->prototypes[i].code = NULL;
128
80.0k
    }
129
8.00k
    break;
130
9.34M
  }
131
132
9.34M
  if (obj->identifier == NULL)
133
0
  {
134
0
    yr_free(obj);
135
0
    return ERROR_INSUFFICIENT_MEMORY;
136
0
  }
137
138
9.34M
  if (parent != NULL)
139
1.12M
  {
140
1.12M
    assert(
141
1.12M
        parent->type == OBJECT_TYPE_STRUCTURE ||
142
1.12M
        parent->type == OBJECT_TYPE_ARRAY ||
143
1.12M
        parent->type == OBJECT_TYPE_DICTIONARY ||
144
1.12M
        parent->type == OBJECT_TYPE_FUNCTION);
145
146
    // Objects with a parent take the canary from it.
147
1.12M
    obj->canary = parent->canary;
148
149
1.12M
    switch (parent->type)
150
1.12M
    {
151
1.08M
    case OBJECT_TYPE_STRUCTURE:
152
1.08M
      FAIL_ON_ERROR_WITH_CLEANUP(yr_object_structure_set_member(parent, obj), {
153
1.08M
        yr_free((void*) obj->identifier);
154
1.08M
        yr_free(obj);
155
1.08M
      });
156
1.08M
      break;
157
158
40.0k
    case OBJECT_TYPE_ARRAY:
159
40.0k
      object_as_array(parent)->prototype_item = obj;
160
40.0k
      break;
161
162
0
    case OBJECT_TYPE_DICTIONARY:
163
0
      object_as_dictionary(parent)->prototype_item = obj;
164
0
      break;
165
166
8.00k
    case OBJECT_TYPE_FUNCTION:
167
8.00k
      object_as_function(parent)->return_obj = obj;
168
8.00k
      break;
169
1.12M
    }
170
1.12M
  }
171
172
9.34M
  if (object != NULL)
173
8.31M
    *object = obj;
174
175
9.34M
  return ERROR_SUCCESS;
176
9.34M
}
177
178
void yr_object_set_canary(YR_OBJECT* object, int canary)
179
8.00k
{
180
8.00k
  object->canary = canary;
181
8.00k
}
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
8.00k
{
191
8.00k
  YR_OBJECT* return_obj;
192
8.00k
  YR_OBJECT* o = NULL;
193
8.00k
  YR_OBJECT_FUNCTION* f = NULL;
194
195
8.00k
  int8_t return_type;
196
197
  // The parent of a function must be a structure.
198
8.00k
  assert(parent != NULL && parent->type == OBJECT_TYPE_STRUCTURE);
199
200
8.00k
  switch (*return_fmt)
201
8.00k
  {
202
0
  case 'i':
203
0
    return_type = OBJECT_TYPE_INTEGER;
204
0
    break;
205
8.00k
  case 's':
206
8.00k
    return_type = OBJECT_TYPE_STRING;
207
8.00k
    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
8.00k
  }
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
8.00k
  f = object_as_function(yr_object_lookup_field(parent, identifier));
218
219
  // Overloaded functions must have the same return type.
220
8.00k
  if (f != NULL && return_type != f->return_obj->type)
221
0
    return ERROR_WRONG_RETURN_TYPE;
222
223
8.00k
  if (f == NULL)  // Function doesn't exist yet
224
8.00k
  {
225
8.00k
    FAIL_ON_ERROR(
226
8.00k
        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
8.00k
    FAIL_ON_ERROR(yr_object_create(return_type, "result", o, &return_obj));
232
233
8.00k
    f = object_as_function(o);
234
8.00k
  }
235
236
8.00k
  for (int i = 0; i < YR_MAX_OVERLOADED_FUNCTIONS; i++)
237
8.00k
  {
238
8.00k
    if (f->prototypes[i].arguments_fmt == NULL)
239
8.00k
    {
240
8.00k
      f->prototypes[i].arguments_fmt = arguments_fmt;
241
8.00k
      f->prototypes[i].code = code;
242
243
8.00k
      break;
244
8.00k
    }
245
8.00k
  }
246
247
8.00k
  if (function != NULL)
248
8.00k
    *function = (YR_OBJECT*) f;
249
250
8.00k
  return ERROR_SUCCESS;
251
8.00k
}
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
9.34M
{
322
9.34M
  YR_STRUCTURE_MEMBER* member;
323
9.34M
  YR_STRUCTURE_MEMBER* next_member;
324
9.34M
  YR_ARRAY_ITEMS* array_items;
325
9.34M
  YR_DICTIONARY_ITEMS* dict_items;
326
327
9.34M
  if (object == NULL)
328
0
    return;
329
330
9.34M
  switch (object->type)
331
9.34M
  {
332
1.45M
  case OBJECT_TYPE_STRUCTURE:
333
1.45M
    member = object_as_structure(object)->members;
334
335
9.34M
    while (member != NULL)
336
7.88M
    {
337
7.88M
      next_member = member->next;
338
7.88M
      yr_object_destroy(member->object);
339
7.88M
      yr_free(member);
340
7.88M
      member = next_member;
341
7.88M
    }
342
1.45M
    break;
343
344
557k
  case OBJECT_TYPE_STRING:
345
557k
    if (object->value.ss != NULL)
346
115k
      yr_free(object->value.ss);
347
557k
    break;
348
349
40.0k
  case OBJECT_TYPE_ARRAY:
350
40.0k
    if (object_as_array(object)->prototype_item != NULL)
351
40.0k
      yr_object_destroy(object_as_array(object)->prototype_item);
352
353
40.0k
    array_items = object_as_array(object)->items;
354
355
40.0k
    if (array_items != NULL)
356
6.60k
    {
357
1.41M
      for (int i = 0; i < array_items->length; i++)
358
1.40M
        if (array_items->objects[i] != NULL)
359
1.40M
          yr_object_destroy(array_items->objects[i]);
360
6.60k
    }
361
362
40.0k
    yr_free(array_items);
363
40.0k
    break;
364
365
0
  case OBJECT_TYPE_DICTIONARY:
366
0
    if (object_as_dictionary(object)->prototype_item != NULL)
367
0
      yr_object_destroy(object_as_dictionary(object)->prototype_item);
368
369
0
    dict_items = object_as_dictionary(object)->items;
370
371
0
    if (dict_items != NULL)
372
0
    {
373
0
      for (int i = 0; i < dict_items->used; i++)
374
0
      {
375
0
        if (dict_items->objects[i].key != NULL)
376
0
          yr_free(dict_items->objects[i].key);
377
378
0
        if (dict_items->objects[i].obj != NULL)
379
0
          yr_object_destroy(dict_items->objects[i].obj);
380
0
      }
381
0
    }
382
383
0
    yr_free(dict_items);
384
0
    break;
385
386
8.00k
  case OBJECT_TYPE_FUNCTION:
387
8.00k
    yr_object_destroy(object_as_function(object)->return_obj);
388
8.00k
    break;
389
9.34M
  }
390
391
9.34M
  yr_free((void*) object->identifier);
392
9.34M
  yr_free(object);
393
9.34M
}
394
395
YR_OBJECT* yr_object_lookup_field(YR_OBJECT* object, const char* field_name)
396
24.5M
{
397
24.5M
  YR_STRUCTURE_MEMBER* member;
398
399
24.5M
  assert(object != NULL);
400
24.5M
  assert(object->type == OBJECT_TYPE_STRUCTURE);
401
402
24.5M
  member = object_as_structure(object)->members;
403
404
321M
  while (member != NULL)
405
313M
  {
406
313M
    if (strcmp(member->object->identifier, field_name) == 0)
407
16.6M
      return member->object;
408
409
297M
    member = member->next;
410
297M
  }
411
412
7.89M
  return NULL;
413
24.5M
}
414
415
static YR_OBJECT* _yr_object_lookup(
416
    YR_OBJECT* object,
417
    int flags,
418
    const char* pattern,
419
    va_list args)
420
8.73M
{
421
8.73M
  YR_OBJECT* obj = object;
422
423
8.73M
  const char* p = pattern;
424
8.73M
  const char* key = NULL;
425
426
8.73M
  char str[256];
427
428
8.73M
  int i;
429
8.73M
  int index = -1;
430
431
16.6M
  while (obj != NULL)
432
16.6M
  {
433
16.6M
    i = 0;
434
435
130M
    while (*p != '\0' && *p != '.' && *p != '[' && i < sizeof(str) - 1)
436
113M
    {
437
113M
      str[i++] = *p++;
438
113M
    }
439
440
16.6M
    str[i] = '\0';
441
442
16.6M
    if (obj->type != OBJECT_TYPE_STRUCTURE)
443
0
      return NULL;
444
445
16.6M
    obj = yr_object_lookup_field(obj, str);
446
447
16.6M
    if (obj == NULL)
448
0
      return NULL;
449
450
16.6M
    if (*p == '[')
451
7.95M
    {
452
7.95M
      p++;
453
454
7.95M
      if (*p == '%')
455
7.95M
      {
456
7.95M
        p++;
457
458
7.95M
        switch (*p++)
459
7.95M
        {
460
7.95M
        case 'i':
461
7.95M
          index = va_arg(args, int);
462
7.95M
          break;
463
0
        case 's':
464
0
          key = va_arg(args, const char*);
465
0
          break;
466
467
0
        default:
468
0
          return NULL;
469
7.95M
        }
470
7.95M
      }
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
7.95M
      assert(*p == ']');
492
7.95M
      p++;
493
7.95M
      assert(*p == '.' || *p == '\0');
494
495
7.95M
      switch (obj->type)
496
7.95M
      {
497
7.95M
      case OBJECT_TYPE_ARRAY:
498
7.95M
        assert(index != -1);
499
7.95M
        obj = yr_object_array_get_item(obj, flags, index);
500
7.95M
        break;
501
502
0
      case OBJECT_TYPE_DICTIONARY:
503
0
        assert(key != NULL);
504
0
        obj = yr_object_dict_get_item(obj, flags, key);
505
0
        break;
506
7.95M
      }
507
7.95M
    }
508
509
16.6M
    if (*p == '\0')
510
8.73M
      break;
511
512
7.95M
    p++;
513
7.95M
  }
514
515
8.73M
  return obj;
516
8.73M
}
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
8.21M
{
538
8.21M
  YR_OBJECT* copy;
539
8.21M
  YR_OBJECT* o;
540
541
8.21M
  YR_STRUCTURE_MEMBER* structure_member;
542
543
8.21M
  *object_copy = NULL;
544
545
8.21M
  FAIL_ON_ERROR(
546
8.21M
      yr_object_create(object->type, object->identifier, NULL, &copy));
547
548
8.21M
  copy->canary = object->canary;
549
550
8.21M
  switch (object->type)
551
8.21M
  {
552
6.27M
  case OBJECT_TYPE_INTEGER:
553
6.27M
    copy->value.i = object->value.i;
554
6.27M
    break;
555
556
0
  case OBJECT_TYPE_FLOAT:
557
0
    copy->value.d = object->value.d;
558
0
    break;
559
560
525k
  case OBJECT_TYPE_STRING:
561
562
525k
    if (object->value.ss != NULL)
563
0
      copy->value.ss = ss_dup(object->value.ss);
564
525k
    else
565
525k
      copy->value.ss = NULL;
566
567
525k
    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
1.40M
  case OBJECT_TYPE_STRUCTURE:
585
586
1.40M
    structure_member = object_as_structure(object)->members;
587
588
8.21M
    while (structure_member != NULL)
589
6.80M
    {
590
6.80M
      FAIL_ON_ERROR_WITH_CLEANUP(
591
6.80M
          yr_object_copy(structure_member->object, &o),
592
6.80M
          yr_object_destroy(copy));
593
594
6.80M
      FAIL_ON_ERROR_WITH_CLEANUP(yr_object_structure_set_member(copy, o),
595
                                 // cleanup
596
6.80M
                                 yr_free(o);
597
6.80M
                                 yr_object_destroy(copy));
598
599
6.80M
      structure_member = structure_member->next;
600
6.80M
    }
601
602
1.40M
    break;
603
604
1.40M
  case OBJECT_TYPE_ARRAY:
605
606
0
    FAIL_ON_ERROR_WITH_CLEANUP(
607
0
        yr_object_copy(object_as_array(object)->prototype_item, &o),
608
0
        yr_object_destroy(copy));
609
610
0
    object_as_array(copy)->prototype_item = o;
611
612
0
    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
8.21M
  }
627
628
8.21M
  *object_copy = copy;
629
630
8.21M
  return ERROR_SUCCESS;
631
8.21M
}
632
633
int yr_object_structure_set_member(YR_OBJECT* object, YR_OBJECT* member)
634
7.88M
{
635
7.88M
  YR_STRUCTURE_MEMBER* sm;
636
637
7.88M
  assert(object->type == OBJECT_TYPE_STRUCTURE);
638
639
  // Check if the object already have a member with the same identifier
640
641
7.88M
  if (yr_object_lookup_field(object, member->identifier) != NULL)
642
0
    return ERROR_DUPLICATED_STRUCTURE_MEMBER;
643
644
7.88M
  sm = (YR_STRUCTURE_MEMBER*) yr_malloc(sizeof(YR_STRUCTURE_MEMBER));
645
646
7.88M
  if (sm == NULL)
647
0
    return ERROR_INSUFFICIENT_MEMORY;
648
649
7.88M
  member->parent = object;
650
7.88M
  sm->object = member;
651
7.88M
  sm->next = object_as_structure(object)->members;
652
653
7.88M
  object_as_structure(object)->members = sm;
654
655
7.88M
  return ERROR_SUCCESS;
656
7.88M
}
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
7.95M
{
673
7.95M
  YR_OBJECT* result = NULL;
674
7.95M
  YR_OBJECT_ARRAY* array;
675
676
7.95M
  assert(object->type == OBJECT_TYPE_ARRAY);
677
678
7.95M
  if (index < 0)
679
0
    return NULL;
680
681
7.95M
  array = object_as_array(object);
682
683
7.95M
  if (array->items != NULL && array->items->capacity > index)
684
7.94M
    result = array->items->objects[index];
685
686
7.95M
  if (result == NULL && flags & OBJECT_CREATE)
687
1.40M
  {
688
1.40M
    yr_object_copy(array->prototype_item, &result);
689
690
1.40M
    if (result != NULL)
691
1.40M
      yr_object_array_set_item(object, result, index);
692
1.40M
  }
693
694
7.95M
  return result;
695
7.95M
}
696
697
int yr_object_array_set_item(YR_OBJECT* object, YR_OBJECT* item, int index)
698
1.40M
{
699
1.40M
  YR_OBJECT_ARRAY* array;
700
701
1.40M
  int capacity;
702
703
1.40M
  assert(index >= 0);
704
1.40M
  assert(object->type == OBJECT_TYPE_ARRAY);
705
706
1.40M
  array = object_as_array(object);
707
708
1.40M
  if (array->items == NULL)
709
6.60k
  {
710
6.60k
    capacity = 64;
711
712
6.60k
    while (capacity <= index) capacity *= 2;
713
714
6.60k
    array->items = (YR_ARRAY_ITEMS*) yr_malloc(
715
6.60k
        sizeof(YR_ARRAY_ITEMS) + capacity * sizeof(YR_OBJECT*));
716
717
6.60k
    if (array->items == NULL)
718
0
      return ERROR_INSUFFICIENT_MEMORY;
719
720
6.60k
    memset(array->items->objects, 0, capacity * sizeof(YR_OBJECT*));
721
722
6.60k
    array->items->capacity = capacity;
723
6.60k
    array->items->length = 0;
724
6.60k
  }
725
1.40M
  else if (index >= array->items->capacity)
726
1.65k
  {
727
1.65k
    capacity = array->items->capacity * 2;
728
729
1.65k
    while (capacity <= index) capacity *= 2;
730
731
1.65k
    array->items = (YR_ARRAY_ITEMS*) yr_realloc(
732
1.65k
        array->items, sizeof(YR_ARRAY_ITEMS) + capacity * sizeof(YR_OBJECT*));
733
734
1.65k
    if (array->items == NULL)
735
0
      return ERROR_INSUFFICIENT_MEMORY;
736
737
1.71M
    for (int i = array->items->capacity; i < capacity; i++)
738
1.70M
      array->items->objects[i] = NULL;
739
740
1.65k
    array->items->capacity = capacity;
741
1.65k
  }
742
743
1.40M
  item->parent = object;
744
1.40M
  array->items->objects[index] = item;
745
746
1.40M
  if (index >= array->items->length)
747
1.40M
    array->items->length = index + 1;
748
749
1.40M
  return ERROR_SUCCESS;
750
1.40M
}
751
752
YR_OBJECT* yr_object_dict_get_item(
753
    YR_OBJECT* object,
754
    int flags,
755
    const char* key)
756
0
{
757
0
  YR_OBJECT* result = NULL;
758
0
  YR_OBJECT_DICTIONARY* dict;
759
760
0
  assert(object->type == OBJECT_TYPE_DICTIONARY);
761
762
0
  dict = object_as_dictionary(object);
763
764
0
  if (dict->items != NULL)
765
0
  {
766
0
    for (int i = 0; i < dict->items->used; i++)
767
0
    {
768
0
      if (strcmp(dict->items->objects[i].key->c_string, key) == 0)
769
0
        result = dict->items->objects[i].obj;
770
0
    }
771
0
  }
772
773
0
  if (result == NULL && flags & OBJECT_CREATE)
774
0
  {
775
0
    yr_object_copy(dict->prototype_item, &result);
776
777
0
    if (result != NULL)
778
0
      yr_object_dict_set_item(object, result, key);
779
0
  }
780
781
0
  return result;
782
0
}
783
784
int yr_object_dict_set_item(YR_OBJECT* object, YR_OBJECT* item, const char* key)
785
0
{
786
0
  YR_OBJECT_DICTIONARY* dict;
787
788
0
  int count;
789
790
0
  assert(object->type == OBJECT_TYPE_DICTIONARY);
791
792
0
  dict = object_as_dictionary(object);
793
794
0
  if (dict->items == NULL)
795
0
  {
796
0
    count = 64;
797
798
0
    dict->items = (YR_DICTIONARY_ITEMS*) yr_malloc(
799
0
        sizeof(YR_DICTIONARY_ITEMS) + count * sizeof(dict->items->objects[0]));
800
801
0
    if (dict->items == NULL)
802
0
      return ERROR_INSUFFICIENT_MEMORY;
803
804
0
    memset(dict->items->objects, 0, count * sizeof(dict->items->objects[0]));
805
806
0
    dict->items->free = count;
807
0
    dict->items->used = 0;
808
0
  }
809
0
  else if (dict->items->free == 0)
810
0
  {
811
0
    count = dict->items->used * 2;
812
0
    dict->items = (YR_DICTIONARY_ITEMS*) yr_realloc(
813
0
        dict->items,
814
0
        sizeof(YR_DICTIONARY_ITEMS) + count * sizeof(dict->items->objects[0]));
815
816
0
    if (dict->items == NULL)
817
0
      return ERROR_INSUFFICIENT_MEMORY;
818
819
0
    for (int i = dict->items->used; i < count; i++)
820
0
    {
821
0
      dict->items->objects[i].key = NULL;
822
0
      dict->items->objects[i].obj = NULL;
823
0
    }
824
825
0
    dict->items->free = dict->items->used;
826
0
  }
827
828
0
  item->parent = object;
829
830
0
  dict->items->objects[dict->items->used].key = ss_new(key);
831
0
  dict->items->objects[dict->items->used].obj = item;
832
833
0
  dict->items->used++;
834
0
  dict->items->free--;
835
836
0
  return ERROR_SUCCESS;
837
0
}
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
8.62M
{
950
8.62M
  YR_OBJECT* integer_obj;
951
952
8.62M
  va_list args;
953
8.62M
  va_start(args, field);
954
955
8.62M
  if (field != NULL)
956
8.62M
    integer_obj = _yr_object_lookup(object, OBJECT_CREATE, field, args);
957
0
  else
958
0
    integer_obj = object;
959
960
8.62M
  va_end(args);
961
962
8.62M
  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
8.62M
  assert(integer_obj->type == OBJECT_TYPE_INTEGER);
971
972
8.62M
  integer_obj->value.i = value;
973
974
8.62M
  return ERROR_SUCCESS;
975
8.62M
}
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
115k
{
1013
115k
  YR_OBJECT* string_obj;
1014
1015
115k
  va_list args;
1016
115k
  va_start(args, field);
1017
1018
115k
  if (field != NULL)
1019
115k
    string_obj = _yr_object_lookup(object, OBJECT_CREATE, field, args);
1020
0
  else
1021
0
    string_obj = object;
1022
1023
115k
  va_end(args);
1024
1025
115k
  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
115k
  assert(string_obj->type == OBJECT_TYPE_STRING);
1034
1035
115k
  if (string_obj->value.ss != NULL)
1036
0
    yr_free(string_obj->value.ss);
1037
1038
115k
  if (value != NULL)
1039
115k
  {
1040
115k
    string_obj->value.ss = (SIZED_STRING*) yr_malloc(
1041
115k
        len + sizeof(SIZED_STRING));
1042
1043
115k
    if (string_obj->value.ss == NULL)
1044
0
      return ERROR_INSUFFICIENT_MEMORY;
1045
1046
115k
    string_obj->value.ss->length = (uint32_t) len;
1047
115k
    string_obj->value.ss->flags = 0;
1048
1049
115k
    memcpy(string_obj->value.ss->c_string, value, len);
1050
115k
    string_obj->value.ss->c_string[len] = '\0';
1051
115k
  }
1052
0
  else
1053
0
  {
1054
0
    string_obj->value.ss = NULL;
1055
0
  }
1056
1057
115k
  return ERROR_SUCCESS;
1058
115k
}
1059
1060
YR_OBJECT* yr_object_get_root(YR_OBJECT* object)
1061
0
{
1062
0
  YR_OBJECT* o = object;
1063
1064
0
  while (o->parent != NULL) o = o->parent;
1065
1066
0
  return o;
1067
0
}
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
}