int nacl_main(int argc, char **argv) { if (nacl_startup_untar(argv[0], DATA_FILE, "/")) return -1; wchar_t **argv_copy; /* We need a second copy, as Python might modify the first one. */ wchar_t **argv_copy2; int i, res; char *oldloc; #ifdef __FreeBSD__ fp_except_t m; #endif argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1)); argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1)); if (!argv_copy || !argv_copy2) { fprintf(stderr, "out of memory\n"); return 1; } /* 754 requires that FP exceptions run in "no stop" mode by default, * and until C vendors implement C99's ways to control FP exceptions, * Python requires non-stop mode. Alas, some platforms enable FP * exceptions by default. Here we disable them. */ #ifdef __FreeBSD__ m = fpgetmask(); fpsetmask(m & ~FP_X_OFL); #endif oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); if (!oldloc) { fprintf(stderr, "out of memory\n"); return 1; } setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy[i] = _Py_char2wchar(argv[i], NULL); if (!argv_copy[i]) { PyMem_RawFree(oldloc); fprintf(stderr, "Fatal Python error: " "unable to decode the command line argument #%i\n", i + 1); return 1; } argv_copy2[i] = argv_copy[i]; } argv_copy2[argc] = argv_copy[argc] = NULL; setlocale(LC_ALL, oldloc); PyMem_RawFree(oldloc); res = Py_Main(argc, argv_copy); for (i = 0; i < argc; i++) { PyMem_RawFree(argv_copy2[i]); } PyMem_RawFree(argv_copy); PyMem_RawFree(argv_copy2); return res; }
static PyThreadState * new_threadstate(PyInterpreterState *interp, int init) { PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); if (_PyThreadState_GetFrame == NULL) _PyThreadState_GetFrame = threadstate_getframe; if (tstate != NULL) { tstate->interp = interp; tstate->frame = NULL; tstate->recursion_depth = 0; tstate->overflowed = 0; tstate->recursion_critical = 0; tstate->tracing = 0; tstate->use_tracing = 0; tstate->tick_counter = 0; tstate->gilstate_counter = 0; tstate->async_exc = NULL; #ifdef WITH_THREAD tstate->thread_id = PyThread_get_thread_ident(); #else tstate->thread_id = 0; #endif tstate->dict = NULL; tstate->curexc_type = NULL; tstate->curexc_value = NULL; tstate->curexc_traceback = NULL; tstate->exc_type = NULL; tstate->exc_value = NULL; tstate->exc_traceback = NULL; tstate->c_profilefunc = NULL; tstate->c_tracefunc = NULL; tstate->c_profileobj = NULL; tstate->c_traceobj = NULL; tstate->trash_delete_nesting = 0; tstate->trash_delete_later = NULL; tstate->on_delete = NULL; tstate->on_delete_data = NULL; if (init) _PyThreadState_Init(tstate); HEAD_LOCK(); tstate->prev = NULL; tstate->next = interp->tstate_head; if (tstate->next) tstate->next->prev = tstate; interp->tstate_head = tstate; HEAD_UNLOCK(); } return tstate; }
static wchar_t* Py_DecodeLocale(const char* arg, size_t*) { size_t argsize = mbstowcs(NULL, arg, 0); if (argsize == (size_t)-1) { return NULL; } if (argsize == PY_SSIZE_T_MAX) { return NULL; } if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t)) { return NULL; } wchar_t *res = (wchar_t *)PyMem_RawMalloc(argsize*sizeof(wchar_t)); if (!res) { return NULL; } size_t count = mbstowcs(res, arg, argsize); if (count != (size_t)-1) { wchar_t *tmp; for (tmp = res; *tmp != 0 && !Py_UNICODE_IS_SURROGATE(*tmp); tmp++) { } if (*tmp == 0) { return res; } } PyMem_RawFree(res); return NULL; }
static PyObject * overlapped_RegisterWaitWithQueue(PyObject *self, PyObject *args) { HANDLE NewWaitObject; HANDLE Object; ULONG Milliseconds; struct PostCallbackData data, *pdata; if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE F_POINTER F_DWORD, &Object, &data.CompletionPort, &data.Overlapped, &Milliseconds)) return NULL; /* Use PyMem_RawMalloc() rather than PyMem_Malloc(), since PostToQueueCallback() will call PyMem_Free() from a new C thread which doesn't hold the GIL. */ pdata = PyMem_RawMalloc(sizeof(struct PostCallbackData)); if (pdata == NULL) return SetFromWindowsErr(0); *pdata = data; if (!RegisterWaitForSingleObject( &NewWaitObject, Object, (WAITORTIMERCALLBACK)PostToQueueCallback, pdata, Milliseconds, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { PyMem_RawFree(pdata); return SetFromWindowsErr(0); } return Py_BuildValue(F_HANDLE, NewWaitObject); }
static wchar_t* wstrlist_join(wchar_t sep, int count, wchar_t **list) { size_t len = 1; /* NUL terminator */ for (int i=0; i < count; i++) { if (i != 0) { len++; } len += wcslen(list[i]); } wchar_t *text = PyMem_RawMalloc(len * sizeof(wchar_t)); if (text == NULL) { return NULL; } wchar_t *str = text; for (int i=0; i < count; i++) { wchar_t *path = list[i]; if (i != 0) { *str++ = SEP; } len = wcslen(path); memcpy(str, path, len * sizeof(wchar_t)); str += len; } *str = L'\0'; return text; }
static wchar_t* decode_ascii_surrogateescape(const char *arg, size_t *size) { wchar_t *res; unsigned char *in; wchar_t *out; size_t argsize = strlen(arg) + 1; if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t)) return NULL; res = PyMem_RawMalloc(argsize*sizeof(wchar_t)); if (!res) return NULL; in = (unsigned char*)arg; out = res; while(*in) if(*in < 128) *out++ = *in++; else *out++ = 0xdc00 + *in++; *out = 0; if (size != NULL) *size = out - res; return res; }
static int elObj_rprompt_setter(EditLineObject *self, PyObject *value, void *closure) { int rv = 0; int n; char *new_rprompt; const char *encoded_c; PyObject *encoded; if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete the rprompt attribute"); return -1; } if (! PyUnicode_Check(value)) { PyErr_SetString(PyExc_TypeError, "The rprompt attribute value must be a string"); return -1; } /* it is stored as a C string */ encoded = encode(value); if (encoded == NULL) { PyErr_SetString(PyExc_ValueError, "The rprompt attribute could not be encoded"); return -1; } /* get it as a c-string */ encoded_c = PyBytes_AS_STRING(encoded); n = strlen(encoded_c); /* create a RawMalloc'd buffer */ new_rprompt = PyMem_RawMalloc(n+1); if (new_rprompt == NULL) { Py_DECREF(encoded); PyErr_NoMemory(); return -1; } /* Copy the malloc'ed buffer into a PyMem_Malloc'ed one. */ strncpy(new_rprompt, encoded_c, n); new_rprompt[n] = '\0'; /* release the previous one if it was assigned */ if (self->rprompt) PyMem_RawFree(self->rprompt); /* make this the active one */ self->rprompt = new_rprompt; /* * REFs: only manage 'enc' to ensure it gets removed. We don't 'own' * any of the others, so we just borrow the ref. */ Py_DECREF(encoded); /* done */ return rv; }
PyInterpreterState * PyInterpreterState_New(void) { PyInterpreterState *interp = (PyInterpreterState *) PyMem_RawMalloc(sizeof(PyInterpreterState)); if (interp != NULL) { HEAD_INIT(); #ifdef WITH_THREAD if (head_mutex == NULL) Py_FatalError("Can't initialize threads for interpreter"); #endif interp->modules = NULL; interp->modules_by_index = NULL; interp->sysdict = NULL; interp->builtins = NULL; interp->builtins_copy = NULL; interp->tstate_head = NULL; interp->codec_search_path = NULL; interp->codec_search_cache = NULL; interp->codec_error_registry = NULL; interp->codecs_initialized = 0; interp->fscodec_initialized = 0; interp->importlib = NULL; interp->import_func = NULL; interp->eval_frame = _PyEval_EvalFrameDefault; #ifdef HAVE_DLOPEN #if HAVE_DECL_RTLD_NOW interp->dlopenflags = RTLD_NOW; #else interp->dlopenflags = RTLD_LAZY; #endif #endif #ifdef HAVE_FORK interp->before_forkers = NULL; interp->after_forkers_parent = NULL; interp->after_forkers_child = NULL; #endif HEAD_LOCK(); interp->next = interp_head; if (interp_main == NULL) { interp_main = interp; } interp_head = interp; if (_next_interp_id < 0) { /* overflow or Py_Initialize() not called! */ PyErr_SetString(PyExc_RuntimeError, "failed to get an interpreter ID"); interp = NULL; } else { interp->id = _next_interp_id; _next_interp_id += 1; } HEAD_UNLOCK(); } return interp; }
static void* PyLzma_Malloc(void *opaque, size_t items, size_t size) { if (items > (size_t)PY_SSIZE_T_MAX / size) return NULL; /* PyMem_Malloc() cannot be used: the GIL is not held when lzma_code() is called */ return PyMem_RawMalloc(items * size); }
static int encode_ascii(const wchar_t *text, char **str, size_t *error_pos, const char **reason, int raw_malloc, int surrogateescape) { char *result = NULL, *out; size_t len, i; wchar_t ch; len = wcslen(text); /* +1 for NULL byte */ if (raw_malloc) { result = PyMem_RawMalloc(len + 1); } else { result = PyMem_Malloc(len + 1); } if (result == NULL) { return -1; } out = result; for (i=0; i<len; i++) { ch = text[i]; if (ch <= 0x7f) { /* ASCII character */ *out++ = (char)ch; } else if (surrogateescape && 0xdc80 <= ch && ch <= 0xdcff) { /* UTF-8b surrogate */ *out++ = (char)(ch - 0xdc00); } else { if (raw_malloc) { PyMem_RawFree(result); } else { PyMem_Free(result); } if (error_pos != NULL) { *error_pos = i; } if (reason) { *reason = "encoding error"; } return -2; } } *out = '\0'; *str = result; return 0; }
static int _register_xidata(PyTypeObject *cls, crossinterpdatafunc getdata) { // Note that we effectively replace already registered classes // rather than failing. struct _xidregitem *newhead = PyMem_RawMalloc(sizeof(struct _xidregitem)); if (newhead == NULL) return -1; newhead->cls = cls; newhead->getdata = getdata; newhead->next = _PyRuntime.xidregistry.head; _PyRuntime.xidregistry.head = newhead; return 0; }
void Py_SetPath(const wchar_t *path) { if (module_search_path != NULL) { PyMem_RawFree(module_search_path); module_search_path = NULL; } if (path != NULL) { extern wchar_t *Py_GetProgramName(void); wchar_t *prog = Py_GetProgramName(); wcsncpy(progpath, prog, MAXPATHLEN); prefix[0] = L'\0'; module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t)); if (module_search_path != NULL) wcscpy(module_search_path, path); } }
static int decode_ascii(const char *arg, wchar_t **wstr, size_t *wlen, const char **reason, int surrogateescape) { wchar_t *res; unsigned char *in; wchar_t *out; size_t argsize = strlen(arg) + 1; if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t)) { return -1; } res = PyMem_RawMalloc(argsize * sizeof(wchar_t)); if (!res) { return -1; } out = res; for (in = (unsigned char*)arg; *in; in++) { unsigned char ch = *in; if (ch < 128) { *out++ = ch; } else { if (!surrogateescape) { PyMem_RawFree(res); if (wlen) { *wlen = in - (unsigned char*)arg; } if (reason) { *reason = "decoding error"; } return -2; } *out++ = 0xdc00 + ch; } } *out = 0; if (wlen != NULL) { *wlen = out - res; } *wstr = res; return 0; }
/* * Python's entry point to this module */ static char * call_editline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) { char *p; PyOS_sighandler_t old_inthandler; EditLineObject *el_gi = editline_module_state->global_instance; /* init missing... */ if (el_gi == NULL) { PyErr_SetString(PyExc_SystemError, "invalid editline global instance"); return NULL; } /* don't do the allocation unless it is different... */ if (strncmp(prompt, el_gi->prompt, strlen(prompt)) != 0) { p = PyMem_RawMalloc(strlen(prompt)+1); if (p == NULL) { PyErr_NoMemory(); return NULL; } strcpy(p, prompt); if (el_gi->prompt != NULL) PyMem_RawFree(el_gi->prompt); el_gi->prompt = p; } /* * this seems like a hack, although it is from readline.c * but it gets around a '\n' needed to interpret a ^C signal */ old_inthandler = PyOS_setsig(SIGINT, onintr); if (setjmp(jbuf)) { #ifdef HAVE_SIGRELSE /* This seems necessary on SunOS 4.1 (Rasmus Hahn) */ sigrelse(SIGINT); #endif PyOS_setsig(SIGINT, old_inthandler); return NULL; } /* interact with the user */ return common_line_interaction(el_gi); }
PyInterpreterState * PyInterpreterState_New(void) { PyInterpreterState *interp = (PyInterpreterState *) PyMem_RawMalloc(sizeof(PyInterpreterState)); if (interp != NULL) { HEAD_INIT(); #ifdef WITH_THREAD if (head_mutex == NULL) Py_FatalError("Can't initialize threads for interpreter"); #endif interp->modules = NULL; interp->modules_by_index = NULL; interp->sysdict = NULL; interp->builtins = NULL; interp->builtins_copy = NULL; interp->tstate_head = NULL; interp->codec_search_path = NULL; interp->codec_search_cache = NULL; interp->codec_error_registry = NULL; interp->codecs_initialized = 0; interp->fscodec_initialized = 0; interp->importlib = NULL; #ifdef HAVE_DLOPEN #ifdef RTLD_NOW interp->dlopenflags = RTLD_NOW; #else interp->dlopenflags = RTLD_LAZY; #endif #endif #ifdef WITH_TSC interp->tscdump = 0; #endif HEAD_LOCK(); interp->next = interp_head; interp_head = interp; HEAD_UNLOCK(); } return interp; }
/* Internal helper. * If the current thread has a mapping for key, the appropriate struct key* * is returned. NB: value is ignored in this case! * If there is no mapping for key in the current thread, then: * If value is NULL, NULL is returned. * Else a mapping of key to value is created for the current thread, * and a pointer to a new struct key* is returned; except that if * malloc() can't find room for a new struct key*, NULL is returned. * So when value==NULL, this acts like a pure lookup routine, and when * value!=NULL, this acts like dict.setdefault(), returning an existing * mapping if one exists, else creating a new mapping. * * Caution: this used to be too clever, trying to hold keymutex only * around the "p->next = keyhead; keyhead = p" pair. That allowed * another thread to mutate the list, via key deletion, concurrent with * find_key() crawling over the list. Hilarity ensued. For example, when * the for-loop here does "p = p->next", p could end up pointing at a * record that PyThread_delete_key_value() was concurrently free()'ing. * That could lead to anything, from failing to find a key that exists, to * segfaults. Now we lock the whole routine. */ static struct key * find_key(int set_value, int key, void *value) { struct key *p, *prev_p; long id = PyThread_get_thread_ident(); if (!keymutex) return NULL; PyThread_acquire_lock(keymutex, 1); prev_p = NULL; for (p = keyhead; p != NULL; p = p->next) { if (p->id == id && p->key == key) { if (set_value) p->value = value; goto Done; } /* Sanity check. These states should never happen but if * they do we must abort. Otherwise we'll end up spinning * in a tight loop with the lock held. A similar check is done * in pystate.c tstate_delete_common(). */ if (p == prev_p) Py_FatalError("tls find_key: small circular list(!)"); prev_p = p; if (p->next == keyhead) Py_FatalError("tls find_key: circular list(!)"); } if (!set_value && value == NULL) { assert(p == NULL); goto Done; } p = (struct key *)PyMem_RawMalloc(sizeof(struct key)); if (p != NULL) { p->id = id; p->key = key; p->value = value; p->next = keyhead; keyhead = p; } Done: PyThread_release_lock(keymutex); return p; }
static _PyInitError core_config_init_module_search_paths(_PyCoreConfig *config, _PyPathConfig *path_config) { assert(config->module_search_paths == NULL); assert(config->nmodule_search_path < 0); config->nmodule_search_path = 0; const wchar_t *sys_path = path_config->module_search_path; const wchar_t delim = DELIM; const wchar_t *p = sys_path; while (1) { p = wcschr(sys_path, delim); if (p == NULL) { p = sys_path + wcslen(sys_path); /* End of string */ } size_t path_len = (p - sys_path); wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t)); if (path == NULL) { return _Py_INIT_NO_MEMORY(); } memcpy(path, sys_path, path_len * sizeof(wchar_t)); path[path_len] = L'\0'; _PyInitError err = _Py_wstrlist_append(&config->nmodule_search_path, &config->module_search_paths, path); PyMem_RawFree(path); if (_Py_INIT_FAILED(err)) { return err; } if (*p == '\0') { break; } sys_path = p + 1; } return _Py_INIT_OK(); }
static char * call_readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) { size_t n; char *p, *q; int signal; #ifdef SAVE_LOCALE char *saved_locale = strdup(setlocale(LC_CTYPE, NULL)); if (!saved_locale) Py_FatalError("not enough memory to save locale"); setlocale(LC_CTYPE, ""); #endif if (sys_stdin != rl_instream || sys_stdout != rl_outstream) { rl_instream = sys_stdin; rl_outstream = sys_stdout; #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER rl_prep_terminal (1); #endif } p = readline_until_enter_or_signal(prompt, &signal); /* we got an interrupt signal */ if (signal) { RESTORE_LOCALE(saved_locale) return NULL; } /* We got an EOF, return an empty string. */ if (p == NULL) { p = PyMem_RawMalloc(1); if (p != NULL) *p = '\0'; RESTORE_LOCALE(saved_locale) return p; }
static _PyInitError get_program_full_path(const _PyCoreConfig *core_config, PyCalculatePath *calculate, _PyPathConfig *config) { const wchar_t *pyvenv_launcher; wchar_t program_full_path[MAXPATHLEN+1]; memset(program_full_path, 0, sizeof(program_full_path)); /* The launcher may need to force the executable path to a * different environment, so override it here. */ pyvenv_launcher = _wgetenv(L"__PYVENV_LAUNCHER__"); if (pyvenv_launcher && pyvenv_launcher[0]) { wcscpy_s(program_full_path, MAXPATHLEN+1, pyvenv_launcher); } else if (!GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) { /* GetModuleFileName should never fail when passed NULL */ return _Py_INIT_ERR("Cannot determine program path"); } config->program_full_path = PyMem_RawMalloc( sizeof(wchar_t) * (MAXPATHLEN + 1)); return canonicalize(config->program_full_path, program_full_path); }
Py_ssize_t PyUnicode_INDEX(const char *text, Py_ssize_t index) { PyObject *u; Py_ssize_t i; /* Prevent excessive micro allocations */ char buffer[256]; size_t buffer_size = Py_ARRAY_LENGTH(buffer); char *s = buffer; size_t l; /* Short-circuit */ if (index == 0) return 0; l = strlen(text); if (index > l) index = l; if (index >= buffer_size) { s = PyMem_RawMalloc(index+1); if (s == NULL) return -1; } strncpy(s, text, index); s[index] = '\0'; u = PyUnicode_DECODE(s); if (s != buffer) PyMem_RawFree(s); if (u == NULL) return -1; i = PyUnicode_GET_LENGTH(u); Py_DECREF(u); return i; }
static PyThreadState * new_threadstate(PyInterpreterState *interp, int init) { PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); if (_PyThreadState_GetFrame == NULL) _PyThreadState_GetFrame = threadstate_getframe; if (tstate != NULL) { tstate->interp = interp; tstate->frame = NULL; tstate->recursion_depth = 0; tstate->overflowed = 0; tstate->recursion_critical = 0; tstate->tracing = 0; tstate->use_tracing = 0; tstate->gilstate_counter = 0; tstate->async_exc = NULL; #ifdef WITH_THREAD tstate->thread_id = PyThread_get_thread_ident(); #else tstate->thread_id = 0; #endif tstate->dict = NULL; tstate->curexc_type = NULL; tstate->curexc_value = NULL; tstate->curexc_traceback = NULL; tstate->exc_type = NULL; tstate->exc_value = NULL; tstate->exc_traceback = NULL; tstate->c_profilefunc = NULL; tstate->c_tracefunc = NULL; tstate->c_profileobj = NULL; tstate->c_traceobj = NULL; tstate->trash_delete_nesting = 0; tstate->trash_delete_later = NULL; tstate->on_delete = NULL; tstate->on_delete_data = NULL; if (init) _PyThreadState_Init(tstate); HEAD_LOCK(); tstate->prev = NULL; tstate->next = interp->tstate_head; if (tstate->next) tstate->next->prev = tstate; interp->tstate_head = tstate; HEAD_UNLOCK(); #if defined _MSC_VER && _MSC_VER >= 1900 /* Issue #23524: Temporary fix to disable termination due to invalid parameters */ _set_thread_local_invalid_parameter_handler((_invalid_parameter_handler)_Py_silent_invalid_parameter_handler); #endif } return tstate; }
/* Decode a byte string from the locale encoding with the surrogateescape error handler (undecodable bytes are decoded as characters in range U+DC80..U+DCFF). If a byte sequence can be decoded as a surrogate character, escape the bytes using the surrogateescape error handler instead of decoding them. Use _Py_wchar2char() to encode the character string back to a byte string. Return a pointer to a newly allocated wide character string (use PyMem_RawFree() to free the memory) and write the number of written wide characters excluding the null character into *size if size is not NULL, or NULL on error (decoding or memory allocation error). If size is not NULL, *size is set to (size_t)-1 on memory error and (size_t)-2 on decoding error. Conversion errors should never happen, unless there is a bug in the C library. */ wchar_t* _Py_char2wchar(const char* arg, size_t *size) { #ifdef __APPLE__ wchar_t *wstr; wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg)); if (size != NULL) { if (wstr != NULL) *size = wcslen(wstr); else *size = (size_t)-1; } return wstr; #else wchar_t *res; size_t argsize; size_t count; #ifdef HAVE_MBRTOWC unsigned char *in; wchar_t *out; mbstate_t mbs; #endif #ifndef MS_WINDOWS if (force_ascii == -1) force_ascii = check_force_ascii(); if (force_ascii) { /* force ASCII encoding to workaround mbstowcs() issue */ res = decode_ascii_surrogateescape(arg, size); if (res == NULL) goto oom; return res; } #endif #ifdef HAVE_BROKEN_MBSTOWCS /* Some platforms have a broken implementation of * mbstowcs which does not count the characters that * would result from conversion. Use an upper bound. */ argsize = strlen(arg); #else argsize = mbstowcs(NULL, arg, 0); #endif if (argsize != (size_t)-1) { if (argsize == PY_SSIZE_T_MAX) goto oom; argsize += 1; if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t)) goto oom; res = (wchar_t *)PyMem_RawMalloc(argsize*sizeof(wchar_t)); if (!res) goto oom; count = mbstowcs(res, arg, argsize); if (count != (size_t)-1) { wchar_t *tmp; /* Only use the result if it contains no surrogate characters. */ for (tmp = res; *tmp != 0 && !Py_UNICODE_IS_SURROGATE(*tmp); tmp++) ; if (*tmp == 0) { if (size != NULL) *size = count; return res; } } PyMem_RawFree(res); } /* Conversion failed. Fall back to escaping with surrogateescape. */ #ifdef HAVE_MBRTOWC /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */ /* Overallocate; as multi-byte characters are in the argument, the actual output could use less memory. */ argsize = strlen(arg) + 1; if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t)) goto oom; res = (wchar_t*)PyMem_RawMalloc(argsize*sizeof(wchar_t)); if (!res) goto oom; in = (unsigned char*)arg; out = res; memset(&mbs, 0, sizeof mbs); while (argsize) { size_t converted = mbrtowc(out, (char*)in, argsize, &mbs); if (converted == 0) /* Reached end of string; null char stored. */ break; if (converted == (size_t)-2) { /* Incomplete character. This should never happen, since we provide everything that we have - unless there is a bug in the C library, or I misunderstood how mbrtowc works. */ PyMem_RawFree(res); if (size != NULL) *size = (size_t)-2; return NULL; } if (converted == (size_t)-1) { /* Conversion error. Escape as UTF-8b, and start over in the initial shift state. */ *out++ = 0xdc00 + *in++; argsize--; memset(&mbs, 0, sizeof mbs); continue; } if (Py_UNICODE_IS_SURROGATE(*out)) { /* Surrogate character. Escape the original byte sequence with surrogateescape. */ argsize -= converted; while (converted--) *out++ = 0xdc00 + *in++; continue; } /* successfully converted some bytes */ in += converted; argsize -= converted; out++; } if (size != NULL) *size = out - res; #else /* HAVE_MBRTOWC */ /* Cannot use C locale for escaping; manually escape as if charset is ASCII (i.e. escape all bytes > 128. This will still roundtrip correctly in the locale's charset, which must be an ASCII superset. */ res = decode_ascii_surrogateescape(arg, size); if (res == NULL) goto oom; #endif /* HAVE_MBRTOWC */ return res; oom: if (size != NULL) *size = (size_t)-1; return NULL; #endif /* __APPLE__ */ }
static _PyInitError calculate_module_search_path(const _PyCoreConfig *core_config, PyCalculatePath *calculate, _PyPathConfig *config, wchar_t *prefix) { int skiphome = calculate->home==NULL ? 0 : 1; #ifdef Py_ENABLE_SHARED calculate->machine_path = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome); calculate->user_path = getpythonregpath(HKEY_CURRENT_USER, skiphome); #endif /* We only use the default relative PYTHONPATH if we haven't anything better to use! */ int skipdefault = (core_config->module_search_path_env != NULL || calculate->home != NULL || calculate->machine_path != NULL || calculate->user_path != NULL); /* We need to construct a path from the following parts. (1) the PYTHONPATH environment variable, if set; (2) for Win32, the zip archive file path; (3) for Win32, the machine_path and user_path, if set; (4) the PYTHONPATH config macro, with the leading "." of each component replaced with home, if set; (5) the directory containing the executable (argv0_path). The length calculation calculates #4 first. Extra rules: - If PYTHONHOME is set (in any way) item (3) is ignored. - If registry values are used, (4) and (5) are ignored. */ /* Calculate size of return buffer */ size_t bufsz = 0; if (calculate->home != NULL) { const wchar_t *p; bufsz = 1; for (p = PYTHONPATH; *p; p++) { if (*p == DELIM) { bufsz++; /* number of DELIM plus one */ } } bufsz *= wcslen(calculate->home); } bufsz += wcslen(PYTHONPATH) + 1; bufsz += wcslen(calculate->argv0_path) + 1; if (calculate->user_path) { bufsz += wcslen(calculate->user_path) + 1; } if (calculate->machine_path) { bufsz += wcslen(calculate->machine_path) + 1; } bufsz += wcslen(calculate->zip_path) + 1; if (core_config->module_search_path_env != NULL) { bufsz += wcslen(core_config->module_search_path_env) + 1; } wchar_t *buf, *start_buf; buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t)); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n"); if (core_config->module_search_path_env) { fprintf(stderr, "Using environment $PYTHONPATH.\n"); config->module_search_path = core_config->module_search_path_env; } else { fprintf(stderr, "Using default static path.\n"); config->module_search_path = PYTHONPATH; } return _Py_INIT_OK(); } start_buf = buf; if (core_config->module_search_path_env) { if (wcscpy_s(buf, bufsz - (buf - start_buf), core_config->module_search_path_env)) { return INIT_ERR_BUFFER_OVERFLOW(); } buf = wcschr(buf, L'\0'); *buf++ = DELIM; } if (calculate->zip_path[0]) { if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->zip_path)) { return INIT_ERR_BUFFER_OVERFLOW(); } buf = wcschr(buf, L'\0'); *buf++ = DELIM; } if (calculate->user_path) { if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->user_path)) { return INIT_ERR_BUFFER_OVERFLOW(); } buf = wcschr(buf, L'\0'); *buf++ = DELIM; } if (calculate->machine_path) { if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->machine_path)) { return INIT_ERR_BUFFER_OVERFLOW(); } buf = wcschr(buf, L'\0'); *buf++ = DELIM; } if (calculate->home == NULL) { if (!skipdefault) { if (wcscpy_s(buf, bufsz - (buf - start_buf), PYTHONPATH)) { return INIT_ERR_BUFFER_OVERFLOW(); } buf = wcschr(buf, L'\0'); *buf++ = DELIM; } } else { const wchar_t *p = PYTHONPATH; const wchar_t *q; size_t n; for (;;) { q = wcschr(p, DELIM); if (q == NULL) { n = wcslen(p); } else { n = q-p; } if (p[0] == '.' && is_sep(p[1])) { if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->home)) { return INIT_ERR_BUFFER_OVERFLOW(); } buf = wcschr(buf, L'\0'); p++; n--; } wcsncpy(buf, p, n); buf += n; *buf++ = DELIM; if (q == NULL) { break; } p = q+1; } } if (calculate->argv0_path) { wcscpy(buf, calculate->argv0_path); buf = wcschr(buf, L'\0'); *buf++ = DELIM; } *(buf - 1) = L'\0'; /* Now to pull one last hack/trick. If sys.prefix is empty, then try and find it somewhere on the paths we calculated. We scan backwards, as our general policy is that Python core directories are at the *end* of sys.path. We assume that our "lib" directory is on the path, and that our 'prefix' directory is the parent of that. */ if (prefix[0] == L'\0') { wchar_t lookBuf[MAXPATHLEN+1]; const wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */ while (1) { Py_ssize_t nchars; const wchar_t *lookEnd = look; /* 'look' will end up one character before the start of the path in question - even if this is one character before the start of the buffer */ while (look >= start_buf && *look != DELIM) look--; nchars = lookEnd-look; wcsncpy(lookBuf, look+1, nchars); lookBuf[nchars] = L'\0'; /* Up one level to the parent */ reduce(lookBuf); if (search_for_prefix(prefix, lookBuf, LANDMARK)) { break; } /* If we are out of paths to search - give up */ if (look < start_buf) { break; } look--; } } config->module_search_path = start_buf; return _Py_INIT_OK(); }
static PyThreadState * new_threadstate(PyInterpreterState *interp, int init) { PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); if (_PyThreadState_GetFrame == NULL) _PyThreadState_GetFrame = threadstate_getframe; if (tstate != NULL) { tstate->interp = interp; tstate->frame = NULL; tstate->recursion_depth = 0; tstate->overflowed = 0; tstate->recursion_critical = 0; tstate->stackcheck_counter = 0; tstate->tracing = 0; tstate->use_tracing = 0; tstate->gilstate_counter = 0; tstate->async_exc = NULL; tstate->thread_id = PyThread_get_thread_ident(); tstate->dict = NULL; tstate->curexc_type = NULL; tstate->curexc_value = NULL; tstate->curexc_traceback = NULL; tstate->exc_state.exc_type = NULL; tstate->exc_state.exc_value = NULL; tstate->exc_state.exc_traceback = NULL; tstate->exc_state.previous_item = NULL; tstate->exc_info = &tstate->exc_state; tstate->c_profilefunc = NULL; tstate->c_tracefunc = NULL; tstate->c_profileobj = NULL; tstate->c_traceobj = NULL; tstate->trash_delete_nesting = 0; tstate->trash_delete_later = NULL; tstate->on_delete = NULL; tstate->on_delete_data = NULL; tstate->coroutine_origin_tracking_depth = 0; tstate->coroutine_wrapper = NULL; tstate->in_coroutine_wrapper = 0; tstate->async_gen_firstiter = NULL; tstate->async_gen_finalizer = NULL; tstate->context = NULL; tstate->context_ver = 1; tstate->id = ++interp->tstate_next_unique_id; if (init) _PyThreadState_Init(tstate); HEAD_LOCK(); tstate->prev = NULL; tstate->next = interp->tstate_head; if (tstate->next) tstate->next->prev = tstate; interp->tstate_head = tstate; HEAD_UNLOCK(); } return tstate; }
int Py_FrozenMain(int argc, char **argv) { char *p; int i, n, sts = 1; int inspect = 0; int unbuffered = 0; char *oldloc = NULL; wchar_t **argv_copy = NULL; /* We need a second copies, as Python might modify the first one. */ wchar_t **argv_copy2 = NULL; argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc); argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc); if (!argv_copy || !argv_copy2) { fprintf(stderr, "out of memory\n"); goto error; } Py_FrozenFlag = 1; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') inspect = 1; if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; if (unbuffered) { setbuf(stdin, (char *)NULL); setbuf(stdout, (char *)NULL); setbuf(stderr, (char *)NULL); } oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); if (!oldloc) { fprintf(stderr, "out of memory\n"); goto error; } setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy[i] = _Py_char2wchar(argv[i], NULL); argv_copy2[i] = argv_copy[i]; if (!argv_copy[i]) { fprintf(stderr, "Unable to decode the command line argument #%i\n", i + 1); argc = i; goto error; } } setlocale(LC_ALL, oldloc); PyMem_RawFree(oldloc); oldloc = NULL; #ifdef MS_WINDOWS PyInitFrozenExtensions(); #endif /* MS_WINDOWS */ Py_SetProgramName(argv_copy[0]); Py_Initialize(); #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); #endif if (Py_VerboseFlag) fprintf(stderr, "Python %s\n%s\n", Py_GetVersion(), Py_GetCopyright()); PySys_SetArgv(argc, argv_copy); n = PyImport_ImportFrozenModule("__main__"); if (n == 0) Py_FatalError("__main__ not frozen"); if (n < 0) { PyErr_Print(); sts = 1; } else sts = 0; if (inspect && isatty((int)fileno(stdin))) sts = PyRun_AnyFile(stdin, "<stdin>") != 0; #ifdef MS_WINDOWS PyWinFreeze_ExeTerm(); #endif Py_Finalize(); error: PyMem_RawFree(argv_copy); if (argv_copy2) { for (i = 0; i < argc; i++) PyMem_RawFree(argv_copy2[i]); PyMem_RawFree(argv_copy2); } PyMem_RawFree(oldloc); return sts; }
int Py_FrozenMain(int argc, char **argv) { _PyInitError err = _PyRuntime_Initialize(); if (_Py_INIT_FAILED(err)) { fprintf(stderr, "Fatal Python error: %s\n", err.msg); fflush(stderr); exit(1); } const char *p; int i, n, sts = 1; int inspect = 0; int unbuffered = 0; char *oldloc = NULL; wchar_t **argv_copy = NULL; /* We need a second copies, as Python might modify the first one. */ wchar_t **argv_copy2 = NULL; if (argc > 0) { argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc); argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc); if (!argv_copy || !argv_copy2) { fprintf(stderr, "out of memory\n"); goto error; } } _PyCoreConfig config = _PyCoreConfig_INIT; config._frozen = 1; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') inspect = 1; if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; if (unbuffered) { setbuf(stdin, (char *)NULL); setbuf(stdout, (char *)NULL); setbuf(stderr, (char *)NULL); } oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); if (!oldloc) { fprintf(stderr, "out of memory\n"); goto error; } setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy[i] = Py_DecodeLocale(argv[i], NULL); argv_copy2[i] = argv_copy[i]; if (!argv_copy[i]) { fprintf(stderr, "Unable to decode the command line argument #%i\n", i + 1); argc = i; goto error; } } setlocale(LC_ALL, oldloc); PyMem_RawFree(oldloc); oldloc = NULL; #ifdef MS_WINDOWS PyInitFrozenExtensions(); #endif /* MS_WINDOWS */ if (argc >= 1) Py_SetProgramName(argv_copy[0]); err = _Py_InitializeFromConfig(&config); /* No need to call _PyCoreConfig_Clear() since we didn't allocate any memory: program_name is a constant string. */ if (_Py_INIT_FAILED(err)) { _Py_FatalInitError(err); } #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); #endif if (Py_VerboseFlag) fprintf(stderr, "Python %s\n%s\n", Py_GetVersion(), Py_GetCopyright()); PySys_SetArgv(argc, argv_copy); n = PyImport_ImportFrozenModule("__main__"); if (n == 0) Py_FatalError("__main__ not frozen"); if (n < 0) { PyErr_Print(); sts = 1; } else sts = 0; if (inspect && isatty((int)fileno(stdin))) sts = PyRun_AnyFile(stdin, "<stdin>") != 0; #ifdef MS_WINDOWS PyWinFreeze_ExeTerm(); #endif if (Py_FinalizeEx() < 0) { sts = 120; } error: PyMem_RawFree(argv_copy); if (argv_copy2) { for (i = 0; i < argc; i++) PyMem_RawFree(argv_copy2[i]); PyMem_RawFree(argv_copy2); } PyMem_RawFree(oldloc); return sts; }
PyInterpreterState * PyInterpreterState_New(void) { PyInterpreterState *interp = (PyInterpreterState *) PyMem_RawMalloc(sizeof(PyInterpreterState)); if (interp == NULL) { return NULL; } memset(interp, 0, sizeof(*interp)); interp->id_refcount = -1; interp->check_interval = 100; interp->ceval.pending.lock = PyThread_allocate_lock(); if (interp->ceval.pending.lock == NULL) { PyErr_SetString(PyExc_RuntimeError, "failed to create interpreter ceval pending mutex"); return NULL; } interp->core_config = _PyCoreConfig_INIT; interp->config = _PyMainInterpreterConfig_INIT; interp->eval_frame = _PyEval_EvalFrameDefault; #ifdef HAVE_DLOPEN #if HAVE_DECL_RTLD_NOW interp->dlopenflags = RTLD_NOW; #else interp->dlopenflags = RTLD_LAZY; #endif #endif if (_PyRuntime.main_thread == 0) { _PyRuntime.main_thread = PyThread_get_thread_ident(); } HEAD_LOCK(); if (_PyRuntime.interpreters.next_id < 0) { /* overflow or Py_Initialize() not called! */ PyErr_SetString(PyExc_RuntimeError, "failed to get an interpreter ID"); PyMem_RawFree(interp); interp = NULL; } else { interp->id = _PyRuntime.interpreters.next_id; _PyRuntime.interpreters.next_id += 1; interp->next = _PyRuntime.interpreters.head; if (_PyRuntime.interpreters.main == NULL) { _PyRuntime.interpreters.main = interp; } _PyRuntime.interpreters.head = interp; } HEAD_UNLOCK(); if (interp == NULL) { return NULL; } interp->tstate_next_unique_id = 0; return interp; }
static wchar_t * getpythonregpath(HKEY keyBase, int skipcore) { HKEY newKey = 0; DWORD dataSize = 0; DWORD numKeys = 0; LONG rc; wchar_t *retval = NULL; WCHAR *dataBuf = NULL; static const WCHAR keyPrefix[] = L"Software\\Python\\PythonCore\\"; static const WCHAR keySuffix[] = L"\\PythonPath"; size_t versionLen, keyBufLen; DWORD index; WCHAR *keyBuf = NULL; WCHAR *keyBufPtr; WCHAR **ppPaths = NULL; /* Tried to use sysget("winver") but here is too early :-( */ versionLen = strlen(PyWin_DLLVersionString); /* Space for all the chars, plus one \0 */ keyBufLen = sizeof(keyPrefix) + sizeof(WCHAR)*(versionLen-1) + sizeof(keySuffix); keyBuf = keyBufPtr = PyMem_RawMalloc(keyBufLen); if (keyBuf==NULL) goto done; memcpy_s(keyBufPtr, keyBufLen, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR)); keyBufPtr += Py_ARRAY_LENGTH(keyPrefix) - 1; mbstowcs(keyBufPtr, PyWin_DLLVersionString, versionLen); keyBufPtr += versionLen; /* NULL comes with this one! */ memcpy(keyBufPtr, keySuffix, sizeof(keySuffix)); /* Open the root Python key */ rc=RegOpenKeyExW(keyBase, keyBuf, /* subkey */ 0, /* reserved */ KEY_READ, &newKey); if (rc!=ERROR_SUCCESS) goto done; /* Find out how big our core buffer is, and how many subkeys we have */ rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL, NULL, NULL, &dataSize, NULL, NULL); if (rc!=ERROR_SUCCESS) goto done; if (skipcore) dataSize = 0; /* Only count core ones if we want them! */ /* Allocate a temp array of char buffers, so we only need to loop reading the registry once */ ppPaths = PyMem_RawMalloc( sizeof(WCHAR *) * numKeys ); if (ppPaths==NULL) goto done; memset(ppPaths, 0, sizeof(WCHAR *) * numKeys); /* Loop over all subkeys, allocating a temp sub-buffer. */ for(index=0;index<numKeys;index++) { WCHAR keyBuf[MAX_PATH+1]; HKEY subKey = 0; DWORD reqdSize = MAX_PATH+1; /* Get the sub-key name */ DWORD rc = RegEnumKeyExW(newKey, index, keyBuf, &reqdSize, NULL, NULL, NULL, NULL ); if (rc!=ERROR_SUCCESS) goto done; /* Open the sub-key */ rc=RegOpenKeyExW(newKey, keyBuf, /* subkey */ 0, /* reserved */ KEY_READ, &subKey); if (rc!=ERROR_SUCCESS) goto done; /* Find the value of the buffer size, malloc, then read it */ RegQueryValueExW(subKey, NULL, 0, NULL, NULL, &reqdSize); if (reqdSize) { ppPaths[index] = PyMem_RawMalloc(reqdSize); if (ppPaths[index]) { RegQueryValueExW(subKey, NULL, 0, NULL, (LPBYTE)ppPaths[index], &reqdSize); dataSize += reqdSize + 1; /* 1 for the ";" */ } } RegCloseKey(subKey); } /* return null if no path to return */ if (dataSize == 0) goto done; /* original datasize from RegQueryInfo doesn't include the \0 */ dataBuf = PyMem_RawMalloc((dataSize+1) * sizeof(WCHAR)); if (dataBuf) { WCHAR *szCur = dataBuf; /* Copy our collected strings */ for (index=0;index<numKeys;index++) { if (index > 0) { *(szCur++) = L';'; dataSize--; } if (ppPaths[index]) { Py_ssize_t len = wcslen(ppPaths[index]); wcsncpy(szCur, ppPaths[index], len); szCur += len; assert(dataSize > (DWORD)len); dataSize -= (DWORD)len; } } if (skipcore) *szCur = '\0'; else { /* If we have no values, we dont need a ';' */ if (numKeys) { *(szCur++) = L';'; dataSize--; } /* Now append the core path entries - this will include the NULL */ rc = RegQueryValueExW(newKey, NULL, 0, NULL, (LPBYTE)szCur, &dataSize); if (rc != ERROR_SUCCESS) { PyMem_RawFree(dataBuf); goto done; } } /* And set the result - caller must free */ retval = dataBuf; } done: /* Loop freeing my temp buffers */ if (ppPaths) { for(index=0; index<numKeys; index++) PyMem_RawFree(ppPaths[index]); PyMem_RawFree(ppPaths); } if (newKey) RegCloseKey(newKey); PyMem_RawFree(keyBuf); return retval; }
static void calculate_path(void) { wchar_t argv0_path[MAXPATHLEN+1]; wchar_t *buf; size_t bufsz; wchar_t *pythonhome = Py_GetPythonHome(); wchar_t *envpath = NULL; int skiphome, skipdefault; wchar_t *machinepath = NULL; wchar_t *userpath = NULL; wchar_t zip_path[MAXPATHLEN+1]; if (!Py_IgnoreEnvironmentFlag) { envpath = _wgetenv(L"PYTHONPATH"); } get_progpath(); /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */ wcscpy_s(argv0_path, MAXPATHLEN+1, progpath); reduce(argv0_path); /* Search for a sys.path file */ { wchar_t spbuffer[MAXPATHLEN+1]; if ((dllpath[0] && !change_ext(spbuffer, dllpath, L"._pth") && exists(spbuffer)) || (progpath[0] && !change_ext(spbuffer, progpath, L"._pth") && exists(spbuffer))) { if (!read_pth_file(spbuffer, prefix, &Py_IsolatedFlag, &Py_NoSiteFlag)) { return; } } } /* Search for an environment configuration file, first in the executable's directory and then in the parent directory. If found, open it for use when searching for prefixes. */ { wchar_t envbuffer[MAXPATHLEN+1]; wchar_t tmpbuffer[MAXPATHLEN+1]; const wchar_t *env_cfg = L"pyvenv.cfg"; FILE * env_file = NULL; wcscpy_s(envbuffer, MAXPATHLEN+1, argv0_path); join(envbuffer, env_cfg); env_file = _Py_wfopen(envbuffer, L"r"); if (env_file == NULL) { errno = 0; reduce(envbuffer); reduce(envbuffer); join(envbuffer, env_cfg); env_file = _Py_wfopen(envbuffer, L"r"); if (env_file == NULL) { errno = 0; } } if (env_file != NULL) { /* Look for a 'home' variable and set argv0_path to it, if found */ if (find_env_config_value(env_file, L"home", tmpbuffer)) { wcscpy_s(argv0_path, MAXPATHLEN+1, tmpbuffer); } fclose(env_file); env_file = NULL; } } /* Calculate zip archive path from DLL or exe path */ change_ext(zip_path, dllpath[0] ? dllpath : progpath, L".zip"); if (pythonhome == NULL || *pythonhome == '\0') { if (zip_path[0] && exists(zip_path)) { wcscpy_s(prefix, MAXPATHLEN+1, zip_path); reduce(prefix); pythonhome = prefix; } else if (search_for_prefix(argv0_path, LANDMARK)) pythonhome = prefix; else pythonhome = NULL; } else wcscpy_s(prefix, MAXPATHLEN+1, pythonhome); if (envpath && *envpath == '\0') envpath = NULL; skiphome = pythonhome==NULL ? 0 : 1; #ifdef Py_ENABLE_SHARED machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome); userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome); #endif /* We only use the default relative PYTHONPATH if we havent anything better to use! */ skipdefault = envpath!=NULL || pythonhome!=NULL || \ machinepath!=NULL || userpath!=NULL; /* We need to construct a path from the following parts. (1) the PYTHONPATH environment variable, if set; (2) for Win32, the zip archive file path; (3) for Win32, the machinepath and userpath, if set; (4) the PYTHONPATH config macro, with the leading "." of each component replaced with pythonhome, if set; (5) the directory containing the executable (argv0_path). The length calculation calculates #4 first. Extra rules: - If PYTHONHOME is set (in any way) item (3) is ignored. - If registry values are used, (4) and (5) are ignored. */ /* Calculate size of return buffer */ if (pythonhome != NULL) { wchar_t *p; bufsz = 1; for (p = PYTHONPATH; *p; p++) { if (*p == DELIM) bufsz++; /* number of DELIM plus one */ } bufsz *= wcslen(pythonhome); } else bufsz = 0; bufsz += wcslen(PYTHONPATH) + 1; bufsz += wcslen(argv0_path) + 1; if (userpath) bufsz += wcslen(userpath) + 1; if (machinepath) bufsz += wcslen(machinepath) + 1; bufsz += wcslen(zip_path) + 1; if (envpath != NULL) bufsz += wcslen(envpath) + 1; module_search_path = buf = PyMem_RawMalloc(bufsz*sizeof(wchar_t)); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n"); if (envpath) { fprintf(stderr, "Using environment $PYTHONPATH.\n"); module_search_path = envpath; } else { fprintf(stderr, "Using default static path.\n"); module_search_path = PYTHONPATH; } PyMem_RawFree(machinepath); PyMem_RawFree(userpath); return; } if (envpath) { if (wcscpy_s(buf, bufsz - (buf - module_search_path), envpath)) Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); *buf++ = DELIM; } if (zip_path[0]) { if (wcscpy_s(buf, bufsz - (buf - module_search_path), zip_path)) Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); *buf++ = DELIM; } if (userpath) { if (wcscpy_s(buf, bufsz - (buf - module_search_path), userpath)) Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); *buf++ = DELIM; PyMem_RawFree(userpath); } if (machinepath) { if (wcscpy_s(buf, bufsz - (buf - module_search_path), machinepath)) Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); *buf++ = DELIM; PyMem_RawFree(machinepath); } if (pythonhome == NULL) { if (!skipdefault) { if (wcscpy_s(buf, bufsz - (buf - module_search_path), PYTHONPATH)) Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); *buf++ = DELIM; } } else { wchar_t *p = PYTHONPATH; wchar_t *q; size_t n; for (;;) { q = wcschr(p, DELIM); if (q == NULL) n = wcslen(p); else n = q-p; if (p[0] == '.' && is_sep(p[1])) { if (wcscpy_s(buf, bufsz - (buf - module_search_path), pythonhome)) Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); p++; n--; } wcsncpy(buf, p, n); buf += n; *buf++ = DELIM; if (q == NULL) break; p = q+1; } } if (argv0_path) { wcscpy(buf, argv0_path); buf = wcschr(buf, L'\0'); *buf++ = DELIM; } *(buf - 1) = L'\0'; /* Now to pull one last hack/trick. If sys.prefix is empty, then try and find it somewhere on the paths we calculated. We scan backwards, as our general policy is that Python core directories are at the *end* of sys.path. We assume that our "lib" directory is on the path, and that our 'prefix' directory is the parent of that. */ if (*prefix==L'\0') { wchar_t lookBuf[MAXPATHLEN+1]; wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */ while (1) { Py_ssize_t nchars; wchar_t *lookEnd = look; /* 'look' will end up one character before the start of the path in question - even if this is one character before the start of the buffer */ while (look >= module_search_path && *look != DELIM) look--; nchars = lookEnd-look; wcsncpy(lookBuf, look+1, nchars); lookBuf[nchars] = L'\0'; /* Up one level to the parent */ reduce(lookBuf); if (search_for_prefix(lookBuf, LANDMARK)) { break; } /* If we are out of paths to search - give up */ if (look < module_search_path) break; look--; } } }
static int read_pth_file(const wchar_t *path, wchar_t *prefix, int *isolated, int *nosite) { FILE *sp_file = _Py_wfopen(path, L"r"); if (sp_file == NULL) return -1; wcscpy_s(prefix, MAXPATHLEN+1, path); reduce(prefix); *isolated = 1; *nosite = 1; size_t bufsiz = MAXPATHLEN; size_t prefixlen = wcslen(prefix); wchar_t *buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t)); buf[0] = '\0'; while (!feof(sp_file)) { char line[MAXPATHLEN + 1]; char *p = fgets(line, MAXPATHLEN + 1, sp_file); if (!p) break; if (*p == '\0' || *p == '#') continue; while (*++p) { if (*p == '\r' || *p == '\n') { *p = '\0'; break; } } if (strcmp(line, "import site") == 0) { *nosite = 0; continue; } else if (strncmp(line, "import ", 7) == 0) { Py_FatalError("only 'import site' is supported in ._pth file"); } DWORD wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, NULL, 0); wchar_t *wline = (wchar_t*)PyMem_RawMalloc((wn + 1) * sizeof(wchar_t)); wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, wline, wn + 1); wline[wn] = '\0'; size_t usedsiz = wcslen(buf); while (usedsiz + wn + prefixlen + 4 > bufsiz) { bufsiz += MAXPATHLEN; buf = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) * sizeof(wchar_t)); if (!buf) { PyMem_RawFree(wline); goto error; } } if (usedsiz) { wcscat_s(buf, bufsiz, L";"); usedsiz += 1; } errno_t result; _Py_BEGIN_SUPPRESS_IPH result = wcscat_s(buf, bufsiz, prefix); _Py_END_SUPPRESS_IPH if (result == EINVAL) { Py_FatalError("invalid argument during ._pth processing"); } else if (result == ERANGE) { Py_FatalError("buffer overflow during ._pth processing"); } wchar_t *b = &buf[usedsiz]; join(b, wline); PyMem_RawFree(wline); } module_search_path = buf; fclose(sp_file); return 0; error: PyMem_RawFree(buf); fclose(sp_file); return -1; }