Coverage Report

Created: 2023-09-25 07:15

/src/yara/libyara/stack.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
Copyright (c) 2018. 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 <yara/error.h>
31
#include <yara/integers.h>
32
#include <yara/mem.h>
33
#include <yara/stack.h>
34
35
////////////////////////////////////////////////////////////////////////////////
36
// Creates a stack for items of the size specified by item_size. All items
37
// in the stack must have the same size. The stack will have an initial
38
// capacity as specified by initial_capacity and will grow as required when
39
// more objects are pushed.
40
//
41
int yr_stack_create(int initial_capacity, int item_size, YR_STACK** stack)
42
5.30k
{
43
5.30k
  *stack = (YR_STACK*) yr_malloc(sizeof(YR_STACK));
44
45
5.30k
  if (*stack == NULL)
46
0
    return ERROR_INSUFFICIENT_MEMORY;
47
48
5.30k
  (*stack)->items = yr_malloc(initial_capacity * item_size);
49
50
5.30k
  if ((*stack)->items == NULL)
51
0
  {
52
0
    yr_free(*stack);
53
0
    *stack = NULL;
54
0
    return ERROR_INSUFFICIENT_MEMORY;
55
0
  }
56
57
5.30k
  (*stack)->capacity = initial_capacity;
58
5.30k
  (*stack)->item_size = item_size;
59
5.30k
  (*stack)->top = 0;
60
61
5.30k
  return ERROR_SUCCESS;
62
5.30k
}
63
64
////////////////////////////////////////////////////////////////////////////////
65
// Destroys a stack and deallocates all its resources.
66
//
67
void yr_stack_destroy(YR_STACK* stack)
68
5.30k
{
69
5.30k
  yr_free(stack->items);
70
5.30k
  yr_free(stack);
71
5.30k
}
72
73
////////////////////////////////////////////////////////////////////////////////
74
// Pushes an item into the stack. If the stack has reached its capacity the
75
// function tries to double the capacity. This operation can fail with
76
// ERROR_INSUFFICIENT_MEMORY.
77
//
78
int yr_stack_push(YR_STACK* stack, void* item)
79
1.37M
{
80
1.37M
  if (stack->top == stack->capacity)
81
258
  {
82
258
    void* items = yr_realloc(
83
258
        stack->items, 2 * stack->capacity * stack->item_size);
84
85
258
    if (items == NULL)
86
0
      return ERROR_INSUFFICIENT_MEMORY;
87
88
258
    stack->items = items;
89
258
    stack->capacity *= 2;
90
258
  }
91
92
1.37M
  memcpy(
93
1.37M
      (uint8_t*) stack->items + stack->top * stack->item_size,
94
1.37M
      item,
95
1.37M
      stack->item_size);
96
97
1.37M
  stack->top++;
98
99
1.37M
  return ERROR_SUCCESS;
100
1.37M
}
101
102
////////////////////////////////////////////////////////////////////////////////
103
// Pops an item from the stack. The caller must pass pointer to a buffer
104
// where the function will copy the item. The buffer must have enough space
105
// to hold the item. Returns 1 if an item could be poped and 0 if the stack
106
// was already empty.
107
//
108
int yr_stack_pop(YR_STACK* stack, void* item)
109
1.37M
{
110
1.37M
  if (stack->top == 0)  // Return 0 if stack is empty.
111
5.30k
    return 0;
112
113
1.37M
  stack->top--;
114
115
1.37M
  memcpy(
116
1.37M
      item,
117
1.37M
      (uint8_t*) stack->items + stack->top * stack->item_size,
118
1.37M
      stack->item_size);
119
120
1.37M
  return 1;
121
1.37M
}