1 /*
2 american fuzzy lop++ - python extension routines
3 ------------------------------------------------
4
5 Originally written by Michal Zalewski
6
7 Now maintained by Marc Heuse <mh@mh-sec.de>,
8 Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
9 Andrea Fioraldi <andreafioraldi@gmail.com>
10
11 Copyright 2016, 2017 Google Inc. All rights reserved.
12 Copyright 2019-2022 AFLplusplus Project. All rights reserved.
13
14 Licensed under the Apache License, Version 2.0 (the "License");
15 you may not use this file except in compliance with the License.
16 You may obtain a copy of the License at:
17
18 https://www.apache.org/licenses/LICENSE-2.0
19
20 This is the real deal: the program takes an instrumented binary and
21 attempts a variety of basic fuzzing tricks, paying close attention to
22 how they affect the execution path.
23
24 */
25
26 #include "afl-fuzz.h"
27
28 /* Python stuff */
29 #ifdef USE_PYTHON
30
unsupported(afl_state_t * afl,unsigned int seed)31 static void *unsupported(afl_state_t *afl, unsigned int seed) {
32
33 (void)afl;
34 (void)seed;
35
36 FATAL("Python Mutator cannot be called twice yet");
37 return NULL;
38
39 }
40
41 /* sorry for this makro...
42 it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */
43 #define BUF_PARAMS(name) (void **)&((py_mutator_t *)py_mutator)->name##_buf
44
fuzz_py(void * py_mutator,u8 * buf,size_t buf_size,u8 ** out_buf,u8 * add_buf,size_t add_buf_size,size_t max_size)45 static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
46 u8 *add_buf, size_t add_buf_size, size_t max_size) {
47
48 size_t mutated_size;
49 PyObject *py_args, *py_value;
50 py_args = PyTuple_New(3);
51 py_mutator_t *py = (py_mutator_t *)py_mutator;
52
53 /* buf */
54 py_value = PyByteArray_FromStringAndSize(buf, buf_size);
55 if (!py_value) {
56
57 Py_DECREF(py_args);
58 FATAL("Failed to convert arguments");
59
60 }
61
62 PyTuple_SetItem(py_args, 0, py_value);
63
64 /* add_buf */
65 py_value = PyByteArray_FromStringAndSize(add_buf, add_buf_size);
66 if (!py_value) {
67
68 Py_DECREF(py_args);
69 FATAL("Failed to convert arguments");
70
71 }
72
73 PyTuple_SetItem(py_args, 1, py_value);
74
75 /* max_size */
76 #if PY_MAJOR_VERSION >= 3
77 py_value = PyLong_FromLong(max_size);
78 #else
79 py_value = PyInt_FromLong(max_size);
80 #endif
81 if (!py_value) {
82
83 Py_DECREF(py_args);
84 FATAL("Failed to convert arguments");
85
86 }
87
88 PyTuple_SetItem(py_args, 2, py_value);
89
90 py_value = PyObject_CallObject(py->py_functions[PY_FUNC_FUZZ], py_args);
91
92 Py_DECREF(py_args);
93
94 if (py_value != NULL) {
95
96 mutated_size = PyByteArray_Size(py_value);
97
98 *out_buf = afl_realloc(BUF_PARAMS(fuzz), mutated_size);
99 if (unlikely(!*out_buf)) { PFATAL("alloc"); }
100
101 memcpy(*out_buf, PyByteArray_AsString(py_value), mutated_size);
102 Py_DECREF(py_value);
103 return mutated_size;
104
105 } else {
106
107 PyErr_Print();
108 FATAL("python custom fuzz: call failed");
109
110 }
111
112 }
113
custom_describe_py(void * py_mutator,size_t max_description_len)114 static const char *custom_describe_py(void * py_mutator,
115 size_t max_description_len) {
116
117 PyObject *py_args, *py_value;
118
119 py_args = PyTuple_New(1);
120
121 PyLong_FromSize_t(max_description_len);
122
123 /* add_buf */
124 py_value = PyLong_FromSize_t(max_description_len);
125 if (!py_value) {
126
127 Py_DECREF(py_args);
128 FATAL("Failed to convert arguments");
129
130 }
131
132 PyTuple_SetItem(py_args, 0, py_value);
133
134 py_value = PyObject_CallObject(
135 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_DESCRIBE], py_args);
136
137 Py_DECREF(py_args);
138
139 if (py_value != NULL) { return PyBytes_AsString(py_value); }
140
141 return NULL;
142
143 }
144
init_py_module(afl_state_t * afl,u8 * module_name)145 static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
146
147 (void)afl;
148
149 if (!module_name) { return NULL; }
150
151 py_mutator_t *py = calloc(1, sizeof(py_mutator_t));
152 if (!py) { PFATAL("Could not allocate memory for python mutator!"); }
153
154 Py_Initialize();
155
156 #if PY_MAJOR_VERSION >= 3
157 PyObject *py_name = PyUnicode_FromString(module_name);
158 #else
159 PyObject *py_name = PyString_FromString(module_name);
160 #endif
161
162 py->py_module = PyImport_Import(py_name);
163 Py_DECREF(py_name);
164
165 PyObject * py_module = py->py_module;
166 PyObject **py_functions = py->py_functions;
167
168 // initialize the post process buffer; ensures it's always valid
169 PyObject *unused_bytes = PyByteArray_FromStringAndSize("OHAI", 4);
170 if (!unused_bytes) { FATAL("allocation failed!"); }
171 if (PyObject_GetBuffer(unused_bytes, &py->post_process_buf, PyBUF_SIMPLE) ==
172 -1) {
173
174 FATAL("buffer initialization failed");
175
176 }
177
178 Py_DECREF(unused_bytes);
179
180 if (py_module != NULL) {
181
182 u8 py_notrim = 0, py_idx;
183 /* init, required */
184 py_functions[PY_FUNC_INIT] = PyObject_GetAttrString(py_module, "init");
185 if (!py_functions[PY_FUNC_INIT])
186 FATAL("init function not found in python module");
187 py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz");
188 if (!py_functions[PY_FUNC_FUZZ])
189 py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "mutate");
190 py_functions[PY_FUNC_DESCRIBE] =
191 PyObject_GetAttrString(py_module, "describe");
192 py_functions[PY_FUNC_FUZZ_COUNT] =
193 PyObject_GetAttrString(py_module, "fuzz_count");
194 if (!py_functions[PY_FUNC_FUZZ])
195 WARNF("fuzz function not found in python module");
196 py_functions[PY_FUNC_POST_PROCESS] =
197 PyObject_GetAttrString(py_module, "post_process");
198 py_functions[PY_FUNC_INIT_TRIM] =
199 PyObject_GetAttrString(py_module, "init_trim");
200 py_functions[PY_FUNC_POST_TRIM] =
201 PyObject_GetAttrString(py_module, "post_trim");
202 py_functions[PY_FUNC_TRIM] = PyObject_GetAttrString(py_module, "trim");
203 py_functions[PY_FUNC_HAVOC_MUTATION] =
204 PyObject_GetAttrString(py_module, "havoc_mutation");
205 py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY] =
206 PyObject_GetAttrString(py_module, "havoc_mutation_probability");
207 py_functions[PY_FUNC_QUEUE_GET] =
208 PyObject_GetAttrString(py_module, "queue_get");
209 py_functions[PY_FUNC_QUEUE_NEW_ENTRY] =
210 PyObject_GetAttrString(py_module, "queue_new_entry");
211 py_functions[PY_FUNC_INTROSPECTION] =
212 PyObject_GetAttrString(py_module, "introspection");
213 py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit");
214 if (!py_functions[PY_FUNC_DEINIT])
215 WARNF("deinit function not found in python module");
216
217 for (py_idx = 0; py_idx < PY_FUNC_COUNT; ++py_idx) {
218
219 if (!py_functions[py_idx] || !PyCallable_Check(py_functions[py_idx])) {
220
221 if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) {
222
223 // Implementing the trim API is optional for now
224 if (PyErr_Occurred()) { PyErr_Print(); }
225 py_notrim = 1;
226
227 } else if (py_idx >= PY_OPTIONAL) {
228
229 // Only _init and _deinit are not optional currently
230
231 if (PyErr_Occurred()) { PyErr_Print(); }
232
233 } else {
234
235 fprintf(stderr,
236 "Cannot find/call function with index %d in external "
237 "Python module.\n",
238 py_idx);
239 return NULL;
240
241 }
242
243 }
244
245 }
246
247 if (py_notrim) {
248
249 py_functions[PY_FUNC_INIT_TRIM] = NULL;
250 py_functions[PY_FUNC_POST_TRIM] = NULL;
251 py_functions[PY_FUNC_TRIM] = NULL;
252 WARNF(
253 "Python module does not implement trim API, standard trimming will "
254 "be used.");
255
256 }
257
258 } else {
259
260 PyErr_Print();
261 fprintf(stderr, "Failed to load \"%s\"\n", module_name);
262 free(py);
263 return NULL;
264
265 }
266
267 return py;
268
269 }
270
finalize_py_module(void * py_mutator)271 void finalize_py_module(void *py_mutator) {
272
273 py_mutator_t *py = (py_mutator_t *)py_mutator;
274
275 if (py->py_module != NULL) {
276
277 deinit_py(py_mutator);
278
279 u32 i;
280 for (i = 0; i < PY_FUNC_COUNT; ++i) {
281
282 Py_XDECREF(py->py_functions[i]);
283
284 }
285
286 Py_DECREF(py->py_module);
287
288 }
289
290 Py_Finalize();
291
292 }
293
init_py(afl_state_t * afl,py_mutator_t * py_mutator,unsigned int seed)294 static void init_py(afl_state_t *afl, py_mutator_t *py_mutator,
295 unsigned int seed) {
296
297 (void)afl;
298
299 PyObject *py_args, *py_value;
300
301 /* Provide the init function a seed for the Python RNG */
302 py_args = PyTuple_New(1);
303 #if PY_MAJOR_VERSION >= 3
304 py_value = PyLong_FromLong(seed);
305 #else
306 py_value = PyInt_FromLong(seed);
307 #endif
308
309 if (!py_value) {
310
311 Py_DECREF(py_args);
312 FATAL("Cannot convert argument in python init.");
313
314 }
315
316 PyTuple_SetItem(py_args, 0, py_value);
317
318 py_value =
319 PyObject_CallObject(py_mutator->py_functions[PY_FUNC_INIT], py_args);
320
321 Py_DECREF(py_args);
322
323 if (py_value == NULL) {
324
325 PyErr_Print();
326 fprintf(stderr, "Call failed\n");
327 FATAL("Custom py mutator INIT failed.");
328
329 }
330
331 }
332
deinit_py(void * py_mutator)333 void deinit_py(void *py_mutator) {
334
335 PyObject *py_args, *py_value;
336
337 py_args = PyTuple_New(0);
338 py_value = PyObject_CallObject(
339 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_DEINIT], py_args);
340 Py_DECREF(py_args);
341
342 if (py_value != NULL) {
343
344 Py_DECREF(py_value);
345
346 } else {
347
348 PyErr_Print();
349 FATAL("Call failed");
350
351 }
352
353 }
354
load_custom_mutator_py(afl_state_t * afl,char * module_name)355 struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
356 char * module_name) {
357
358 struct custom_mutator *mutator;
359
360 mutator = ck_alloc(sizeof(struct custom_mutator));
361
362 mutator->name = module_name;
363 ACTF("Loading Python mutator library from '%s'...", module_name);
364
365 py_mutator_t *py_mutator;
366 py_mutator = init_py_module(afl, module_name);
367 mutator->data = py_mutator;
368 if (!py_mutator) { FATAL("Failed to load python mutator."); }
369
370 PyObject **py_functions = py_mutator->py_functions;
371
372 if (py_functions[PY_FUNC_INIT]) { mutator->afl_custom_init = unsupported; }
373
374 if (py_functions[PY_FUNC_DEINIT]) { mutator->afl_custom_deinit = deinit_py; }
375
376 if (py_functions[PY_FUNC_FUZZ]) { mutator->afl_custom_fuzz = fuzz_py; }
377
378 if (py_functions[PY_FUNC_DESCRIBE]) {
379
380 mutator->afl_custom_describe = custom_describe_py;
381
382 }
383
384 if (py_functions[PY_FUNC_POST_PROCESS]) {
385
386 mutator->afl_custom_post_process = post_process_py;
387
388 }
389
390 if (py_functions[PY_FUNC_INIT_TRIM]) {
391
392 mutator->afl_custom_init_trim = init_trim_py;
393
394 }
395
396 if (py_functions[PY_FUNC_FUZZ_COUNT]) {
397
398 mutator->afl_custom_fuzz_count = fuzz_count_py;
399
400 }
401
402 if (py_functions[PY_FUNC_POST_TRIM]) {
403
404 mutator->afl_custom_post_trim = post_trim_py;
405
406 }
407
408 if (py_functions[PY_FUNC_TRIM]) { mutator->afl_custom_trim = trim_py; }
409
410 if (py_functions[PY_FUNC_HAVOC_MUTATION]) {
411
412 mutator->afl_custom_havoc_mutation = havoc_mutation_py;
413
414 }
415
416 if (py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY]) {
417
418 mutator->afl_custom_havoc_mutation_probability =
419 havoc_mutation_probability_py;
420
421 }
422
423 if (py_functions[PY_FUNC_QUEUE_GET]) {
424
425 mutator->afl_custom_queue_get = queue_get_py;
426
427 }
428
429 if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY]) {
430
431 mutator->afl_custom_queue_new_entry = queue_new_entry_py;
432
433 }
434
435 #ifdef INTROSPECTION
436 if (py_functions[PY_FUNC_INTROSPECTION]) {
437
438 mutator->afl_custom_introspection = introspection_py;
439
440 }
441
442 #endif
443
444 OKF("Python mutator '%s' installed successfully.", module_name);
445
446 /* Initialize the custom mutator */
447 init_py(afl, py_mutator, rand_below(afl, 0xFFFFFFFF));
448
449 mutator->stacked_custom = (mutator && mutator->afl_custom_havoc_mutation);
450 mutator->stacked_custom_prob =
451 6; // like one of the default mutations in havoc
452
453 return mutator;
454
455 }
456
post_process_py(void * py_mutator,u8 * buf,size_t buf_size,u8 ** out_buf)457 size_t post_process_py(void *py_mutator, u8 *buf, size_t buf_size,
458 u8 **out_buf) {
459
460 PyObject * py_args, *py_value;
461 py_mutator_t *py = (py_mutator_t *)py_mutator;
462
463 // buffer returned previously must be released; initialized during init
464 // so we don't need to do comparisons
465 PyBuffer_Release(&py->post_process_buf);
466
467 py_args = PyTuple_New(1);
468 py_value = PyByteArray_FromStringAndSize(buf, buf_size);
469 if (!py_value) {
470
471 Py_DECREF(py_args);
472 FATAL("Failed to convert arguments in custom post_process");
473
474 }
475
476 PyTuple_SetItem(py_args, 0, py_value);
477
478 py_value = PyObject_CallObject(
479 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_PROCESS],
480 py_args);
481
482 Py_DECREF(py_args);
483
484 if (py_value != NULL) {
485
486 if (PyObject_GetBuffer(py_value, &py->post_process_buf, PyBUF_SIMPLE) ==
487 -1) {
488
489 PyErr_Print();
490 FATAL(
491 "Python custom mutator: post_process call return value not a "
492 "bytes-like object");
493
494 }
495
496 Py_DECREF(py_value);
497
498 *out_buf = (u8 *)py->post_process_buf.buf;
499 return py->post_process_buf.len;
500
501 } else {
502
503 PyErr_Print();
504 FATAL("Python custom mutator: post_process call failed.");
505
506 }
507
508 }
509
init_trim_py(void * py_mutator,u8 * buf,size_t buf_size)510 s32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) {
511
512 PyObject *py_args, *py_value;
513
514 py_args = PyTuple_New(1);
515 py_value = PyByteArray_FromStringAndSize(buf, buf_size);
516 if (!py_value) {
517
518 Py_DECREF(py_args);
519 FATAL("Failed to convert arguments");
520
521 }
522
523 PyTuple_SetItem(py_args, 0, py_value);
524
525 py_value = PyObject_CallObject(
526 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INIT_TRIM], py_args);
527 Py_DECREF(py_args);
528
529 if (py_value != NULL) {
530
531 #if PY_MAJOR_VERSION >= 3
532 u32 retcnt = (u32)PyLong_AsLong(py_value);
533 #else
534 u32 retcnt = PyInt_AsLong(py_value);
535 #endif
536 Py_DECREF(py_value);
537 return retcnt;
538
539 } else {
540
541 PyErr_Print();
542 FATAL("Call failed");
543
544 }
545
546 }
547
fuzz_count_py(void * py_mutator,const u8 * buf,size_t buf_size)548 u32 fuzz_count_py(void *py_mutator, const u8 *buf, size_t buf_size) {
549
550 PyObject *py_args, *py_value;
551
552 py_args = PyTuple_New(1);
553 py_value = PyByteArray_FromStringAndSize(buf, buf_size);
554 if (!py_value) {
555
556 Py_DECREF(py_args);
557 FATAL("Failed to convert arguments");
558
559 }
560
561 PyTuple_SetItem(py_args, 0, py_value);
562
563 py_value = PyObject_CallObject(
564 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ_COUNT], py_args);
565 Py_DECREF(py_args);
566
567 if (py_value != NULL) {
568
569 #if PY_MAJOR_VERSION >= 3
570 u32 retcnt = (u32)PyLong_AsLong(py_value);
571 #else
572 u32 retcnt = PyInt_AsLong(py_value);
573 #endif
574 Py_DECREF(py_value);
575 return retcnt;
576
577 } else {
578
579 PyErr_Print();
580 FATAL("Call failed");
581
582 }
583
584 }
585
post_trim_py(void * py_mutator,u8 success)586 s32 post_trim_py(void *py_mutator, u8 success) {
587
588 PyObject *py_args, *py_value;
589
590 py_args = PyTuple_New(1);
591
592 py_value = PyBool_FromLong(success);
593 if (!py_value) {
594
595 Py_DECREF(py_args);
596 FATAL("Failed to convert arguments");
597
598 }
599
600 PyTuple_SetItem(py_args, 0, py_value);
601
602 py_value = PyObject_CallObject(
603 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_TRIM], py_args);
604 Py_DECREF(py_args);
605
606 if (py_value != NULL) {
607
608 #if PY_MAJOR_VERSION >= 3
609 u32 retcnt = (u32)PyLong_AsLong(py_value);
610 #else
611 u32 retcnt = PyInt_AsLong(py_value);
612 #endif
613 Py_DECREF(py_value);
614 return retcnt;
615
616 } else {
617
618 PyErr_Print();
619 FATAL("Call failed");
620
621 }
622
623 }
624
trim_py(void * py_mutator,u8 ** out_buf)625 size_t trim_py(void *py_mutator, u8 **out_buf) {
626
627 PyObject *py_args, *py_value;
628 size_t ret;
629
630 py_args = PyTuple_New(0);
631 py_value = PyObject_CallObject(
632 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_TRIM], py_args);
633 Py_DECREF(py_args);
634
635 if (py_value != NULL) {
636
637 ret = PyByteArray_Size(py_value);
638 *out_buf = afl_realloc(BUF_PARAMS(trim), ret);
639 if (unlikely(!*out_buf)) { PFATAL("alloc"); }
640 memcpy(*out_buf, PyByteArray_AsString(py_value), ret);
641 Py_DECREF(py_value);
642
643 } else {
644
645 PyErr_Print();
646 FATAL("Call failed");
647
648 }
649
650 return ret;
651
652 }
653
havoc_mutation_py(void * py_mutator,u8 * buf,size_t buf_size,u8 ** out_buf,size_t max_size)654 size_t havoc_mutation_py(void *py_mutator, u8 *buf, size_t buf_size,
655 u8 **out_buf, size_t max_size) {
656
657 size_t mutated_size;
658 PyObject *py_args, *py_value;
659 py_args = PyTuple_New(2);
660
661 /* buf */
662 py_value = PyByteArray_FromStringAndSize(buf, buf_size);
663 if (!py_value) {
664
665 Py_DECREF(py_args);
666 FATAL("Failed to convert arguments");
667
668 }
669
670 PyTuple_SetItem(py_args, 0, py_value);
671
672 /* max_size */
673 #if PY_MAJOR_VERSION >= 3
674 py_value = PyLong_FromLong(max_size);
675 #else
676 py_value = PyInt_FromLong(max_size);
677 #endif
678 if (!py_value) {
679
680 Py_DECREF(py_args);
681 FATAL("Failed to convert arguments");
682
683 }
684
685 PyTuple_SetItem(py_args, 1, py_value);
686
687 py_value = PyObject_CallObject(
688 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION],
689 py_args);
690
691 Py_DECREF(py_args);
692
693 if (py_value != NULL) {
694
695 mutated_size = PyByteArray_Size(py_value);
696 if (mutated_size <= buf_size) {
697
698 /* We reuse the input buf here. */
699 *out_buf = buf;
700
701 } else {
702
703 /* A new buf is needed... */
704 *out_buf = afl_realloc(BUF_PARAMS(havoc), mutated_size);
705 if (unlikely(!*out_buf)) { PFATAL("alloc"); }
706
707 }
708
709 memcpy(*out_buf, PyByteArray_AsString(py_value), mutated_size);
710
711 Py_DECREF(py_value);
712 return mutated_size;
713
714 } else {
715
716 PyErr_Print();
717 FATAL("Call failed");
718
719 }
720
721 }
722
havoc_mutation_probability_py(void * py_mutator)723 u8 havoc_mutation_probability_py(void *py_mutator) {
724
725 PyObject *py_args, *py_value;
726
727 py_args = PyTuple_New(0);
728 py_value = PyObject_CallObject(
729 ((py_mutator_t *)py_mutator)
730 ->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY],
731 py_args);
732 Py_DECREF(py_args);
733
734 if (py_value != NULL) {
735
736 long prob = PyLong_AsLong(py_value);
737 Py_DECREF(py_value);
738 return (u8)prob;
739
740 } else {
741
742 PyErr_Print();
743 FATAL("Call failed");
744
745 }
746
747 }
748
introspection_py(void * py_mutator)749 const char *introspection_py(void *py_mutator) {
750
751 PyObject *py_args, *py_value;
752
753 py_args = PyTuple_New(0);
754 py_value = PyObject_CallObject(
755 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INTROSPECTION],
756 py_args);
757 Py_DECREF(py_args);
758
759 if (py_value == NULL) {
760
761 return NULL;
762
763 } else {
764
765 return PyByteArray_AsString(py_value);
766
767 }
768
769 }
770
queue_get_py(void * py_mutator,const u8 * filename)771 u8 queue_get_py(void *py_mutator, const u8 *filename) {
772
773 PyObject *py_args, *py_value;
774
775 py_args = PyTuple_New(1);
776
777 // File name
778 #if PY_MAJOR_VERSION >= 3
779 py_value = PyUnicode_FromString(filename);
780 #else
781 py_value = PyString_FromString(filename);
782 #endif
783 if (!py_value) {
784
785 Py_DECREF(py_args);
786 FATAL("Failed to convert arguments");
787
788 }
789
790 PyTuple_SetItem(py_args, 0, py_value);
791
792 // Call Python function
793 py_value = PyObject_CallObject(
794 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_GET], py_args);
795 Py_DECREF(py_args);
796
797 if (py_value != NULL) {
798
799 int ret = PyObject_IsTrue(py_value);
800 Py_DECREF(py_value);
801
802 if (ret == -1) {
803
804 PyErr_Print();
805 FATAL("Failed to convert return value");
806
807 }
808
809 return (u8)ret & 0xFF;
810
811 } else {
812
813 PyErr_Print();
814 FATAL("Call failed");
815
816 }
817
818 }
819
queue_new_entry_py(void * py_mutator,const u8 * filename_new_queue,const u8 * filename_orig_queue)820 u8 queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue,
821 const u8 *filename_orig_queue) {
822
823 PyObject *py_args, *py_value;
824
825 py_args = PyTuple_New(2);
826
827 // New queue
828 #if PY_MAJOR_VERSION >= 3
829 py_value = PyUnicode_FromString(filename_new_queue);
830 #else
831 py_value = PyString_FromString(filename_new_queue);
832 #endif
833 if (!py_value) {
834
835 Py_DECREF(py_args);
836 FATAL("Failed to convert arguments");
837
838 }
839
840 PyTuple_SetItem(py_args, 0, py_value);
841
842 // Orig queue
843 py_value = Py_None;
844 if (filename_orig_queue) {
845
846 #if PY_MAJOR_VERSION >= 3
847 py_value = PyUnicode_FromString(filename_orig_queue);
848 #else
849 py_value = PyString_FromString(filename_orig_queue);
850 #endif
851 if (!py_value) {
852
853 Py_DECREF(py_args);
854 FATAL("Failed to convert arguments");
855
856 }
857
858 }
859
860 PyTuple_SetItem(py_args, 1, py_value);
861
862 // Call
863 py_value = PyObject_CallObject(
864 ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_NEW_ENTRY],
865 py_args);
866 Py_DECREF(py_args);
867
868 if (py_value != NULL) {
869
870 int ret = PyObject_IsTrue(py_value);
871 Py_DECREF(py_value);
872
873 if (ret == -1) {
874
875 PyErr_Print();
876 FATAL("Failed to convert return value");
877
878 }
879
880 return (u8)ret & 0xFF;
881
882 } else {
883
884 PyErr_Print();
885 FATAL("Call failed");
886
887 }
888
889 }
890
891 #undef BUF_PARAMS
892
893 #endif /* USE_PYTHON */
894
895