Coverage Report

Created: 2026-10-17 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xmlsec/src/membuf.c
Line
Count
Source
1
/**
2
 * XML Security Library (http://www.aleksey.com/xmlsec).
3
 *
4
 * This is free software; see the Copyright file in the source distribution for precise wording.
5
 *
6
 * Copyright (C) 2002-2026 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
7
 */
8
/**
9
 * @addtogroup xmlsec_core_membuf
10
 * @brief Memory buffer transform functions.
11
 */
12
#include "globals.h"
13
14
#include <stdlib.h>
15
#include <string.h>
16
17
#include <libxml/tree.h>
18
19
#include <xmlsec/xmlsec.h>
20
#include <xmlsec/buffer.h>
21
#include <xmlsec/keys.h>
22
#include <xmlsec/transforms.h>
23
#include <xmlsec/base64.h>
24
#include <xmlsec/membuf.h>
25
#include <xmlsec/errors.h>
26
27
#include "cast_helpers.h"
28
29
/******************************************************************************
30
 *
31
 * Memory Buffer Transform
32
 *
33
 * xmlSecTransform + xmlSecBuffer
34
 *
35
  *****************************************************************************/
36
0
XMLSEC_TRANSFORM_DECLARE(MemBuf, xmlSecBuffer)
37
0
#define xmlSecMemBufSize XMLSEC_TRANSFORM_SIZE(MemBuf)
38
0
39
0
static int              xmlSecTransformMemBufInitialize         (xmlSecTransformPtr transform);
40
0
static void             xmlSecTransformMemBufFinalize           (xmlSecTransformPtr transform);
41
0
static int              xmlSecTransformMemBufExecute            (xmlSecTransformPtr transform,
42
0
                                                                 int last,
43
0
                                                                 xmlSecTransformCtxPtr transformCtx);
44
0
static xmlSecTransformKlass xmlSecTransformMemBufKlass = {
45
0
    /* klass/object sizes */
46
0
    sizeof(xmlSecTransformKlass),               /* xmlSecSize klassSize */
47
0
    xmlSecMemBufSize,                           /* xmlSecSize objSize */
48
0
49
0
    xmlSecNameMemBuf,                           /* const xmlChar* name; */
50
0
    NULL,                                       /* const xmlChar* href; */
51
0
    0,                                          /* xmlSecAlgorithmUsage usage; */
52
0
53
0
    xmlSecTransformMemBufInitialize,            /* xmlSecTransformInitializeMethod initialize; */
54
0
    xmlSecTransformMemBufFinalize,              /* xmlSecTransformFinalizeMethod finalize; */
55
0
    NULL,                                       /* xmlSecTransformNodeReadMethod readNode; */
56
0
    NULL,                                       /* xmlSecTransformNodeWriteMethod writeNode; */
57
0
    NULL,                                       /* xmlSecTransformSetKeyReqMethod setKeyReq; */
58
0
    NULL,                                       /* xmlSecTransformSetKeyMethod setKey; */
59
0
    NULL,                                       /* xmlSecTransformVerifyMethod verify; */
60
0
    xmlSecTransformDefaultGetDataType,          /* xmlSecTransformGetDataTypeMethod getDataType; */
61
0
    xmlSecTransformDefaultPushBin,              /* xmlSecTransformPushBinMethod pushBin; */
62
0
    xmlSecTransformDefaultPopBin,               /* xmlSecTransformPopBinMethod popBin; */
63
0
    NULL,                                       /* xmlSecTransformPushXmlMethod pushXml; */
64
0
    NULL,                                       /* xmlSecTransformPopXmlMethod popXml; */
65
0
    xmlSecTransformMemBufExecute,               /* xmlSecTransformExecuteMethod execute; */
66
0
67
0
    NULL,                                       /* void* reserved0; */
68
0
    NULL,                                       /* void* reserved1; */
69
0
};
70
0
71
0
/**
72
0
 * @brief The memory buffer transform (used to store the data that go through it).
73
0
 *
74
0
 * @return memory buffer transform klass.
75
0
 */
76
0
xmlSecTransformId
77
0
xmlSecTransformMemBufGetKlass(void) {
78
0
    return(&xmlSecTransformMemBufKlass);
79
0
}
80
81
/**
82
 * @brief Gets the pointer to memory buffer transform buffer.
83
 * @param transform the pointer to memory buffer transform.
84
 *
85
 * @return pointer to the transform's xmlSecBuffer.
86
 */
87
xmlSecBufferPtr
88
0
xmlSecTransformMemBufGetBuffer(xmlSecTransformPtr transform) {
89
0
    xmlSecBufferPtr buffer;
90
91
0
    xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformMemBufId), NULL);
92
93
0
    buffer = xmlSecMemBufGetCtx(transform);
94
0
    xmlSecAssert2(buffer != NULL, NULL);
95
96
0
    return(buffer);
97
0
}
98
99
static int
100
0
xmlSecTransformMemBufInitialize(xmlSecTransformPtr transform) {
101
0
    xmlSecBufferPtr buffer;
102
0
    int ret;
103
104
0
    xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformMemBufId), -1);
105
106
0
    buffer = xmlSecMemBufGetCtx(transform);
107
0
    xmlSecAssert2(buffer != NULL, -1);
108
109
0
    ret = xmlSecBufferInitialize(buffer, 0);
110
0
    if(ret < 0) {
111
0
        xmlSecInternalError("xmlSecBufferInitialize",
112
0
                            xmlSecTransformGetName(transform));
113
0
        return(-1);
114
0
    }
115
0
    return(0);
116
0
}
117
118
static void
119
0
xmlSecTransformMemBufFinalize(xmlSecTransformPtr transform) {
120
0
    xmlSecBufferPtr buffer;
121
122
0
    xmlSecAssert(xmlSecTransformCheckId(transform, xmlSecTransformMemBufId));
123
124
0
    buffer = xmlSecMemBufGetCtx(transform);
125
0
    xmlSecAssert(buffer != NULL);
126
127
0
    xmlSecBufferFinalize(buffer);
128
0
}
129
130
/*
131
 * Note: in case of failure, the transform state is undefined until
132
 * the #xmlSecTransformDestroy function is called.
133
 */
134
static int
135
0
xmlSecTransformMemBufExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
136
0
    xmlSecBufferPtr buffer;
137
0
    xmlSecBufferPtr in, out;
138
0
    xmlSecSize inSize;
139
0
    int ret;
140
141
0
    xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformMemBufId), -1);
142
0
    xmlSecAssert2(transformCtx != NULL, -1);
143
144
0
    buffer = xmlSecMemBufGetCtx(transform);
145
0
    xmlSecAssert2(buffer != NULL, -1);
146
147
0
    in = &(transform->inBuf);
148
0
    out = &(transform->outBuf);
149
0
    inSize = xmlSecBufferGetSize(in);
150
151
0
    if(transform->status == xmlSecTransformStatusNone) {
152
0
        transform->status = xmlSecTransformStatusWorking;
153
0
    }
154
155
0
    if(transform->status == xmlSecTransformStatusWorking) {
156
        /* just copy everything from in to our buffer and out */
157
0
        ret = xmlSecBufferAppend(buffer, xmlSecBufferGetData(in), inSize);
158
0
        if(ret < 0) {
159
0
            xmlSecInternalError2("xmlSecBufferAppend",
160
0
                                 xmlSecTransformGetName(transform),
161
0
                                 "size=" XMLSEC_SIZE_FMT, inSize);
162
0
            return(-1);
163
0
        }
164
165
0
        ret = xmlSecBufferAppend(out, xmlSecBufferGetData(in), inSize);
166
0
        if(ret < 0) {
167
0
            xmlSecInternalError2("xmlSecBufferAppend",
168
0
                                 xmlSecTransformGetName(transform),
169
0
                                 "size=" XMLSEC_SIZE_FMT, inSize);
170
0
            return(-1);
171
0
        }
172
173
0
        ret = xmlSecBufferRemoveHead(in, inSize);
174
0
        if(ret < 0) {
175
0
            xmlSecInternalError2("xmlSecBufferRemoveHead",
176
0
                                 xmlSecTransformGetName(transform),
177
0
                                 "size=" XMLSEC_SIZE_FMT, inSize);
178
0
            return(-1);
179
0
        }
180
181
0
        if(last != 0) {
182
0
            transform->status = xmlSecTransformStatusFinished;
183
0
        }
184
0
    } else if(transform->status == xmlSecTransformStatusFinished) {
185
        /* the only way we can get here is if there is no input */
186
0
        xmlSecAssert2(inSize == 0, -1);
187
0
    } else {
188
0
        xmlSecInvalidTransformStatusError(transform);
189
0
        return(-1);
190
0
    }
191
0
    return(0);
192
0
}