Coverage Report

Created: 2023-06-07 07:18

/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.77M
{
57
9.77M
  YR_OBJECT* obj;
58
9.77M
  size_t object_size = 0;
59
60
9.77M
  assert(parent != NULL || object != NULL);
61
9.77M
  assert(identifier != NULL);
62
63
9.77M
  switch (type)
64
9.77M
  {
65
1.50M
  case OBJECT_TYPE_STRUCTURE:
66
1.50M
    object_size = sizeof(YR_OBJECT_STRUCTURE);
67
1.50M
    break;
68
37.4k
  case OBJECT_TYPE_ARRAY:
69
37.4k
    object_size = sizeof(YR_OBJECT_ARRAY);
70
37.4k
    break;
71
0
  case OBJECT_TYPE_DICTIONARY:
72
0
    object_size = sizeof(YR_OBJECT_DICTIONARY);
73
0
    break;
74
7.63M
  case OBJECT_TYPE_INTEGER:
75
7.63M
    object_size = sizeof(YR_OBJECT);
76
7.63M
    break;
77
0
  case OBJECT_TYPE_FLOAT:
78
0
    object_size = sizeof(YR_OBJECT);
79
0
    break;
80
599k
  case OBJECT_TYPE_STRING:
81
599k
    object_size = sizeof(YR_OBJECT);
82
599k
    break;
83
7.49k
  case OBJECT_TYPE_FUNCTION:
84
7.49k
    object_size = sizeof(YR_OBJECT_FUNCTION);
85
7.49k
    break;
86
0
  default:
87
0
    assert(false);
88
9.77M
  }
89
90
9.77M
  obj = (YR_OBJECT*) yr_malloc(object_size);
91
92
9.77M
  if (obj == NULL)
93
0
    return ERROR_INSUFFICIENT_MEMORY;
94
95
9.77M
  obj->type = type;
96
9.77M
  obj->identifier = yr_strdup(identifier);
97
9.77M
  obj->parent = parent;
98
9.77M
  obj->data = NULL;
99
100
9.77M
  switch (type)
101
9.77M
  {
102
7.63M
  case OBJECT_TYPE_INTEGER:
103
7.63M
    obj->value.i = YR_UNDEFINED;
104
7.63M
    break;
105
0
  case OBJECT_TYPE_FLOAT:
106
0
    obj->value.d = NAN;
107
0
    break;
108
599k
  case OBJECT_TYPE_STRING:
109
599k
    obj->value.ss = NULL;
110
599k
    break;
111
1.50M
  case OBJECT_TYPE_STRUCTURE:
112
1.50M
    object_as_structure(obj)->members = NULL;
113
1.50M
    break;
114
37.4k
  case OBJECT_TYPE_ARRAY:
115
37.4k
    object_as_array(obj)->items = NULL;
116
37.4k
    object_as_array(obj)->prototype_item = NULL;
117
37.4k
    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
7.49k
  case OBJECT_TYPE_FUNCTION:
123
7.49k
    object_as_function(obj)->return_obj = NULL;
124
82.4k
    for (int i = 0; i < YR_MAX_OVERLOADED_FUNCTIONS; i++)
125
74.9k
    {
126
74.9k
      object_as_function(obj)->prototypes[i].arguments_fmt = NULL;
127
74.9k
      object_as_function(obj)->prototypes[i].code = NULL;
128
74.9k
    }
129
7.49k
    break;
130
9.77M
  }
131
132
9.77M
  if (obj->identifier == NULL)
133
0
  {
134
0
    yr_free(obj);
135
0
    return ERROR_INSUFFICIENT_MEMORY;
136
0
  }
137
138
9.77M
  if (parent != NULL)
139
1.05M
  {
140
1.05M
    assert(
141
1.05M
        parent->type == OBJECT_TYPE_STRUCTURE ||
142
1.05M
        parent->type == OBJECT_TYPE_ARRAY ||
143
1.05M
        parent->type == OBJECT_TYPE_DICTIONARY ||
144
1.05M
        parent->type == OBJECT_TYPE_FUNCTION);
145
146
    // Objects with a parent take the canary from it.
147
1.05M
    obj->canary = parent->canary;
148
149
1.05M
    switch (parent->type)
150
1.05M
    {
151
1.01M
    case OBJECT_TYPE_STRUCTURE:
152
1.01M
      FAIL_ON_ERROR_WITH_CLEANUP(yr_object_structure_set_member(parent, obj), {
153
1.01M
        yr_free((void*) obj->identifier);
154
1.01M
        yr_free(obj);
155
1.01M
      });
156
1.01M
      break;
157
158
37.4k
    case OBJECT_TYPE_ARRAY:
159
37.4k
      object_as_array(parent)->prototype_item = obj;
160
37.4k
      break;
161
162
0
    case OBJECT_TYPE_DICTIONARY:
163
0
      object_as_dictionary(parent)->prototype_item = obj;
164
0
      break;
165
166
7.49k
    case OBJECT_TYPE_FUNCTION:
167
7.49k
      object_as_function(parent)->return_obj = obj;
168
7.49k
      break;
169
1.05M
    }
170
1.05M
  }
171
172
9.77M
  if (object != NULL)
173
8.81M
    *object = obj;
174
175
9.77M
  return ERROR_SUCCESS;
176
9.77M
}
177
178
void yr_object_set_canary(YR_OBJECT* object, int canary)
179
7.49k
{
180
7.49k
  object->canary = canary;
181
7.49k
}
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
7.49k
{
191
7.49k
  YR_OBJECT* return_obj;
192
7.49k
  YR_OBJECT* o = NULL;
193
7.49k
  YR_OBJECT_FUNCTION* f = NULL;
194
195
7.49k
  int8_t return_type;
196
197
  // The parent of a function must be a structure.
198
7.49k
  assert(parent != NULL && parent->type == OBJECT_TYPE_STRUCTURE);
199
200
7.49k
  switch (*return_fmt)
201
7.49k
  {
202
0
  case 'i':
203
0
    return_type = OBJECT_TYPE_INTEGER;
204
0
    break;
205
7.49k
  case 's':
206
7.49k
    return_type = OBJECT_TYPE_STRING;
207
7.49k
    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
7.49k
  }
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
7.49k
  f = object_as_function(yr_object_lookup_field(parent, identifier));
218
219
  // Overloaded functions must have the same return type.
220
7.49k
  if (f != NULL && return_type != f->return_obj->type)
221
0
    return ERROR_WRONG_RETURN_TYPE;
222
223
7.49k
  if (f == NULL)  // Function doesn't exist yet
224
7.49k
  {
225
7.49k
    FAIL_ON_ERROR(
226
7.49k
        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
7.49k
    FAIL_ON_ERROR(yr_object_create(return_type, "result", o, &return_obj));
232
233
7.49k
    f = object_as_function(o);
234
7.49k
  }
235
236
7.49k
  for (int i = 0; i < YR_MAX_OVERLOADED_FUNCTIONS; i++)
237
7.49k
  {
238
7.49k
    if (f->prototypes[i].arguments_fmt == NULL)
239
7.49k
    {
240
7.49k
      f->prototypes[i].arguments_fmt = arguments_fmt;
241
7.49k
      f->prototypes[i].code = code;
242
243
7.49k
      break;
244
7.49k
    }
245
7.49k
  }
246
247
7.49k
  if (function != NULL)
248
7.49k
    *function = (YR_OBJECT*) f;
249
250
7.49k
  return ERROR_SUCCESS;
251
7.49k
}
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.77M
{
322
9.77M
  YR_STRUCTURE_MEMBER* member;
323
9.77M
  YR_STRUCTURE_MEMBER* next_member;
324
9.77M
  YR_ARRAY_ITEMS* array_items;
325
9.77M
  YR_DICTIONARY_ITEMS* dict_items;
326
327
9.77M
  if (object == NULL)
328
0
    return;
329
330
9.77M
  switch (object->type)
331
9.77M
  {
332
1.50M
  case OBJECT_TYPE_STRUCTURE:
333
1.50M
    member = object_as_structure(object)->members;
334
335
9.77M
    while (member != NULL)
336
8.26M
    {
337
8.26M
      next_member = member->next;
338
8.26M
      yr_object_destroy(member->object);
339
8.26M
      yr_free(member);
340
8.26M
      member = next_member;
341
8.26M
    }
342
1.50M
    break;
343
344
599k
  case OBJECT_TYPE_STRING:
345
599k
    if (object->value.ss != NULL)
346
91.0k
      yr_free(object->value.ss);
347
599k
    break;
348
349
37.4k
  case OBJECT_TYPE_ARRAY:
350
37.4k
    if (object_as_array(object)->prototype_item != NULL)
351
37.4k
      yr_object_destroy(object_as_array(object)->prototype_item);
352
353
37.4k
    array_items = object_as_array(object)->items;
354
355
37.4k
    if (array_items != NULL)
356
6.30k
    {
357
1.46M
      for (int i = 0; i < array_items->length; i++)
358
1.45M
        if (array_items->objects[i] != NULL)
359
1.45M
          yr_object_destroy(array_items->objects[i]);
360
6.30k
    }
361
362
37.4k
    yr_free(array_items);
363
37.4k
    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
7.49k
  case OBJECT_TYPE_FUNCTION:
387
7.49k
    yr_object_destroy(object_as_function(object)->return_obj);
388
7.49k
    break;
389
9.77M
  }
390
391
9.77M
  yr_free((void*) object->identifier);
392
9.77M
  yr_free(object);
393
9.77M
}
394
395
YR_OBJECT* yr_object_lookup_field(YR_OBJECT* object, const char* field_name)
396
34.1M
{
397
34.1M
  YR_STRUCTURE_MEMBER* member;
398
399
34.1M
  assert(object != NULL);
400
34.1M
  assert(object->type == OBJECT_TYPE_STRUCTURE);
401
402
34.1M
  member = object_as_structure(object)->members;
403
404
365M
  while (member != NULL)
405
356M
  {
406
356M
    if (strcmp(member->object->identifier, field_name) == 0)
407
25.8M
      return member->object;
408
409
331M
    member = member->next;
410
331M
  }
411
412
8.27M
  return NULL;
413
34.1M
}
414
415
static YR_OBJECT* _yr_object_lookup(
416
    YR_OBJECT* object,
417
    int flags,
418
    const char* pattern,
419
    va_list args)
420
13.2M
{
421
13.2M
  YR_OBJECT* obj = object;
422
423
13.2M
  const char* p = pattern;
424
13.2M
  const char* key = NULL;
425
426
13.2M
  char str[256];
427
428
13.2M
  int i;
429
13.2M
  int index = -1;
430
431
25.8M
  while (obj != NULL)
432
25.8M
  {
433
25.8M
    i = 0;
434
435
189M
    while (*p != '\0' && *p != '.' && *p != '[' && i < sizeof(str) - 1)
436
163M
    {
437
163M
      str[i++] = *p++;
438
163M
    }
439
440
25.8M
    str[i] = '\0';
441
442
25.8M
    if (obj->type != OBJECT_TYPE_STRUCTURE)
443
0
      return NULL;
444
445
25.8M
    obj = yr_object_lookup_field(obj, str);
446
447
25.8M
    if (obj == NULL)
448
0
      return NULL;
449
450
25.8M
    if (*p == '[')
451
12.5M
    {
452
12.5M
      p++;
453
454
12.5M
      if (*p == '%')
455
12.5M
      {
456
12.5M
        p++;
457
458
12.5M
        switch (*p++)
459
12.5M
        {
460
12.5M
        case 'i':
461
12.5M
          index = va_arg(args, int);
462
12.5M
          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
12.5M
        }
470
12.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
12.5M
      assert(*p == ']');
492
12.5M
      p++;
493
12.5M
      assert(*p == '.' || *p == '\0');
494
495
12.5M
      switch (obj->type)
496
12.5M
      {
497
12.5M
      case OBJECT_TYPE_ARRAY:
498
12.5M
        assert(index != -1);
499
12.5M
        obj = yr_object_array_get_item(obj, flags, index);
500
12.5M
        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
12.5M
      }
507
12.5M
    }
508
509
25.8M
    if (*p == '\0')
510
13.2M
      break;
511
512
12.5M
    p++;
513
12.5M
  }
514
515
13.2M
  return obj;
516
13.2M
}
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.71M
{
538
8.71M
  YR_OBJECT* copy;
539
8.71M
  YR_OBJECT* o;
540
541
8.71M
  YR_STRUCTURE_MEMBER* structure_member;
542
543
8.71M
  *object_copy = NULL;
544
545
8.71M
  FAIL_ON_ERROR(
546
8.71M
      yr_object_create(object->type, object->identifier, NULL, &copy));
547
548
8.71M
  copy->canary = object->canary;
549
550
8.71M
  switch (object->type)
551
8.71M
  {
552
6.68M
  case OBJECT_TYPE_INTEGER:
553
6.68M
    copy->value.i = object->value.i;
554
6.68M
    break;
555
556
0
  case OBJECT_TYPE_FLOAT:
557
0
    copy->value.d = object->value.d;
558
0
    break;
559
560
569k
  case OBJECT_TYPE_STRING:
561
562
569k
    if (object->value.ss != NULL)
563
0
      copy->value.ss = ss_dup(object->value.ss);
564
569k
    else
565
569k
      copy->value.ss = NULL;
566
567
569k
    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.45M
  case OBJECT_TYPE_STRUCTURE:
585
586
1.45M
    structure_member = object_as_structure(object)->members;
587
588
8.71M
    while (structure_member != NULL)
589
7.25M
    {
590
7.25M
      FAIL_ON_ERROR_WITH_CLEANUP(
591
7.25M
          yr_object_copy(structure_member->object, &o),
592
7.25M
          yr_object_destroy(copy));
593
594
7.25M
      FAIL_ON_ERROR_WITH_CLEANUP(yr_object_structure_set_member(copy, o),
595
                                 // cleanup
596
7.25M
                                 yr_free(o);
597
7.25M
                                 yr_object_destroy(copy));
598
599
7.25M
      structure_member = structure_member->next;
600
7.25M
    }
601
602
1.45M
    break;
603
604
1.45M
  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.71M
  }
627
628
8.71M
  *object_copy = copy;
629
630
8.71M
  return ERROR_SUCCESS;
631
8.71M
}
632
633
int yr_object_structure_set_member(YR_OBJECT* object, YR_OBJECT* member)
634
8.26M
{
635
8.26M
  YR_STRUCTURE_MEMBER* sm;
636
637
8.26M
  assert(object->type == OBJECT_TYPE_STRUCTURE);
638
639
  // Check if the object already have a member with the same identifier
640
641
8.26M
  if (yr_object_lookup_field(object, member->identifier) != NULL)
642
0
    return ERROR_DUPLICATED_STRUCTURE_MEMBER;
643
644
8.26M
  sm = (YR_STRUCTURE_MEMBER*) yr_malloc(sizeof(YR_STRUCTURE_MEMBER));
645
646
8.26M
  if (sm == NULL)
647
0
    return ERROR_INSUFFICIENT_MEMORY;
648
649
8.26M
  member->parent = object;
650
8.26M
  sm->object = member;
651
8.26M
  sm->next = object_as_structure(object)->members;
652
653
8.26M
  object_as_structure(object)->members = sm;
654
655
8.26M
  return ERROR_SUCCESS;
656
8.26M
}
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
12.5M
{
673
12.5M
  YR_OBJECT* result = NULL;
674
12.5M
  YR_OBJECT_ARRAY* array;
675
676
12.5M
  assert(object->type == OBJECT_TYPE_ARRAY);
677
678
12.5M
  if (index < 0)
679
0
    return NULL;
680
681
12.5M
  array = object_as_array(object);
682
683
12.5M
  if (array->items != NULL && array->items->capacity > index)
684
12.5M
    result = array->items->objects[index];
685
686
12.5M
  if (result == NULL && flags & OBJECT_CREATE)
687
1.45M
  {
688
1.45M
    yr_object_copy(array->prototype_item, &result);
689
690
1.45M
    if (result != NULL)
691
1.45M
      yr_object_array_set_item(object, result, index);
692
1.45M
  }
693
694
12.5M
  return result;
695
12.5M
}
696
697
int yr_object_array_set_item(YR_OBJECT* object, YR_OBJECT* item, int index)
698
1.45M
{
699
1.45M
  YR_OBJECT_ARRAY* array;
700
701
1.45M
  int capacity;
702
703
1.45M
  assert(index >= 0);
704
1.45M
  assert(object->type == OBJECT_TYPE_ARRAY);
705
706
1.45M
  array = object_as_array(object);
707
708
1.45M
  if (array->items == NULL)
709
6.30k
  {
710
6.30k
    capacity = 64;
711
712
6.30k
    while (capacity <= index) capacity *= 2;
713
714
6.30k
    array->items = (YR_ARRAY_ITEMS*) yr_malloc(
715
6.30k
        sizeof(YR_ARRAY_ITEMS) + capacity * sizeof(YR_OBJECT*));
716
717
6.30k
    if (array->items == NULL)
718
0
      return ERROR_INSUFFICIENT_MEMORY;
719
720
6.30k
    memset(array->items->objects, 0, capacity * sizeof(YR_OBJECT*));
721
722
6.30k
    array->items->capacity = capacity;
723
6.30k
    array->items->length = 0;
724
6.30k
  }
725
1.45M
  else if (index >= array->items->capacity)
726
1.61k
  {
727
1.61k
    capacity = array->items->capacity * 2;
728
729
1.61k
    while (capacity <= index) capacity *= 2;
730
731
1.61k
    array->items = (YR_ARRAY_ITEMS*) yr_realloc(
732
1.61k
        array->items, sizeof(YR_ARRAY_ITEMS) + capacity * sizeof(YR_OBJECT*));
733
734
1.61k
    if (array->items == NULL)
735
0
      return ERROR_INSUFFICIENT_MEMORY;
736
737
1.64M
    for (int i = array->items->capacity; i < capacity; i++)
738
1.64M
      array->items->objects[i] = NULL;
739
740
1.61k
    array->items->capacity = capacity;
741
1.61k
  }
742
743
1.45M
  item->parent = object;
744
1.45M
  array->items->objects[index] = item;
745
746
1.45M
  if (index >= array->items->length)
747
1.45M
    array->items->length = index + 1;
748
749
1.45M
  return ERROR_SUCCESS;
750
1.45M
}
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
13.1M
{
950
13.1M
  YR_OBJECT* integer_obj;
951
952
13.1M
  va_list args;
953
13.1M
  va_start(args, field);
954
955
13.1M
  if (field != NULL)
956
13.1M
    integer_obj = _yr_object_lookup(object, OBJECT_CREATE, field, args);
957
0
  else
958
0
    integer_obj = object;
959
960
13.1M
  va_end(args);
961
962
13.1M
  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
13.1M
  assert(integer_obj->type == OBJECT_TYPE_INTEGER);
971
972
13.1M
  integer_obj->value.i = value;
973
974
13.1M
  return ERROR_SUCCESS;
975
13.1M
}
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
91.0k
{
1013
91.0k
  YR_OBJECT* string_obj;
1014
1015
91.0k
  va_list args;
1016
91.0k
  va_start(args, field);
1017
1018
91.0k
  if (field != NULL)
1019
91.0k
    string_obj = _yr_object_lookup(object, OBJECT_CREATE, field, args);
1020
0
  else
1021
0
    string_obj = object;
1022
1023
91.0k
  va_end(args);
1024
1025
91.0k
  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
91.0k
  assert(string_obj->type == OBJECT_TYPE_STRING);
1034
1035
91.0k
  if (string_obj->value.ss != NULL)
1036
0
    yr_free(string_obj->value.ss);
1037
1038
91.0k
  if (value != NULL)
1039
91.0k
  {
1040
91.0k
    string_obj->value.ss = (SIZED_STRING*) yr_malloc(
1041
91.0k
        len + sizeof(SIZED_STRING));
1042
1043
91.0k
    if (string_obj->value.ss == NULL)
1044
0
      return ERROR_INSUFFICIENT_MEMORY;
1045
1046
91.0k
    string_obj->value.ss->length = (uint32_t) len;
1047
91.0k
    string_obj->value.ss->flags = 0;
1048
1049
91.0k
    memcpy(string_obj->value.ss->c_string, value, len);
1050
91.0k
    string_obj->value.ss->c_string[len] = '\0';
1051
91.0k
  }
1052
0
  else
1053
0
  {
1054
0
    string_obj->value.ss = NULL;
1055
0
  }
1056
1057
91.0k
  return ERROR_SUCCESS;
1058
91.0k
}
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
}