Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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);
    }
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
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);
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
/* 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;
}
Ejemplo n.º 17
0
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();
}
Ejemplo n.º 18
0
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;
    }
Ejemplo n.º 19
0
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);
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
/* 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__ */
}
Ejemplo n.º 23
0
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();
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
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;
}
Ejemplo n.º 26
0
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;
}
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 29
0
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--;
        }
    }
}
Ejemplo n.º 30
0
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;
}