/
niceSOFT
/
swig
Обзор
Документация
Войти
/
niceSOFT
/
swig
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Lib/python/argcargv.i
107 строк
3 KB
William S Fulton
argcargv / OOM-protection follow-ups
19 май 2026, 23:01
19 май 2026, 23:01
a1e619b
Код
Авторство
О чём код?
/* ------------------------------------------------------------- * SWIG library containing argc and argv multi-argument typemaps * ------------------------------------------------------------- */ %fragment("SWIG_AsArgcArgv", "header", fragment="SWIG_AsCharPtrAndSize") { SWIGINTERN int SWIG_AsArgcArgv(PyObject *input, swig_type_info *ppchar_info, size_t *argc, char ***argv, int *owner) { void *vptr; int res = SWIG_ConvertPtr(input, &vptr, ppchar_info, 0); if (SWIG_IsOK(res)) { /* seems dangerous, but the user asked for it... */ size_t i = 0; if (argv && *argv) { while ((*argv)[i] != 0) ++i; } if (argc) *argc = i; if (owner) *owner = 0; return SWIG_OK; } PyErr_Clear(); int is_list = PyList_Check(input); if (!is_list && !PyTuple_Check(input)) return SWIG_TypeError; size_t i; res = SWIG_OK; size_t size = is_list ? PyList_Size(input) : PyTuple_Size(input); if (argv != NULL) { char **p = %new_array(size + 1, char*); if (p == NULL) { SWIG_Error(SWIG_MemoryError, "Failed to allocate memory for 'int ARGC, char **ARGV'"); return SWIG_ERROR; } *argv = p; } for (i = 0; i < size; ++i) { /* Thread safety: a list could be modified by another thread while this function is running, causing its elements to get dereferenced between PyList_GetItem and SWIG_AsCharPtrAndSize, resulting in a segfault. tuples are immutable, so this is not an issue for them. */ PyObject *obj = is_list ? SWIG_PyList_GetItemRef(input, i) : PyTuple_GetItem(input, i); if (!obj) { /* List was shrunk by another thread. Return early with SWIG_OK. */ PyErr_Clear(); break; } if (argv) { char *cptr = 0; size_t sz = 0; int alloc = 0; res = SWIG_AsCharPtrAndSize(obj, &cptr, &sz, &alloc); if (SWIG_IsOK(res)) { if (cptr && sz) { if (alloc == SWIG_NEWOBJ) { (*argv)[i] = cptr; } else { char *p = %new_array(sz, char); if (p == NULL) { SWIG_Error(SWIG_MemoryError, "Failed to allocate string for 'int ARGC, char **ARGV'"); (*argv)[i] = 0; res = SWIG_MemoryError; } else { memcpy(p, cptr, sz); (*argv)[i] = p; } } } else { (*argv)[i] = 0; } } } else { res = SWIG_AsCharPtrAndSize(obj, 0, 0, 0); } if (is_list) Py_DECREF(obj); if (!SWIG_IsOK(res)) break; } if (argc) *argc = i; // Covers early exits from for loop if (argv) (*argv)[i] = 0; if (owner) *owner = 1; return res; } } /* This typemap works with either a char **, a python list or a python tuple */ %typemap(in,noblock=0,fragment="SWIG_AsArgcArgv") (int ARGC, char **ARGV) (int res,char **argv = 0, size_t argc = 0, int owner= 0) { res = SWIG_AsArgcArgv($input, $descriptor(char**), &argc, &argv, &owner); if (!SWIG_IsOK(res)) { $1 = 0; $2 = 0; %argument_fail(SWIG_TypeError, "int ARGC, char **ARGV", $symname, $argnum); } else { $1 = %static_cast(argc,$1_ltype); $2 = %static_cast(argv, $2_ltype); } } %typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) { int res = SWIG_AsArgcArgv($input, $descriptor(char**), 0, 0, 0); $1 = SWIG_IsOK(res); } %typemap(freearg,noblock=1) (int ARGC, char **ARGV) { if (owner$argnum) { size_t i = argc$argnum; while (i) %delete_array(argv$argnum[--i]); %delete_array(argv$argnum); } }