Coverage Report

Created: 2025-07-11 06:24

/src/cpython/Python/clinic/marshal.c.h
Line
Count
Source (jump to first uncovered line)
1
/*[clinic input]
2
preserve
3
[clinic start generated code]*/
4
5
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
6
#  include "pycore_gc.h"          // PyGC_Head
7
#  include "pycore_runtime.h"     // _Py_ID()
8
#endif
9
#include "pycore_modsupport.h"    // _PyArg_UnpackKeywords()
10
11
PyDoc_STRVAR(marshal_dump__doc__,
12
"dump($module, value, file, version=version, /, *, allow_code=True)\n"
13
"--\n"
14
"\n"
15
"Write the value on the open file.\n"
16
"\n"
17
"  value\n"
18
"    Must be a supported type.\n"
19
"  file\n"
20
"    Must be a writeable binary file.\n"
21
"  version\n"
22
"    Indicates the data format that dump should use.\n"
23
"  allow_code\n"
24
"    Allow to write code objects.\n"
25
"\n"
26
"If the value has (or contains an object that has) an unsupported type, a\n"
27
"ValueError exception is raised - but garbage data will also be written\n"
28
"to the file. The object will not be properly read back by load().");
29
30
#define MARSHAL_DUMP_METHODDEF    \
31
    {"dump", _PyCFunction_CAST(marshal_dump), METH_FASTCALL|METH_KEYWORDS, marshal_dump__doc__},
32
33
static PyObject *
34
marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file,
35
                  int version, int allow_code);
36
37
static PyObject *
38
marshal_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
39
0
{
40
0
    PyObject *return_value = NULL;
41
0
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
42
43
0
    #define NUM_KEYWORDS 1
44
0
    static struct {
45
0
        PyGC_Head _this_is_not_used;
46
0
        PyObject_VAR_HEAD
47
0
        Py_hash_t ob_hash;
48
0
        PyObject *ob_item[NUM_KEYWORDS];
49
0
    } _kwtuple = {
50
0
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
51
0
        .ob_hash = -1,
52
0
        .ob_item = { &_Py_ID(allow_code), },
53
0
    };
54
0
    #undef NUM_KEYWORDS
55
0
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
56
57
    #else  // !Py_BUILD_CORE
58
    #  define KWTUPLE NULL
59
    #endif  // !Py_BUILD_CORE
60
61
0
    static const char * const _keywords[] = {"", "", "", "allow_code", NULL};
62
0
    static _PyArg_Parser _parser = {
63
0
        .keywords = _keywords,
64
0
        .fname = "dump",
65
0
        .kwtuple = KWTUPLE,
66
0
    };
67
0
    #undef KWTUPLE
68
0
    PyObject *argsbuf[4];
69
0
    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
70
0
    PyObject *value;
71
0
    PyObject *file;
72
0
    int version = Py_MARSHAL_VERSION;
73
0
    int allow_code = 1;
74
75
0
    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
76
0
            /*minpos*/ 2, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
77
0
    if (!args) {
78
0
        goto exit;
79
0
    }
80
0
    value = args[0];
81
0
    file = args[1];
82
0
    if (nargs < 3) {
83
0
        goto skip_optional_posonly;
84
0
    }
85
0
    noptargs--;
86
0
    version = PyLong_AsInt(args[2]);
87
0
    if (version == -1 && PyErr_Occurred()) {
88
0
        goto exit;
89
0
    }
90
0
skip_optional_posonly:
91
0
    if (!noptargs) {
92
0
        goto skip_optional_kwonly;
93
0
    }
94
0
    allow_code = PyObject_IsTrue(args[3]);
95
0
    if (allow_code < 0) {
96
0
        goto exit;
97
0
    }
98
0
skip_optional_kwonly:
99
0
    return_value = marshal_dump_impl(module, value, file, version, allow_code);
100
101
0
exit:
102
0
    return return_value;
103
0
}
104
105
PyDoc_STRVAR(marshal_load__doc__,
106
"load($module, file, /, *, allow_code=True)\n"
107
"--\n"
108
"\n"
109
"Read one value from the open file and return it.\n"
110
"\n"
111
"  file\n"
112
"    Must be readable binary file.\n"
113
"  allow_code\n"
114
"    Allow to load code objects.\n"
115
"\n"
116
"If no valid value is read (e.g. because the data has a different Python\n"
117
"version\'s incompatible marshal format), raise EOFError, ValueError or\n"
118
"TypeError.\n"
119
"\n"
120
"Note: If an object containing an unsupported type was marshalled with\n"
121
"dump(), load() will substitute None for the unmarshallable type.");
122
123
#define MARSHAL_LOAD_METHODDEF    \
124
    {"load", _PyCFunction_CAST(marshal_load), METH_FASTCALL|METH_KEYWORDS, marshal_load__doc__},
125
126
static PyObject *
127
marshal_load_impl(PyObject *module, PyObject *file, int allow_code);
128
129
static PyObject *
130
marshal_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
131
0
{
132
0
    PyObject *return_value = NULL;
133
0
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
134
135
0
    #define NUM_KEYWORDS 1
136
0
    static struct {
137
0
        PyGC_Head _this_is_not_used;
138
0
        PyObject_VAR_HEAD
139
0
        Py_hash_t ob_hash;
140
0
        PyObject *ob_item[NUM_KEYWORDS];
141
0
    } _kwtuple = {
142
0
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
143
0
        .ob_hash = -1,
144
0
        .ob_item = { &_Py_ID(allow_code), },
145
0
    };
146
0
    #undef NUM_KEYWORDS
147
0
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
148
149
    #else  // !Py_BUILD_CORE
150
    #  define KWTUPLE NULL
151
    #endif  // !Py_BUILD_CORE
152
153
0
    static const char * const _keywords[] = {"", "allow_code", NULL};
154
0
    static _PyArg_Parser _parser = {
155
0
        .keywords = _keywords,
156
0
        .fname = "load",
157
0
        .kwtuple = KWTUPLE,
158
0
    };
159
0
    #undef KWTUPLE
160
0
    PyObject *argsbuf[2];
161
0
    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
162
0
    PyObject *file;
163
0
    int allow_code = 1;
164
165
0
    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
166
0
            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
167
0
    if (!args) {
168
0
        goto exit;
169
0
    }
170
0
    file = args[0];
171
0
    if (!noptargs) {
172
0
        goto skip_optional_kwonly;
173
0
    }
174
0
    allow_code = PyObject_IsTrue(args[1]);
175
0
    if (allow_code < 0) {
176
0
        goto exit;
177
0
    }
178
0
skip_optional_kwonly:
179
0
    return_value = marshal_load_impl(module, file, allow_code);
180
181
0
exit:
182
0
    return return_value;
183
0
}
184
185
PyDoc_STRVAR(marshal_dumps__doc__,
186
"dumps($module, value, version=version, /, *, allow_code=True)\n"
187
"--\n"
188
"\n"
189
"Return the bytes object that would be written to a file by dump(value, file).\n"
190
"\n"
191
"  value\n"
192
"    Must be a supported type.\n"
193
"  version\n"
194
"    Indicates the data format that dumps should use.\n"
195
"  allow_code\n"
196
"    Allow to write code objects.\n"
197
"\n"
198
"Raise a ValueError exception if value has (or contains an object that has) an\n"
199
"unsupported type.");
200
201
#define MARSHAL_DUMPS_METHODDEF    \
202
    {"dumps", _PyCFunction_CAST(marshal_dumps), METH_FASTCALL|METH_KEYWORDS, marshal_dumps__doc__},
203
204
static PyObject *
205
marshal_dumps_impl(PyObject *module, PyObject *value, int version,
206
                   int allow_code);
207
208
static PyObject *
209
marshal_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
210
223
{
211
223
    PyObject *return_value = NULL;
212
223
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
213
214
223
    #define NUM_KEYWORDS 1
215
223
    static struct {
216
223
        PyGC_Head _this_is_not_used;
217
223
        PyObject_VAR_HEAD
218
223
        Py_hash_t ob_hash;
219
223
        PyObject *ob_item[NUM_KEYWORDS];
220
223
    } _kwtuple = {
221
223
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
222
223
        .ob_hash = -1,
223
223
        .ob_item = { &_Py_ID(allow_code), },
224
223
    };
225
223
    #undef NUM_KEYWORDS
226
223
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
227
228
    #else  // !Py_BUILD_CORE
229
    #  define KWTUPLE NULL
230
    #endif  // !Py_BUILD_CORE
231
232
223
    static const char * const _keywords[] = {"", "", "allow_code", NULL};
233
223
    static _PyArg_Parser _parser = {
234
223
        .keywords = _keywords,
235
223
        .fname = "dumps",
236
223
        .kwtuple = KWTUPLE,
237
223
    };
238
223
    #undef KWTUPLE
239
223
    PyObject *argsbuf[3];
240
223
    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
241
223
    PyObject *value;
242
223
    int version = Py_MARSHAL_VERSION;
243
223
    int allow_code = 1;
244
245
223
    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
246
223
            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
247
223
    if (!args) {
248
0
        goto exit;
249
0
    }
250
223
    value = args[0];
251
223
    if (nargs < 2) {
252
223
        goto skip_optional_posonly;
253
223
    }
254
0
    noptargs--;
255
0
    version = PyLong_AsInt(args[1]);
256
0
    if (version == -1 && PyErr_Occurred()) {
257
0
        goto exit;
258
0
    }
259
223
skip_optional_posonly:
260
223
    if (!noptargs) {
261
223
        goto skip_optional_kwonly;
262
223
    }
263
0
    allow_code = PyObject_IsTrue(args[2]);
264
0
    if (allow_code < 0) {
265
0
        goto exit;
266
0
    }
267
223
skip_optional_kwonly:
268
223
    return_value = marshal_dumps_impl(module, value, version, allow_code);
269
270
223
exit:
271
223
    return return_value;
272
223
}
273
274
PyDoc_STRVAR(marshal_loads__doc__,
275
"loads($module, bytes, /, *, allow_code=True)\n"
276
"--\n"
277
"\n"
278
"Convert the bytes-like object to a value.\n"
279
"\n"
280
"  allow_code\n"
281
"    Allow to load code objects.\n"
282
"\n"
283
"If no valid value is found, raise EOFError, ValueError or TypeError.  Extra\n"
284
"bytes in the input are ignored.");
285
286
#define MARSHAL_LOADS_METHODDEF    \
287
    {"loads", _PyCFunction_CAST(marshal_loads), METH_FASTCALL|METH_KEYWORDS, marshal_loads__doc__},
288
289
static PyObject *
290
marshal_loads_impl(PyObject *module, Py_buffer *bytes, int allow_code);
291
292
static PyObject *
293
marshal_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
294
504
{
295
504
    PyObject *return_value = NULL;
296
504
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
297
298
504
    #define NUM_KEYWORDS 1
299
504
    static struct {
300
504
        PyGC_Head _this_is_not_used;
301
504
        PyObject_VAR_HEAD
302
504
        Py_hash_t ob_hash;
303
504
        PyObject *ob_item[NUM_KEYWORDS];
304
504
    } _kwtuple = {
305
504
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
306
504
        .ob_hash = -1,
307
504
        .ob_item = { &_Py_ID(allow_code), },
308
504
    };
309
504
    #undef NUM_KEYWORDS
310
504
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
311
312
    #else  // !Py_BUILD_CORE
313
    #  define KWTUPLE NULL
314
    #endif  // !Py_BUILD_CORE
315
316
504
    static const char * const _keywords[] = {"", "allow_code", NULL};
317
504
    static _PyArg_Parser _parser = {
318
504
        .keywords = _keywords,
319
504
        .fname = "loads",
320
504
        .kwtuple = KWTUPLE,
321
504
    };
322
504
    #undef KWTUPLE
323
504
    PyObject *argsbuf[2];
324
504
    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
325
504
    Py_buffer bytes = {NULL, NULL};
326
504
    int allow_code = 1;
327
328
504
    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
329
504
            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
330
504
    if (!args) {
331
0
        goto exit;
332
0
    }
333
504
    if (PyObject_GetBuffer(args[0], &bytes, PyBUF_SIMPLE) != 0) {
334
0
        goto exit;
335
0
    }
336
504
    if (!noptargs) {
337
504
        goto skip_optional_kwonly;
338
504
    }
339
0
    allow_code = PyObject_IsTrue(args[1]);
340
0
    if (allow_code < 0) {
341
0
        goto exit;
342
0
    }
343
504
skip_optional_kwonly:
344
504
    return_value = marshal_loads_impl(module, &bytes, allow_code);
345
346
504
exit:
347
    /* Cleanup for bytes */
348
504
    if (bytes.obj) {
349
504
       PyBuffer_Release(&bytes);
350
504
    }
351
352
504
    return return_value;
353
504
}
354
/*[clinic end generated code: output=3e4bfc070a3c78ac input=a9049054013a1b77]*/