Coverage Report

Created: 2025-07-04 06:49

/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
216
{
211
216
    PyObject *return_value = NULL;
212
216
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
213
214
216
    #define NUM_KEYWORDS 1
215
216
    static struct {
216
216
        PyGC_Head _this_is_not_used;
217
216
        PyObject_VAR_HEAD
218
216
        Py_hash_t ob_hash;
219
216
        PyObject *ob_item[NUM_KEYWORDS];
220
216
    } _kwtuple = {
221
216
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
222
216
        .ob_hash = -1,
223
216
        .ob_item = { &_Py_ID(allow_code), },
224
216
    };
225
216
    #undef NUM_KEYWORDS
226
216
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
227
228
    #else  // !Py_BUILD_CORE
229
    #  define KWTUPLE NULL
230
    #endif  // !Py_BUILD_CORE
231
232
216
    static const char * const _keywords[] = {"", "", "allow_code", NULL};
233
216
    static _PyArg_Parser _parser = {
234
216
        .keywords = _keywords,
235
216
        .fname = "dumps",
236
216
        .kwtuple = KWTUPLE,
237
216
    };
238
216
    #undef KWTUPLE
239
216
    PyObject *argsbuf[3];
240
216
    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
241
216
    PyObject *value;
242
216
    int version = Py_MARSHAL_VERSION;
243
216
    int allow_code = 1;
244
245
216
    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
246
216
            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
247
216
    if (!args) {
248
0
        goto exit;
249
0
    }
250
216
    value = args[0];
251
216
    if (nargs < 2) {
252
216
        goto skip_optional_posonly;
253
216
    }
254
0
    noptargs--;
255
0
    version = PyLong_AsInt(args[1]);
256
0
    if (version == -1 && PyErr_Occurred()) {
257
0
        goto exit;
258
0
    }
259
216
skip_optional_posonly:
260
216
    if (!noptargs) {
261
216
        goto skip_optional_kwonly;
262
216
    }
263
0
    allow_code = PyObject_IsTrue(args[2]);
264
0
    if (allow_code < 0) {
265
0
        goto exit;
266
0
    }
267
216
skip_optional_kwonly:
268
216
    return_value = marshal_dumps_impl(module, value, version, allow_code);
269
270
216
exit:
271
216
    return return_value;
272
216
}
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
510
{
295
510
    PyObject *return_value = NULL;
296
510
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
297
298
510
    #define NUM_KEYWORDS 1
299
510
    static struct {
300
510
        PyGC_Head _this_is_not_used;
301
510
        PyObject_VAR_HEAD
302
510
        Py_hash_t ob_hash;
303
510
        PyObject *ob_item[NUM_KEYWORDS];
304
510
    } _kwtuple = {
305
510
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
306
510
        .ob_hash = -1,
307
510
        .ob_item = { &_Py_ID(allow_code), },
308
510
    };
309
510
    #undef NUM_KEYWORDS
310
510
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
311
312
    #else  // !Py_BUILD_CORE
313
    #  define KWTUPLE NULL
314
    #endif  // !Py_BUILD_CORE
315
316
510
    static const char * const _keywords[] = {"", "allow_code", NULL};
317
510
    static _PyArg_Parser _parser = {
318
510
        .keywords = _keywords,
319
510
        .fname = "loads",
320
510
        .kwtuple = KWTUPLE,
321
510
    };
322
510
    #undef KWTUPLE
323
510
    PyObject *argsbuf[2];
324
510
    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
325
510
    Py_buffer bytes = {NULL, NULL};
326
510
    int allow_code = 1;
327
328
510
    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
329
510
            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
330
510
    if (!args) {
331
0
        goto exit;
332
0
    }
333
510
    if (PyObject_GetBuffer(args[0], &bytes, PyBUF_SIMPLE) != 0) {
334
0
        goto exit;
335
0
    }
336
510
    if (!noptargs) {
337
510
        goto skip_optional_kwonly;
338
510
    }
339
0
    allow_code = PyObject_IsTrue(args[1]);
340
0
    if (allow_code < 0) {
341
0
        goto exit;
342
0
    }
343
510
skip_optional_kwonly:
344
510
    return_value = marshal_loads_impl(module, &bytes, allow_code);
345
346
510
exit:
347
    /* Cleanup for bytes */
348
510
    if (bytes.obj) {
349
510
       PyBuffer_Release(&bytes);
350
510
    }
351
352
510
    return return_value;
353
510
}
354
/*[clinic end generated code: output=3e4bfc070a3c78ac input=a9049054013a1b77]*/