Coverage Report

Created: 2026-02-26 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/yara/libyara/object.c
Line
Count
Source
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
101M
{
57
101M
  YR_OBJECT* obj;
58
101M
  size_t object_size = 0;
59
60
101M
  assert(parent != NULL || object != NULL);
61
101M
  assert(identifier != NULL);
62
63
101M
  switch (type)
64
101M
  {
65
15.2M
  case OBJECT_TYPE_STRUCTURE:
66
15.2M
    object_size = sizeof(YR_OBJECT_STRUCTURE);
67
15.2M
    break;
68
3.21M
  case OBJECT_TYPE_ARRAY:
69
3.21M
    object_size = sizeof(YR_OBJECT_ARRAY);
70
3.21M
    break;
71
8.59k
  case OBJECT_TYPE_DICTIONARY:
72
8.59k
    object_size = sizeof(YR_OBJECT_DICTIONARY);
73
8.59k
    break;
74
64.2M
  case OBJECT_TYPE_INTEGER:
75
64.2M
    object_size = sizeof(YR_OBJECT);
76
64.2M
    break;
77
89
  case OBJECT_TYPE_FLOAT:
78
89
    object_size = sizeof(YR_OBJECT);
79
89
    break;
80
18.5M
  case OBJECT_TYPE_STRING:
81
18.5M
    object_size = sizeof(YR_OBJECT);
82
18.5M
    break;
83
143k
  case OBJECT_TYPE_FUNCTION:
84
143k
    object_size = sizeof(YR_OBJECT_FUNCTION);
85
143k
    break;
86
0
  default:
87
0
    assert(false);
88
101M
  }
89
90
101M
  obj = (YR_OBJECT*) yr_malloc(object_size);
91
92
101M
  if (obj == NULL)
93
0
    return ERROR_INSUFFICIENT_MEMORY;
94
95
101M
  obj->type = type;
96
101M
  obj->identifier = yr_strdup(identifier);
97
101M
  obj->parent = parent;
98
101M
  obj->data = NULL;
99
100
101M
  switch (type)
101
101M
  {
102
64.2M
  case OBJECT_TYPE_INTEGER:
103
64.2M
    obj->value.i = YR_UNDEFINED;
104
64.2M
    break;
105
89
  case OBJECT_TYPE_FLOAT:
106
89
    obj->value.d = NAN;
107
89
    break;
108
18.5M
  case OBJECT_TYPE_STRING:
109
18.5M
    obj->value.ss = NULL;
110
18.5M
    break;
111
15.2M
  case OBJECT_TYPE_STRUCTURE:
112
15.2M
    object_as_structure(obj)->members = NULL;
113
15.2M
    break;
114
3.21M
  case OBJECT_TYPE_ARRAY:
115
3.21M
    object_as_array(obj)->items = NULL;
116
3.21M
    object_as_array(obj)->prototype_item = NULL;
117
3.21M
    break;
118
8.59k
  case OBJECT_TYPE_DICTIONARY:
119
8.59k
    object_as_dictionary(obj)->items = NULL;
120
8.59k
    object_as_dictionary(obj)->prototype_item = NULL;
121
8.59k
    break;
122
143k
  case OBJECT_TYPE_FUNCTION:
123
143k
    object_as_function(obj)->return_obj = NULL;
124
1.58M
    for (int i = 0; i < YR_MAX_OVERLOADED_FUNCTIONS; i++)
125
1.43M
    {
126
1.43M
      object_as_function(obj)->prototypes[i].arguments_fmt = NULL;
127
1.43M
      object_as_function(obj)->prototypes[i].code = NULL;
128
1.43M
    }
129
143k
    break;
130
101M
  }
131
132
101M
  if (obj->identifier == NULL)
133
0
  {
134
0
    yr_free(obj);
135
0
    return ERROR_INSUFFICIENT_MEMORY;
136
0
  }
137
138
101M
  if (parent != NULL)
139
5.38M
  {
140
5.38M
    assert(
141
5.38M
        parent->type == OBJECT_TYPE_STRUCTURE ||
142
5.38M
        parent->type == OBJECT_TYPE_ARRAY ||
143
5.38M
        parent->type == OBJECT_TYPE_DICTIONARY ||
144
5.38M
        parent->type == OBJECT_TYPE_FUNCTION);
145
146
    // Objects with a parent take the canary from it.
147
5.38M
    obj->canary = parent->canary;
148
149
5.38M
    switch (parent->type)
150
5.38M
    {
151
4.98M
    case OBJECT_TYPE_STRUCTURE:
152
4.98M
      FAIL_ON_ERROR_WITH_CLEANUP(yr_object_structure_set_member(parent, obj), {
153
4.98M
        yr_free((void*) obj->identifier);
154
4.98M
        yr_free(obj);
155
4.98M
      });
156
4.98M
      break;
157
158
239k
    case OBJECT_TYPE_ARRAY:
159
239k
      object_as_array(parent)->prototype_item = obj;
160
239k
      break;
161
162
8.59k
    case OBJECT_TYPE_DICTIONARY:
163
8.59k
      object_as_dictionary(parent)->prototype_item = obj;
164
8.59k
      break;
165
166
143k
    case OBJECT_TYPE_FUNCTION:
167
143k
      object_as_function(parent)->return_obj = obj;
168
143k
      break;
169
5.38M
    }
170
5.38M
  }
171
172
101M
  if (object != NULL)
173
96.7M
    *object = obj;
174
175
101M
  return ERROR_SUCCESS;
176
101M
}
177
178
void yr_object_set_canary(YR_OBJECT* object, int canary)
179
26.9k
{
180
26.9k
  object->canary = canary;
181
26.9k
}
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
289k
{
191
289k
  YR_OBJECT* return_obj;
192
289k
  YR_OBJECT* o = NULL;
193
289k
  YR_OBJECT_FUNCTION* f = NULL;
194
195
289k
  int8_t return_type;
196
197
  // The parent of a function must be a structure.
198
289k
  assert(parent != NULL && parent->type == OBJECT_TYPE_STRUCTURE);
199
200
289k
  switch (*return_fmt)
201
289k
  {
202
281k
  case 'i':
203
281k
    return_type = OBJECT_TYPE_INTEGER;
204
281k
    break;
205
7.13k
  case 's':
206
7.13k
    return_type = OBJECT_TYPE_STRING;
207
7.13k
    break;
208
144
  case 'f':
209
144
    return_type = OBJECT_TYPE_FLOAT;
210
144
    break;
211
0
  default:
212
0
    return ERROR_INVALID_FORMAT;
213
289k
  }
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
289k
  f = object_as_function(yr_object_lookup_field(parent, identifier));
218
219
  // Overloaded functions must have the same return type.
220
289k
  if (f != NULL && return_type != f->return_obj->type)
221
0
    return ERROR_WRONG_RETURN_TYPE;
222
223
289k
  if (f == NULL)  // Function doesn't exist yet
224
143k
  {
225
143k
    FAIL_ON_ERROR(
226
143k
        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
143k
    FAIL_ON_ERROR(yr_object_create(return_type, "result", o, &return_obj));
232
233
143k
    f = object_as_function(o);
234
143k
  }
235
236
631k
  for (int i = 0; i < YR_MAX_OVERLOADED_FUNCTIONS; i++)
237
631k
  {
238
631k
    if (f->prototypes[i].arguments_fmt == NULL)
239
289k
    {
240
289k
      f->prototypes[i].arguments_fmt = arguments_fmt;
241
289k
      f->prototypes[i].code = code;
242
243
289k
      break;
244
289k
    }
245
631k
  }
246
247
289k
  if (function != NULL)
248
289k
    *function = (YR_OBJECT*) f;
249
250
289k
  return ERROR_SUCCESS;
251
289k
}
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
101M
{
322
101M
  YR_STRUCTURE_MEMBER* member;
323
101M
  YR_STRUCTURE_MEMBER* next_member;
324
101M
  YR_ARRAY_ITEMS* array_items;
325
101M
  YR_DICTIONARY_ITEMS* dict_items;
326
327
101M
  if (object == NULL)
328
0
    return;
329
330
101M
  switch (object->type)
331
101M
  {
332
15.2M
  case OBJECT_TYPE_STRUCTURE:
333
15.2M
    member = object_as_structure(object)->members;
334
335
100M
    while (member != NULL)
336
84.9M
    {
337
84.9M
      next_member = member->next;
338
84.9M
      yr_object_destroy(member->object);
339
84.9M
      yr_free(member);
340
84.9M
      member = next_member;
341
84.9M
    }
342
15.2M
    break;
343
344
18.5M
  case OBJECT_TYPE_STRING:
345
18.5M
    if (object->value.ss != NULL)
346
9.58M
      yr_free(object->value.ss);
347
18.5M
    break;
348
349
3.21M
  case OBJECT_TYPE_ARRAY:
350
3.21M
    if (object_as_array(object)->prototype_item != NULL)
351
3.21M
      yr_object_destroy(object_as_array(object)->prototype_item);
352
353
3.21M
    array_items = object_as_array(object)->items;
354
355
3.21M
    if (array_items != NULL)
356
154k
    {
357
13.4M
      for (int i = 0; i < array_items->length; i++)
358
13.2M
        if (array_items->objects[i] != NULL)
359
12.9M
          yr_object_destroy(array_items->objects[i]);
360
154k
    }
361
362
3.21M
    yr_free(array_items);
363
3.21M
    break;
364
365
8.59k
  case OBJECT_TYPE_DICTIONARY:
366
8.59k
    if (object_as_dictionary(object)->prototype_item != NULL)
367
8.59k
      yr_object_destroy(object_as_dictionary(object)->prototype_item);
368
369
8.59k
    dict_items = object_as_dictionary(object)->items;
370
371
8.59k
    if (dict_items != NULL)
372
214
    {
373
2.13k
      for (int i = 0; i < dict_items->used; i++)
374
1.92k
      {
375
1.92k
        if (dict_items->objects[i].key != NULL)
376
1.92k
          yr_free(dict_items->objects[i].key);
377
378
1.92k
        if (dict_items->objects[i].obj != NULL)
379
1.92k
          yr_object_destroy(dict_items->objects[i].obj);
380
1.92k
      }
381
214
    }
382
383
8.59k
    yr_free(dict_items);
384
8.59k
    break;
385
386
143k
  case OBJECT_TYPE_FUNCTION:
387
143k
    yr_object_destroy(object_as_function(object)->return_obj);
388
143k
    break;
389
101M
  }
390
391
101M
  yr_free((void*) object->identifier);
392
101M
  yr_free(object);
393
101M
}
394
395
YR_OBJECT* yr_object_lookup_field(YR_OBJECT* object, const char* field_name)
396
231M
{
397
231M
  YR_STRUCTURE_MEMBER* member;
398
399
231M
  assert(object != NULL);
400
231M
  assert(object->type == OBJECT_TYPE_STRUCTURE);
401
402
231M
  member = object_as_structure(object)->members;
403
404
2.08G
  while (member != NULL)
405
2.00G
  {
406
2.00G
    if (strcmp(member->object->identifier, field_name) == 0)
407
146M
      return member->object;
408
409
1.85G
    member = member->next;
410
1.85G
  }
411
412
85.4M
  return NULL;
413
231M
}
414
415
static YR_OBJECT* _yr_object_lookup(
416
    YR_OBJECT* object,
417
    int flags,
418
    const char* pattern,
419
    va_list args)
420
66.3M
{
421
66.3M
  YR_OBJECT* obj = object;
422
423
66.3M
  const char* p = pattern;
424
66.3M
  const char* key = NULL;
425
426
66.3M
  char str[256];
427
428
66.3M
  int i;
429
66.3M
  int index = -1;
430
431
146M
  while (obj != NULL)
432
146M
  {
433
146M
    i = 0;
434
435
1.43G
    while (*p != '\0' && *p != '.' && *p != '[' && i < sizeof(str) - 1)
436
1.29G
    {
437
1.29G
      str[i++] = *p++;
438
1.29G
    }
439
440
146M
    str[i] = '\0';
441
442
146M
    if (obj->type != OBJECT_TYPE_STRUCTURE)
443
0
      return NULL;
444
445
146M
    obj = yr_object_lookup_field(obj, str);
446
447
146M
    if (obj == NULL)
448
398k
      return NULL;
449
450
145M
    if (*p == '[')
451
79.5M
    {
452
79.5M
      p++;
453
454
79.5M
      if (*p == '%')
455
79.5M
      {
456
79.5M
        p++;
457
458
79.5M
        switch (*p++)
459
79.5M
        {
460
79.4M
        case 'i':
461
79.4M
          index = va_arg(args, int);
462
79.4M
          break;
463
4.36k
        case 's':
464
4.36k
          key = va_arg(args, const char*);
465
4.36k
          break;
466
467
0
        default:
468
0
          return NULL;
469
79.5M
        }
470
79.5M
      }
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
79.5M
      assert(*p == ']');
492
79.5M
      p++;
493
79.5M
      assert(*p == '.' || *p == '\0');
494
495
79.5M
      switch (obj->type)
496
79.5M
      {
497
79.4M
      case OBJECT_TYPE_ARRAY:
498
79.4M
        assert(index != -1);
499
79.4M
        obj = yr_object_array_get_item(obj, flags, index);
500
79.4M
        break;
501
502
4.36k
      case OBJECT_TYPE_DICTIONARY:
503
4.36k
        assert(key != NULL);
504
4.36k
        obj = yr_object_dict_get_item(obj, flags, key);
505
4.36k
        break;
506
79.5M
      }
507
79.5M
    }
508
509
145M
    if (*p == '\0')
510
65.9M
      break;
511
512
79.8M
    p++;
513
79.8M
  }
514
515
65.9M
  return obj;
516
66.3M
}
517
518
YR_OBJECT* yr_object_lookup(
519
    YR_OBJECT* object,
520
    int flags,
521
    const char* pattern,
522
    ...)
523
189k
{
524
189k
  YR_OBJECT* result;
525
526
189k
  va_list args;
527
189k
  va_start(args, pattern);
528
529
189k
  result = _yr_object_lookup(object, flags, pattern, args);
530
531
189k
  va_end(args);
532
533
189k
  return result;
534
189k
}
535
536
int yr_object_copy(YR_OBJECT* object, YR_OBJECT** object_copy)
537
95.8M
{
538
95.8M
  YR_OBJECT* copy;
539
95.8M
  YR_OBJECT* o;
540
541
95.8M
  YR_STRUCTURE_MEMBER* structure_member;
542
543
95.8M
  *object_copy = NULL;
544
545
95.8M
  FAIL_ON_ERROR(
546
95.8M
      yr_object_create(object->type, object->identifier, NULL, &copy));
547
548
95.8M
  copy->canary = object->canary;
549
550
95.8M
  switch (object->type)
551
95.8M
  {
552
59.8M
  case OBJECT_TYPE_INTEGER:
553
59.8M
    copy->value.i = object->value.i;
554
59.8M
    break;
555
556
0
  case OBJECT_TYPE_FLOAT:
557
0
    copy->value.d = object->value.d;
558
0
    break;
559
560
18.1M
  case OBJECT_TYPE_STRING:
561
562
18.1M
    if (object->value.ss != NULL)
563
0
      copy->value.ss = ss_dup(object->value.ss);
564
18.1M
    else
565
18.1M
      copy->value.ss = NULL;
566
567
18.1M
    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
14.9M
  case OBJECT_TYPE_STRUCTURE:
585
586
14.9M
    structure_member = object_as_structure(object)->members;
587
588
94.8M
    while (structure_member != NULL)
589
79.9M
    {
590
79.9M
      FAIL_ON_ERROR_WITH_CLEANUP(
591
79.9M
          yr_object_copy(structure_member->object, &o),
592
79.9M
          yr_object_destroy(copy));
593
594
79.9M
      FAIL_ON_ERROR_WITH_CLEANUP(yr_object_structure_set_member(copy, o),
595
                                 // cleanup
596
79.9M
                                 yr_free(o);
597
79.9M
                                 yr_object_destroy(copy));
598
599
79.9M
      structure_member = structure_member->next;
600
79.9M
    }
601
602
14.9M
    break;
603
604
14.9M
  case OBJECT_TYPE_ARRAY:
605
606
2.97M
    FAIL_ON_ERROR_WITH_CLEANUP(
607
2.97M
        yr_object_copy(object_as_array(object)->prototype_item, &o),
608
2.97M
        yr_object_destroy(copy));
609
610
2.97M
    object_as_array(copy)->prototype_item = o;
611
612
2.97M
    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
95.8M
  }
627
628
95.8M
  *object_copy = copy;
629
630
95.8M
  return ERROR_SUCCESS;
631
95.8M
}
632
633
int yr_object_structure_set_member(YR_OBJECT* object, YR_OBJECT* member)
634
84.9M
{
635
84.9M
  YR_STRUCTURE_MEMBER* sm;
636
637
84.9M
  assert(object->type == OBJECT_TYPE_STRUCTURE);
638
639
  // Check if the object already have a member with the same identifier
640
641
84.9M
  if (yr_object_lookup_field(object, member->identifier) != NULL)
642
0
    return ERROR_DUPLICATED_STRUCTURE_MEMBER;
643
644
84.9M
  sm = (YR_STRUCTURE_MEMBER*) yr_malloc(sizeof(YR_STRUCTURE_MEMBER));
645
646
84.9M
  if (sm == NULL)
647
0
    return ERROR_INSUFFICIENT_MEMORY;
648
649
84.9M
  member->parent = object;
650
84.9M
  sm->object = member;
651
84.9M
  sm->next = object_as_structure(object)->members;
652
653
84.9M
  object_as_structure(object)->members = sm;
654
655
84.9M
  return ERROR_SUCCESS;
656
84.9M
}
657
658
YR_API 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_API YR_OBJECT* yr_object_array_get_item(YR_OBJECT* object, int flags,
672
                                           int index)
673
79.5M
{
674
79.5M
  YR_OBJECT* result = NULL;
675
79.5M
  YR_OBJECT_ARRAY* array;
676
677
79.5M
  assert(object->type == OBJECT_TYPE_ARRAY);
678
679
79.5M
  if (index < 0)
680
0
    return NULL;
681
682
79.5M
  array = object_as_array(object);
683
684
79.5M
  if (array->items != NULL && array->items->capacity > index)
685
79.3M
    result = array->items->objects[index];
686
687
79.5M
  if (result == NULL && flags & OBJECT_CREATE)
688
12.9M
  {
689
12.9M
    yr_object_copy(array->prototype_item, &result);
690
691
12.9M
    if (result != NULL)
692
12.9M
      yr_object_array_set_item(object, result, index);
693
12.9M
  }
694
695
79.5M
  return result;
696
79.5M
}
697
698
int yr_object_array_set_item(YR_OBJECT* object, YR_OBJECT* item, int index)
699
12.9M
{
700
12.9M
  YR_OBJECT_ARRAY* array;
701
702
12.9M
  int capacity;
703
704
12.9M
  assert(index >= 0);
705
12.9M
  assert(object->type == OBJECT_TYPE_ARRAY);
706
707
12.9M
  array = object_as_array(object);
708
709
12.9M
  if (array->items == NULL)
710
154k
  {
711
154k
    capacity = 64;
712
713
154k
    while (capacity <= index) capacity *= 2;
714
715
154k
    array->items = (YR_ARRAY_ITEMS*) yr_malloc(
716
154k
        sizeof(YR_ARRAY_ITEMS) + capacity * sizeof(YR_OBJECT*));
717
718
154k
    if (array->items == NULL)
719
0
      return ERROR_INSUFFICIENT_MEMORY;
720
721
154k
    memset(array->items->objects, 0, capacity * sizeof(YR_OBJECT*));
722
723
154k
    array->items->capacity = capacity;
724
154k
    array->items->length = 0;
725
154k
  }
726
12.7M
  else if (index >= array->items->capacity)
727
28.0k
  {
728
28.0k
    capacity = array->items->capacity * 2;
729
730
28.1k
    while (capacity <= index) capacity *= 2;
731
732
28.0k
    array->items = (YR_ARRAY_ITEMS*) yr_realloc(
733
28.0k
        array->items, sizeof(YR_ARRAY_ITEMS) + capacity * sizeof(YR_OBJECT*));
734
735
28.0k
    if (array->items == NULL)
736
0
      return ERROR_INSUFFICIENT_MEMORY;
737
738
16.7M
    for (int i = array->items->capacity; i < capacity; i++)
739
16.7M
      array->items->objects[i] = NULL;
740
741
28.0k
    array->items->capacity = capacity;
742
28.0k
  }
743
744
12.9M
  item->parent = object;
745
12.9M
  array->items->objects[index] = item;
746
747
12.9M
  if (index >= array->items->length)
748
12.9M
    array->items->length = index + 1;
749
750
12.9M
  return ERROR_SUCCESS;
751
12.9M
}
752
753
YR_OBJECT* yr_object_dict_get_item(
754
    YR_OBJECT* object,
755
    int flags,
756
    const char* key)
757
4.36k
{
758
4.36k
  YR_OBJECT* result = NULL;
759
4.36k
  YR_OBJECT_DICTIONARY* dict;
760
761
4.36k
  assert(object->type == OBJECT_TYPE_DICTIONARY);
762
763
4.36k
  dict = object_as_dictionary(object);
764
765
4.36k
  if (dict->items != NULL)
766
4.14k
  {
767
122k
    for (int i = 0; i < dict->items->used; i++)
768
118k
    {
769
118k
      if (strcmp(dict->items->objects[i].key->c_string, key) == 0)
770
2.43k
        result = dict->items->objects[i].obj;
771
118k
    }
772
4.14k
  }
773
774
4.36k
  if (result == NULL && flags & OBJECT_CREATE)
775
1.92k
  {
776
1.92k
    yr_object_copy(dict->prototype_item, &result);
777
778
1.92k
    if (result != NULL)
779
1.92k
      yr_object_dict_set_item(object, result, key);
780
1.92k
  }
781
782
4.36k
  return result;
783
4.36k
}
784
785
int yr_object_dict_set_item(YR_OBJECT* object, YR_OBJECT* item, const char* key)
786
1.92k
{
787
1.92k
  YR_OBJECT_DICTIONARY* dict;
788
789
1.92k
  int count;
790
791
1.92k
  assert(object->type == OBJECT_TYPE_DICTIONARY);
792
793
1.92k
  dict = object_as_dictionary(object);
794
795
1.92k
  if (dict->items == NULL)
796
214
  {
797
214
    count = 64;
798
799
214
    dict->items = (YR_DICTIONARY_ITEMS*) yr_malloc(
800
214
        sizeof(YR_DICTIONARY_ITEMS) + count * sizeof(dict->items->objects[0]));
801
802
214
    if (dict->items == NULL)
803
0
      return ERROR_INSUFFICIENT_MEMORY;
804
805
214
    memset(dict->items->objects, 0, count * sizeof(dict->items->objects[0]));
806
807
214
    dict->items->free = count;
808
214
    dict->items->used = 0;
809
214
  }
810
1.71k
  else if (dict->items->free == 0)
811
8
  {
812
8
    count = dict->items->used * 2;
813
8
    dict->items = (YR_DICTIONARY_ITEMS*) yr_realloc(
814
8
        dict->items,
815
8
        sizeof(YR_DICTIONARY_ITEMS) + count * sizeof(dict->items->objects[0]));
816
817
8
    if (dict->items == NULL)
818
0
      return ERROR_INSUFFICIENT_MEMORY;
819
820
840
    for (int i = dict->items->used; i < count; i++)
821
832
    {
822
832
      dict->items->objects[i].key = NULL;
823
832
      dict->items->objects[i].obj = NULL;
824
832
    }
825
826
8
    dict->items->free = dict->items->used;
827
8
  }
828
829
1.92k
  item->parent = object;
830
831
1.92k
  dict->items->objects[dict->items->used].key = ss_new(key);
832
1.92k
  dict->items->objects[dict->items->used].obj = item;
833
834
1.92k
  dict->items->used++;
835
1.92k
  dict->items->free--;
836
837
1.92k
  return ERROR_SUCCESS;
838
1.92k
}
839
840
bool yr_object_has_undefined_value(YR_OBJECT* object, const char* field, ...)
841
0
{
842
0
  YR_OBJECT* field_obj;
843
844
0
  va_list args;
845
0
  va_start(args, field);
846
847
0
  if (field != NULL)
848
0
    field_obj = _yr_object_lookup(object, 0, field, args);
849
0
  else
850
0
    field_obj = object;
851
852
0
  va_end(args);
853
854
0
  if (field_obj == NULL)
855
0
    return true;
856
857
0
  switch (field_obj->type)
858
0
  {
859
0
  case OBJECT_TYPE_FLOAT:
860
0
    return yr_isnan(field_obj->value.d);
861
0
  case OBJECT_TYPE_STRING:
862
0
    return field_obj->value.ss == NULL;
863
0
  case OBJECT_TYPE_INTEGER:
864
0
    return field_obj->value.i == YR_UNDEFINED;
865
0
  }
866
867
0
  return false;
868
0
}
869
870
int64_t yr_object_get_integer(YR_OBJECT* object, const char* field, ...)
871
3.70M
{
872
3.70M
  YR_OBJECT* integer_obj;
873
874
3.70M
  va_list args;
875
3.70M
  va_start(args, field);
876
877
3.70M
  if (field != NULL)
878
3.70M
    integer_obj = _yr_object_lookup(object, 0, field, args);
879
0
  else
880
0
    integer_obj = object;
881
882
3.70M
  va_end(args);
883
884
3.70M
  if (integer_obj == NULL)
885
2.02k
    return YR_UNDEFINED;
886
887
3.69M
  assertf(
888
3.69M
      integer_obj->type == OBJECT_TYPE_INTEGER,
889
3.69M
      "type of \"%s\" is not integer\n",
890
3.69M
      field);
891
892
3.69M
  return integer_obj->value.i;
893
3.69M
}
894
895
double yr_object_get_float(YR_OBJECT* object, const char* field, ...)
896
0
{
897
0
  YR_OBJECT* double_obj;
898
899
0
  va_list args;
900
0
  va_start(args, field);
901
902
0
  if (field != NULL)
903
0
    double_obj = _yr_object_lookup(object, 0, field, args);
904
0
  else
905
0
    double_obj = object;
906
907
0
  va_end(args);
908
909
0
  if (double_obj == NULL)
910
0
    return NAN;
911
912
0
  assertf(
913
0
      double_obj->type == OBJECT_TYPE_FLOAT,
914
0
      "type of \"%s\" is not double\n",
915
0
      field);
916
917
0
  return double_obj->value.d;
918
0
}
919
920
SIZED_STRING* yr_object_get_string(YR_OBJECT* object, const char* field, ...)
921
0
{
922
0
  YR_OBJECT* string_obj;
923
924
0
  va_list args;
925
0
  va_start(args, field);
926
927
0
  if (field != NULL)
928
0
    string_obj = _yr_object_lookup(object, 0, field, args);
929
0
  else
930
0
    string_obj = object;
931
932
0
  va_end(args);
933
934
0
  if (string_obj == NULL)
935
0
    return NULL;
936
937
0
  assertf(
938
0
      string_obj->type == OBJECT_TYPE_STRING,
939
0
      "type of \"%s\" is not string\n",
940
0
      field);
941
942
0
  return string_obj->value.ss;
943
0
}
944
945
int yr_object_set_integer(
946
    int64_t value,
947
    YR_OBJECT* object,
948
    const char* field,
949
    ...)
950
52.8M
{
951
52.8M
  YR_OBJECT* integer_obj;
952
953
52.8M
  va_list args;
954
52.8M
  va_start(args, field);
955
956
52.8M
  if (field != NULL)
957
52.8M
    integer_obj = _yr_object_lookup(object, OBJECT_CREATE, field, args);
958
2.06k
  else
959
2.06k
    integer_obj = object;
960
961
52.8M
  va_end(args);
962
963
52.8M
  if (integer_obj == NULL)
964
398k
  {
965
398k
    if (field != NULL)
966
398k
      return ERROR_INSUFFICIENT_MEMORY;
967
0
    else
968
0
      return ERROR_INVALID_ARGUMENT;
969
398k
  }
970
971
52.8M
  assert(integer_obj->type == OBJECT_TYPE_INTEGER);
972
973
52.4M
  integer_obj->value.i = value;
974
975
52.4M
  return ERROR_SUCCESS;
976
52.4M
}
977
978
int yr_object_set_float(double value, YR_OBJECT* object, const char* field, ...)
979
0
{
980
0
  YR_OBJECT* double_obj;
981
982
0
  va_list args;
983
0
  va_start(args, field);
984
985
0
  if (field != NULL)
986
0
    double_obj = _yr_object_lookup(object, OBJECT_CREATE, field, args);
987
0
  else
988
0
    double_obj = object;
989
990
0
  va_end(args);
991
992
0
  if (double_obj == NULL)
993
0
  {
994
0
    if (field != NULL)
995
0
      return ERROR_INSUFFICIENT_MEMORY;
996
0
    else
997
0
      return ERROR_INVALID_ARGUMENT;
998
0
  }
999
1000
0
  assert(double_obj->type == OBJECT_TYPE_FLOAT);
1001
1002
0
  double_obj->value.d = value;
1003
1004
0
  return ERROR_SUCCESS;
1005
0
}
1006
1007
int yr_object_set_string(
1008
    const char* value,
1009
    size_t len,
1010
    YR_OBJECT* object,
1011
    const char* field,
1012
    ...)
1013
9.69M
{
1014
9.69M
  YR_OBJECT* string_obj;
1015
1016
9.69M
  va_list args;
1017
9.69M
  va_start(args, field);
1018
1019
9.69M
  if (field != NULL)
1020
9.69M
    string_obj = _yr_object_lookup(object, OBJECT_CREATE, field, args);
1021
0
  else
1022
0
    string_obj = object;
1023
1024
9.69M
  va_end(args);
1025
1026
9.69M
  if (string_obj == NULL)
1027
0
  {
1028
0
    if (field != NULL)
1029
0
      return ERROR_INSUFFICIENT_MEMORY;
1030
0
    else
1031
0
      return ERROR_INVALID_ARGUMENT;
1032
0
  }
1033
1034
9.69M
  assert(string_obj->type == OBJECT_TYPE_STRING);
1035
1036
9.69M
  if (string_obj->value.ss != NULL)
1037
3.09k
    yr_free(string_obj->value.ss);
1038
1039
9.69M
  if (value != NULL)
1040
9.58M
  {
1041
9.58M
    string_obj->value.ss = (SIZED_STRING*) yr_malloc(
1042
9.58M
        len + sizeof(SIZED_STRING));
1043
1044
9.58M
    if (string_obj->value.ss == NULL)
1045
0
      return ERROR_INSUFFICIENT_MEMORY;
1046
1047
9.58M
    string_obj->value.ss->length = (uint32_t) len;
1048
9.58M
    string_obj->value.ss->flags = 0;
1049
1050
9.58M
    memcpy(string_obj->value.ss->c_string, value, len);
1051
9.58M
    string_obj->value.ss->c_string[len] = '\0';
1052
9.58M
  }
1053
110k
  else
1054
110k
  {
1055
110k
    string_obj->value.ss = NULL;
1056
110k
  }
1057
1058
9.69M
  return ERROR_SUCCESS;
1059
9.69M
}
1060
1061
YR_OBJECT* yr_object_get_root(YR_OBJECT* object)
1062
2.06k
{
1063
2.06k
  YR_OBJECT* o = object;
1064
1065
4.13k
  while (o->parent != NULL) o = o->parent;
1066
1067
2.06k
  return o;
1068
2.06k
}
1069
1070
YR_API void yr_object_print_data(
1071
    YR_OBJECT* object,
1072
    int indent,
1073
    int print_identifier)
1074
0
{
1075
0
  YR_DICTIONARY_ITEMS* dict_items;
1076
0
  YR_STRUCTURE_MEMBER* member;
1077
1078
0
  char indent_spaces[32];
1079
1080
0
  indent = yr_min(indent, sizeof(indent_spaces) - 1);
1081
1082
0
  memset(indent_spaces, '\t', indent);
1083
0
  indent_spaces[indent] = '\0';
1084
1085
0
  if (print_identifier && object->type != OBJECT_TYPE_FUNCTION)
1086
0
    printf("%s%s", indent_spaces, object->identifier);
1087
1088
0
  switch (object->type)
1089
0
  {
1090
0
  case OBJECT_TYPE_FLOAT:
1091
0
    if (object->value.i != YR_UNDEFINED)
1092
0
      printf(" = %f", object->value.d);
1093
0
    else
1094
0
      printf(" = YR_UNDEFINED");
1095
1096
0
    break;
1097
1098
0
  case OBJECT_TYPE_INTEGER:
1099
1100
0
    if (object->value.i != YR_UNDEFINED)
1101
0
      printf(" = %" PRId64, object->value.i);
1102
0
    else
1103
0
      printf(" = YR_UNDEFINED");
1104
1105
0
    break;
1106
1107
0
  case OBJECT_TYPE_STRING:
1108
1109
0
    if (object->value.ss != NULL)
1110
0
    {
1111
0
      printf(" = \"");
1112
1113
0
      for (size_t l = 0; l < object->value.ss->length; l++)
1114
0
      {
1115
0
        char c = object->value.ss->c_string[l];
1116
1117
0
        if (isprint((unsigned char) c))
1118
0
          printf("%c", c);
1119
0
        else
1120
0
          printf("\\x%02x", (unsigned char) c);
1121
0
      }
1122
1123
0
      printf("\"");
1124
0
    }
1125
0
    else
1126
0
    {
1127
0
      printf(" = YR_UNDEFINED");
1128
0
    }
1129
1130
0
    break;
1131
1132
0
  case OBJECT_TYPE_STRUCTURE:
1133
1134
0
    member = object_as_structure(object)->members;
1135
1136
0
    while (member != NULL)
1137
0
    {
1138
0
      if (member->object->type != OBJECT_TYPE_FUNCTION)
1139
0
      {
1140
0
        printf("\n");
1141
0
        yr_object_print_data(member->object, indent + 1, 1);
1142
0
      }
1143
0
      member = member->next;
1144
0
    }
1145
1146
0
    break;
1147
1148
0
  case OBJECT_TYPE_ARRAY:
1149
0
    for (int i = 0; i < yr_object_array_length(object); i++)
1150
0
    {
1151
0
      YR_OBJECT* o = yr_object_array_get_item(object, 0, i);
1152
1153
0
      if (o != NULL)
1154
0
      {
1155
0
        printf("\n%s\t[%d]", indent_spaces, i);
1156
0
        yr_object_print_data(o, indent + 1, 0);
1157
0
      }
1158
0
    }
1159
0
    break;
1160
1161
0
  case OBJECT_TYPE_DICTIONARY:
1162
1163
0
    dict_items = object_as_dictionary(object)->items;
1164
1165
0
    if (dict_items != NULL)
1166
0
    {
1167
0
      for (int i = 0; i < dict_items->used; i++)
1168
0
      {
1169
0
        printf("\n%s\t%s", indent_spaces, dict_items->objects[i].key->c_string);
1170
1171
0
        yr_object_print_data(dict_items->objects[i].obj, indent + 1, 0);
1172
0
      }
1173
0
    }
1174
1175
0
    break;
1176
0
  }
1177
0
}