Coverage Report

Created: 2025-07-23 06:42

/src/zydis/src/FormatterBuffer.c
Line
Count
Source (jump to first uncovered line)
1
/***************************************************************************************************
2
3
  Zyan Disassembler Library (Zydis)
4
5
  Original Author : Florian Bernd
6
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in all
15
 * copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * SOFTWARE.
24
25
***************************************************************************************************/
26
27
#include <Zydis/Internal/String.h>
28
#include <Zydis/FormatterBuffer.h>
29
30
/* ============================================================================================== */
31
/* Exported functions                                                                             */
32
/* ============================================================================================== */
33
34
/* ---------------------------------------------------------------------------------------------- */
35
/* Token                                                                                          */
36
/* ---------------------------------------------------------------------------------------------- */
37
38
ZyanStatus ZydisFormatterTokenGetValue(const ZydisFormatterToken* token,
39
    ZydisTokenType* type, ZyanConstCharPointer* value)
40
0
{
41
0
    if (!token || !type || !value)
42
0
    {
43
0
        return ZYAN_STATUS_INVALID_ARGUMENT;
44
0
    }
45
46
0
    *type = token->type;
47
0
    *value = (ZyanConstCharPointer)((ZyanU8*)token + sizeof(ZydisFormatterToken));
48
49
0
    return ZYAN_STATUS_SUCCESS;
50
0
}
51
52
ZyanStatus ZydisFormatterTokenNext(ZydisFormatterTokenConst** token)
53
0
{
54
0
    if (!token || !*token)
55
0
    {
56
0
        return ZYAN_STATUS_INVALID_ARGUMENT;
57
0
    }
58
59
0
    const ZyanU8 next = (*token)->next;
60
0
    if (!next)
61
0
    {
62
0
        return ZYAN_STATUS_OUT_OF_RANGE;
63
0
    }
64
0
    *token = (ZydisFormatterTokenConst*)((ZyanU8*)*token + sizeof(ZydisFormatterToken) + next);
65
66
0
    return ZYAN_STATUS_SUCCESS;
67
0
}
68
69
/* ---------------------------------------------------------------------------------------------- */
70
/* Buffer                                                                                         */
71
/* ---------------------------------------------------------------------------------------------- */
72
73
ZyanStatus ZydisFormatterBufferGetToken(const ZydisFormatterBuffer* buffer,
74
    ZydisFormatterTokenConst** token)
75
0
{
76
0
    if (!buffer || !token)
77
0
    {
78
0
        return ZYAN_STATUS_INVALID_ARGUMENT;
79
0
    }
80
81
0
    *token = ((ZydisFormatterTokenConst*)buffer->string.vector.data - 1);
82
0
    if ((*token)->type == ZYDIS_TOKEN_INVALID)
83
0
    {
84
0
        return ZYAN_STATUS_INVALID_OPERATION;
85
0
    }
86
87
0
    return ZYAN_STATUS_SUCCESS;
88
0
}
89
90
ZyanStatus ZydisFormatterBufferGetString(ZydisFormatterBuffer* buffer, ZyanString** string)
91
0
{
92
0
    if (!buffer || !string)
93
0
    {
94
0
        return ZYAN_STATUS_INVALID_ARGUMENT;
95
0
    }
96
97
0
    if (buffer->is_token_list &&
98
0
        ((ZydisFormatterTokenConst*)buffer->string.vector.data - 1)->type == ZYDIS_TOKEN_INVALID)
99
0
    {
100
0
        return ZYAN_STATUS_INVALID_OPERATION;
101
0
    }
102
103
0
    ZYAN_ASSERT(buffer->string.vector.data);
104
0
    ZYAN_ASSERT(buffer->string.vector.size);
105
106
0
    *string = &buffer->string;
107
108
0
    return ZYAN_STATUS_SUCCESS;
109
0
}
110
111
ZyanStatus ZydisFormatterBufferAppend(ZydisFormatterBuffer* buffer, ZydisTokenType type)
112
0
{
113
0
    if (!buffer)
114
0
    {
115
0
        return ZYAN_STATUS_INVALID_ARGUMENT;
116
0
    }
117
118
0
    if (!buffer->is_token_list)
119
0
    {
120
0
        return ZYAN_STATUS_SUCCESS;
121
0
    }
122
123
0
    ZydisFormatterToken* const last = (ZydisFormatterToken*)buffer->string.vector.data - 1;
124
0
    if (last->type == type)
125
0
    {
126
0
        return ZYAN_STATUS_SUCCESS;
127
0
    }
128
129
0
    const ZyanUSize len = buffer->string.vector.size;
130
0
    ZYAN_ASSERT((len > 0) && (len < 256));
131
0
    if (buffer->capacity <= len + sizeof(ZydisFormatterToken))
132
0
    {
133
0
        return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
134
0
    }
135
136
0
    last->next = (ZyanU8)len;
137
138
0
    const ZyanUSize delta = len + sizeof(ZydisFormatterToken);
139
0
    buffer->capacity -= delta;
140
0
    buffer->string.vector.data = (ZyanU8*)buffer->string.vector.data + delta;
141
0
    buffer->string.vector.size = 1;
142
0
    buffer->string.vector.capacity = ZYAN_MIN(buffer->capacity, 255);
143
0
    *(char*)buffer->string.vector.data = '\0';
144
145
0
    ZydisFormatterToken* const token = (ZydisFormatterToken*)buffer->string.vector.data - 1;
146
0
    token->type = type;
147
0
    token->next = 0;
148
149
0
    return ZYAN_STATUS_SUCCESS;
150
0
}
151
152
ZyanStatus ZydisFormatterBufferRemember(const ZydisFormatterBuffer* buffer, ZyanUPointer* state)
153
0
{
154
0
    if (!buffer || !state)
155
0
    {
156
0
        return ZYAN_STATUS_INVALID_ARGUMENT;
157
0
    }
158
159
0
    if (buffer->is_token_list)
160
0
    {
161
0
        *state = (ZyanUPointer)buffer->string.vector.data;
162
0
    } else
163
0
    {
164
0
        *state = (ZyanUPointer)buffer->string.vector.size;
165
0
    }
166
167
0
    return ZYAN_STATUS_SUCCESS;
168
0
}
169
170
ZyanStatus ZydisFormatterBufferRestore(ZydisFormatterBuffer* buffer, ZyanUPointer state)
171
0
{
172
0
    if (!buffer)
173
0
    {
174
0
        return ZYAN_STATUS_INVALID_ARGUMENT;
175
0
    }
176
177
0
    if (buffer->is_token_list)
178
0
    {
179
0
        const ZyanUSize delta = (ZyanUPointer)buffer->string.vector.data - state;
180
0
        buffer->capacity += delta;
181
0
        buffer->string.vector.data = (void*)state;
182
0
        buffer->string.vector.size = 1; // TODO: Restore size?
183
0
        buffer->string.vector.capacity = ZYAN_MIN(buffer->capacity, 255);
184
0
        *(char*)buffer->string.vector.data = '\0';
185
0
    } else
186
0
    {
187
0
        buffer->string.vector.size = (ZyanUSize)state;
188
0
        ZYDIS_STRING_NULLTERMINATE(&buffer->string);
189
0
    }
190
191
0
    return ZYAN_STATUS_SUCCESS;
192
0
}
193
194
/* ---------------------------------------------------------------------------------------------- */
195
196
/* ============================================================================================== */