static PyObject*
PyLocale_strcoll(PyObject* self, PyObject* args)
{
#if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
    char *s1,*s2;

    if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
        return NULL;
    return PyInt_FromLong(strcoll(s1, s2));
#else
    PyObject *os1, *os2, *result = NULL;
    wchar_t *ws1 = NULL, *ws2 = NULL;
    int rel1 = 0, rel2 = 0, len1, len2;

    if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
        return NULL;
    /* If both arguments are byte strings, use strcoll.  */
    if (PyString_Check(os1) && PyString_Check(os2))
        return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
                                      PyString_AS_STRING(os2)));
    /* If neither argument is unicode, it's an error.  */
    if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
        PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
    }
    /* Convert the non-unicode argument to unicode. */
    if (!PyUnicode_Check(os1)) {
    os1 = PyUnicode_FromObject(os1);
    if (!os1)
        return NULL;
        rel1 = 1;
    }
    if (!PyUnicode_Check(os2)) {
        os2 = PyUnicode_FromObject(os2);
        if (!os2) {
            if (rel1) {
                Py_DECREF(os1);
            }
            return NULL;
        }
        rel2 = 1;
    }
    /* Convert the unicode strings to wchar[]. */
    len1 = PyUnicode_GET_SIZE(os1) + 1;
    ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
    if (!ws1) {
        PyErr_NoMemory();
        goto done;
    }
    if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
        goto done;
    ws1[len1 - 1] = 0;
    len2 = PyUnicode_GET_SIZE(os2) + 1;
    ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
    if (!ws2) {
        PyErr_NoMemory();
        goto done;
    }
    if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
        goto done;
    ws2[len2 - 1] = 0;
    /* Collate the strings. */
    result = PyInt_FromLong(wcscoll(ws1, ws2));
  done:
    /* Deallocate everything. */
    if (ws1) PyMem_FREE(ws1);
    if (ws2) PyMem_FREE(ws2);
    if (rel1) {
        Py_DECREF(os1);
    }
    if (rel2) {
        Py_DECREF(os2);
    }
    return result;
#endif
}
Exemplo n.º 2
0
static int
prepare_s(PyStructObject *self)
{
    const formatdef *f;
    const formatdef *e;
    formatcode *codes;

    const char *s;
    const char *fmt;
    char c;
    Py_ssize_t size, len, num, itemsize;

    fmt = PyBytes_AS_STRING(self->s_format);

    f = whichtable((char **)&fmt);

    s = fmt;
    size = 0;
    len = 0;
    while ((c = *s++) != '\0') {
        if (isspace(Py_CHARMASK(c)))
            continue;
        if ('0' <= c && c <= '9') {
            num = c - '0';
            while ('0' <= (c = *s++) && c <= '9') {
                /* overflow-safe version of
                   if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
                if (num >= PY_SSIZE_T_MAX / 10 && (
                        num > PY_SSIZE_T_MAX / 10 ||
                        (c - '0') > PY_SSIZE_T_MAX % 10))
                    goto overflow;
                num = num*10 + (c - '0');
            }
            if (c == '\0') {
                PyErr_SetString(StructError,
                                "repeat count given without format specifier");
                return -1;
            }
        }
        else
            num = 1;

        e = getentry(c, f);
        if (e == NULL)
            return -1;

        switch (c) {
            case 's': /* fall through */
            case 'p': len++; break;
            case 'x': break;
            default: len += num; break;
        }

        itemsize = e->size;
        size = align(size, c, e);
        if (size == -1)
            goto overflow;

        /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
        if (num > (PY_SSIZE_T_MAX - size) / itemsize)
            goto overflow;
        size += num * itemsize;
    }

    /* check for overflow */
    if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
        PyErr_NoMemory();
        return -1;
    }

    self->s_size = size;
    self->s_len = len;
    codes = (formatcode *) PyMem_MALLOC((len + 1) * sizeof(formatcode));
    if (codes == NULL) {
        PyErr_NoMemory();
        return -1;
    }
    /* Free any s_codes value left over from a previous initialization. */
    if (self->s_codes != NULL)
        PyMem_FREE(self->s_codes);
    self->s_codes = codes;

    s = fmt;
    size = 0;
    while ((c = *s++) != '\0') {
        if (isspace(Py_CHARMASK(c)))
            continue;
        if ('0' <= c && c <= '9') {
            num = c - '0';
            while ('0' <= (c = *s++) && c <= '9')
                num = num*10 + (c - '0');
            if (c == '\0')
                break;
        }
        else
            num = 1;

        e = getentry(c, f);

        size = align(size, c, e);
        if (c == 's' || c == 'p') {
            codes->offset = size;
            codes->size = num;
            codes->fmtdef = e;
            codes++;
            size += num;
        } else if (c == 'x') {
            size += num;
        } else {
            while (--num >= 0) {
                codes->offset = size;
                codes->size = e->size;
                codes->fmtdef = e;
                codes++;
                size += e->size;
            }
        }
    }
    codes->fmtdef = NULL;
    codes->offset = size;
    codes->size = 0;

    return 0;

  overflow:
    PyErr_SetString(StructError,
                    "total struct size too long");
    return -1;
}
Exemplo n.º 3
0
int
exceptionlist__initmodule(PyObject* module, struct exceptionlist* exclist) {
	const struct exceptionlist* exc;
	char* longname = NULL;
	PyObject* name;
	Py_ssize_t size;
	Py_ssize_t maxsize;

	if ((name = PyObject_GetAttrString(module, "__name__")) == NULL)
		return -1;
	if (!PyString_Check(name)) {
		PyErr_SetString(PyExc_TypeError, "__name__ required an str()");
		goto failed;
	}
	size = PyString_GET_SIZE(name);
	for (maxsize = 0, exc = exclist; exc->exc_name != NULL; exc++) {
		register int i = strlen(exc->exc_name);
		if (i > maxsize)
			maxsize = i;
	}
	if ((longname = PyMem_MALLOC(size + sizeof(".") + maxsize + sizeof("\0"))) == NULL) {
		PyErr_NoMemory();
		goto failed;
	}
	memcpy(longname, PyString_AS_STRING(name), size);
	Py_DECREF(name);
	longname[size++] = '.';
	for (exc = exclist; exc->exc_name != NULL; exc++) {
		PyObject* dict;
		PyObject* s;
		
		if ((dict = PyDict_New()) == NULL)
			goto failed;
		if ((s = PyString_FromString(exc->exc_doc)) == NULL) {
			Py_DECREF(dict);
			goto failed;
		}
		if (PyDict_SetItemString(dict, "__doc__", s) < 0) {
			Py_DECREF(dict);
			Py_DECREF(s);
			goto failed;
		}
		Py_DECREF(s);
		strcpy(&longname[size], exc->exc_name);
		if (*exc->exc_this == NULL &&
		   (*exc->exc_this = PyErr_NewException(longname, *exc->exc_base, dict)) == NULL) {
			Py_DECREF(dict);
			goto failed;
		}
		Py_DECREF(dict);
	}
	PyMem_FREE(longname);
	for (exc = exclist; exc->exc_name != NULL; exc++) {
		Py_INCREF(*exc->exc_this);
		if (PyModule_AddObject(module, exc->exc_name, *exc->exc_this) < 0)
			return -1;
	}
	return 0;
failed:
	if (longname != NULL)
		PyMem_FREE(longname);
	Py_DECREF(name);
	return -1;
}
Exemplo n.º 4
0
/* TODO, multi-dimensional arrays */
int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
{
	int len = RNA_property_array_length(ptr, prop);
	int type;
	int i;

	if (len == 0) /* possible with dynamic arrays */
		return 0;

	if (RNA_property_array_dimension(ptr, prop, NULL) > 1) {
		PyErr_SetString(PyExc_TypeError, "PropertyRNA - multi dimensional arrays not supported yet");
		return -1;
	}

	type = RNA_property_type(prop);

	switch (type) {
		case PROP_FLOAT:
		{
			float value_f = PyFloat_AsDouble(value);
			if (value_f == -1 && PyErr_Occurred()) {
				PyErr_Clear();
				return 0;
			}
			else {
				float tmp[32];
				float *tmp_arr;

				if (len * sizeof(float) > sizeof(tmp)) {
					tmp_arr = PyMem_MALLOC(len * sizeof(float));
				}
				else {
					tmp_arr = tmp;
				}

				RNA_property_float_get_array(ptr, prop, tmp_arr);

				for (i = 0; i < len; i++) {
					if (tmp_arr[i] == value_f) {
						break;
					}
				}

				if (tmp_arr != tmp)
					PyMem_FREE(tmp_arr);

				return i < len ? 1 : 0;
			}
			break;
		}
		case PROP_BOOLEAN:
		case PROP_INT:
		{
			int value_i = PyLong_AsSsize_t(value);
			if (value_i == -1 && PyErr_Occurred()) {
				PyErr_Clear();
				return 0;
			}
			else {
				int tmp[32];
				int *tmp_arr;

				if (len * sizeof(int) > sizeof(tmp)) {
					tmp_arr = PyMem_MALLOC(len * sizeof(int));
				}
				else {
					tmp_arr = tmp;
				}

				if (type == PROP_BOOLEAN)
					RNA_property_boolean_get_array(ptr, prop, tmp_arr);
				else
					RNA_property_int_get_array(ptr, prop, tmp_arr);

				for (i = 0; i < len; i++) {
					if (tmp_arr[i] == value_i) {
						break;
					}
				}

				if (tmp_arr != tmp)
					PyMem_FREE(tmp_arr);

				return i < len ? 1 : 0;
			}
			break;
		}
	}

	/* should never reach this */
	PyErr_SetString(PyExc_TypeError, "PropertyRNA - type not in float/bool/int");
	return -1;
}
Exemplo n.º 5
0
static PyObject *
marshal_Load_internal(PyObject *py_stream, PyObject *py_callback, int skipcrc)
{
	// Return value: New Reference

	char *stream;
	Py_ssize_t size;

	char *s;
	char *end;

	int type = -1;   // current object type
	int shared = -1; // indicates whether current object is shared
	int i;

	char *error = "NO ERROR SPECIFIED";
	char errortext[256];

	Py_ssize_t length = 0;  // generic length value.

	int shared_mapsize;
	int shared_count;  // shared object index counter
	int *shared_map;  // points to shared object mapping at end of stream
	PyObject **shared_obj = NULL;  // holds the shared objects

	PyObject *obj = NULL;  // currently decoded object
	PyObject *result = NULL;  // final result

	int ct_ix = 0;
	struct Container ct_stack[MAX_DEPTH];
	struct Container *container = &ct_stack[0];

	if(PyString_AsStringAndSize(py_stream, &stream, &size) == -1)
		return NULL;

	s = stream;

	container->obj = NULL;
	container->type = 0;
	container->free = -1;
	container->index = 0;

	if(size < 6 || *s++ != PROTOCOL_ID)
	{
		int offset = 0;
		result = unpickle(py_stream, &offset);
		if(!result)
			goto cleanup;

		return result;
	}

	// how many shared objects in this stream?
	shared_mapsize = *(int32_t *)s;
	s += 4;

	// Security Check: assert there is enough data for that many items.
	if((5 + shared_mapsize*4) > size) 
	{
		PyErr_Format(UnmarshalError, "Not enough room in stream for map. Wanted %d, but have only %d bytes remaining...", (shared_mapsize*4), ((int)size-5));
		goto cleanup;
	}

	// ok, we got the map data right here...
	shared_map = (int32_t *)&stream[size - shared_mapsize * 4];

	// Security Check #2: assert all map entries are between 1 and shared_mapsize
	for(i=0; i<shared_mapsize; i++)
	{
		if( (shared_map[i] > shared_mapsize) || (shared_map[i] < 1) )
		{
			PyErr_SetString(UnmarshalError, "Bogus map data in marshal stream");
			goto cleanup;
		}
	}

	// the start of which is incidentally also the end of the object data.
	end = (char *)shared_map;

	// create object table
	shared_obj = PyMem_MALLOC(shared_mapsize * sizeof(PyObject *));
	if(!shared_obj)
		goto cleanup;

	// zero out object table
	for(shared_count = 0; shared_count < shared_mapsize; shared_count++)
		shared_obj[shared_count] = NULL;
	shared_count = 0;


	// start decoding.

	while(s < end)
	{
		// This outer loop is responsible for reading and decoding the next
		// object from the stream. The object is then handed to the inner loop,
		// which adds it to the current container, or returns it to the caller.

		// get type of next object to decode and check shared flag
		type = *s++;
		shared = type & SHARED_FLAG;
		type &= ~SHARED_FLAG;

		// if token uses a normal length value, read it now.
		if(needlength[type])
		{
			READ_LENGTH;
		}
		else
			length = 0;


#if MARSHAL_DEBUG
//		if(shared)
		{
			char text[220];

			DEBUG_INDENT;
			sprintf(text, "pos:%4d type:%s(0x%02x) shared:%d len:%4d map:[", s-stream, tokenname[type], type, shared?1:0, length);
			printf(text);
			for(i=0; i<shared_mapsize; i++)
				printf("%d(%d),", shared_obj[i], shared_obj[i] ? ((PyObject *)(shared_obj[i]))->ob_refcnt : 0);
			printf("]\r\n");
		}
#endif // MARSHAL_DEBUG

		switch(type) {
		//
		// break statement:
		//   attempts to add the newly decoded object (in the obj variable) to
		//   the currently building container object.
		//
		// continue statement:
		//   indicates the decoded object or type marker was handled/consumed
		//   by the case and should _not_ be added to the currently building
		//   container object or used in any other way; immediately decode a
		//   new object
		//

		//---------------------------------------------------------------------
		// SCALAR TYPES
		//---------------------------------------------------------------------

		case TYPE_INT8:
			CHECK_SIZE(1);
			obj = PyInt_FromLong(*(int8_t *)s);
			s++;
			break;

		case TYPE_INT16:
			CHECK_SIZE(2);
			obj = PyInt_FromLong(*(int16_t *)s);
			s += 2;
			break;

		case TYPE_INT32:
			CHECK_SIZE(4);
			obj = PyInt_FromLong(*(int32_t *)s);
			s += 4;
			break;

		case TYPE_INT64:
			CHECK_SIZE(8);
			obj = PyLong_FromLongLong(*(int64_t *)s);
			s += 8;
			break;

		case TYPE_LONG:
			CHECK_SIZE(length);
			if(!length)
				obj = PyLong_FromLong(0);
			else
			{
				obj = _PyLong_FromByteArray((unsigned char *)s, length, 1, 1);
				Py_INCREF(obj);
			}

			CHECK_SHARED(obj);
			s += length;
			break;

		case TYPE_FLOAT:
			CHECK_SIZE(8);
			obj = PyFloat_FromDouble(*(double *)s);
			s += 8;
			break;


		case TYPE_CHECKSUM:
			CHECK_SIZE(4);
			if(!skipcrc && (*(uint32_t *)s != (uint32_t)adler32(1, s, (unsigned long)(end-s))))
			{
				error = "checksum error";
				goto fail;
			}
			s += 4;
			// because this type does not yield an object, go grab another
			// object right away!
			continue;


		//---------------------------------------------------------------------
		// STRING TYPES
		//---------------------------------------------------------------------

		case TYPE_STRINGR:
			if (length < 1 || length >= PyList_GET_SIZE(string_table))
			{
				if(PyList_GET_SIZE(string_table))
					PyErr_Format(UnmarshalError, "Invalid string table index %d", (int)length);
				else
					PyErr_SetString(PyExc_RuntimeError, "_stringtable not initialized");
				goto cleanup;
			}
			obj = PyList_GET_ITEM(string_table, length);
			Py_INCREF(obj);
			break;

		case TYPE_STRING:
			// appears to be deprecated since machoVersion 213
			CHECK_SIZE(1);
			length = *(unsigned char *)s++;
			CHECK_SIZE(length);
			obj = PyString_FromStringAndSize(s, length);
			s += length;
			break;

		case TYPE_STRING1:
			CHECK_SIZE(1);
			obj = PyString_FromStringAndSize(s, 1);
			s++;
			break;

		case TYPE_STREAM:
			// fallthrough, can be treated as string.
		case TYPE_STRINGL:
			// fallthrough, deprecated since machoVersion 213
		case TYPE_BUFFER:
			// Type identifier re-used by CCP. treat as string.
			CHECK_SIZE(length);
			obj = PyString_FromStringAndSize(s, length);
			s += length;
			CHECK_SHARED(obj);
			break;

		case TYPE_UNICODE1:
			CHECK_SIZE(2);
#ifdef Py_UNICODE_WIDE
			obj = _PyUnicodeUCS4_FromUCS2((void *)s, 1);
#else
			obj = PyUnicode_FromWideChar((wchar_t *)s, 1);
#endif
			s += 2;
			break;

		case TYPE_UNICODE:
			CHECK_SIZE(length*2);
#ifdef Py_UNICODE_WIDE
			obj = _PyUnicodeUCS4_FromUCS2((void *)s, (int)length);
#else
			obj = PyUnicode_FromWideChar((wchar_t *)s, length);
#endif
			s += length*2;
			break;

		case TYPE_UTF8:
			CHECK_SIZE(length);
			obj = PyUnicode_DecodeUTF8(s, length, NULL);
			s += length;
			break;

		//---------------------------------------------------------------------
		// SEQUENCE/MAPPING TYPES
		//---------------------------------------------------------------------

		case TYPE_TUPLE1:
			NEW_SEQUENCE(TYPE_TUPLE, 1);
			continue;

		case TYPE_TUPLE2:
			NEW_SEQUENCE(TYPE_TUPLE, 2);
			continue;

		case TYPE_TUPLE:
			NEW_SEQUENCE(TYPE_TUPLE, (int)length);
			continue;

		case TYPE_LIST0:
			obj = PyList_New(0);
			CHECK_SHARED(obj);
			break;

		case TYPE_LIST1:
			NEW_SEQUENCE(TYPE_LIST, 1);
			continue;

		case TYPE_LIST:
			NEW_SEQUENCE(TYPE_LIST, (int)length);
			continue;

		case TYPE_DICT:
			if(length)
			{
				CHECK_SIZE(length*2);
				PUSH_CONTAINER(TYPE_DICT, (int)length*2);
				container->obj = PyDict_New();
				container->obj2 = NULL;
				container->index = 0;
				CHECK_SHARED(container->obj);
				continue;
			}
			else
			{
				obj = PyDict_New();
				CHECK_SHARED(obj);
				break;
			}


		//---------------------------------------------------------------------
		// OBJECT TYPES
		//---------------------------------------------------------------------

		case TYPE_REF:
			// length value is index in sharedobj array!
			if((length < 1 || length > shared_mapsize))
			{
				error = "Shared reference index out of range";
				goto fail;
			}

			if(!(obj = shared_obj[length-1]))
			{
				error = "Shared reference points to invalid object";
				goto fail;
			}

			Py_INCREF(obj);
			//printf("Getting object %d from %d (refs:%d)\r\n", (int)obj, length-1, obj->ob_refcnt);
			break;

		case TYPE_GLOBAL:
		{
			PyObject *name;
			CHECK_SIZE(length);
 			name = PyString_FromStringAndSize(s, length);
			if(!name)
				goto cleanup;
			s += length;
			if(!(obj = find_global(name)))
			{
				// exception should be set by find_global
				goto cleanup;
			}

			Py_DECREF(name);

			CHECK_SHARED(obj);
			break;
		}

		case TYPE_DBROW:
		case TYPE_INSTANCE:
		case TYPE_NEWOBJ:
		case TYPE_REDUCE:
			PUSH_CONTAINER(type, -1);
			container->obj = NULL;
			RESERVE_SLOT(container->index);
			continue;

		case TYPE_MARK:
			// this is a marker, not a real object. list/dict iterators check
			// for this type, but it can't be instantiated.
			break;

		default:
			if((obj = constants[type]))
			{
				Py_INCREF(obj);
			}
			else
			{
				error = "Unsupported type";
				goto fail;
			}
		}


		// object decoding and construction done!

		if(!obj && type != TYPE_MARK)
		{
			// if obj is somehow NULL, whatever caused it is expected to have
			// set an exception at this point.
			goto cleanup;
		}

#if MARSHAL_DEBUG
/*
if(obj && obj->ob_refcnt < 0)
{
	char b[200];
	sprintf(b, "type: %d, refcount: %d", type, obj->ob_refcnt);
	DEBUG(b);
}
*/
if(obj) {
	DEBUG_INDENT;
	printf("`-- ");
	PyObject_Print(obj, stdout, 0);
	printf("\r\n");
	fflush(stdout);
}
else
{
	DEBUG_INDENT;
	printf("*** MARK\r\n");
}
#endif // MARSHAL_DEBUG

		while(1)
		{
			// This inner loop does one of two things:
			//
			// - return the finished object to the caller if we're at the root
			//   container.
			//
			// - add the object to the current container in a container-
			//   specific manner. note that ownership of the reference is to be
			//   given to the container object.

#if MARSHAL_DEBUG
		{ 
			//char text[220];
			DEBUG_INDENT;
			printf("container ix:%d (%08lx) type:%s[0x%02x] free:%d index:%d\r\n", ct_ix, container->obj, tokenname[container->type], container->type, container->free, container->index);
		}
#endif // MARSHAL_DEBUG

/*			if(!container->obj) {
				error = "Root container popped off stack";
				goto fail;
			}
*/
			switch(container->type) {
				case TYPE_TUPLE:
					// tuples steal references.
					PyTuple_SET_ITEM(container->obj, container->index++, obj);
					break;

				case TYPE_LIST:
					// lists steal references.
					PyList_SET_ITEM(container->obj, container->index++, obj);
					break;


				case TYPE_DBROW:
					if(container->obj)
					{
						// we have an initialized DBRow. current object is a
						// non-scalar object for the row. append it.
						if(!dbrow_append_internal((PyDBRowObject *)container->obj, obj))
						{
							// append call will have set an exception here.
							goto cleanup;
						}
					}
					else
					{
						// we now have a DBRowDescriptor, and the header data
						// should follow. Pull it and create the DBRow.
						READ_LENGTH;
						CHECK_SIZE(length);
						container->obj = PyDBRow_New((PyDBRowDescriptorObject *)obj, s, (int)length);
						container->free = 1+((PyDBRowDescriptorObject *)obj)->rd_num_objects;

						if(!container->obj)
							goto cleanup;
						Py_DECREF(obj);
						s += length;

						// add as shared object, if neccessary...
						UPDATE_SLOT(container->index, container->obj);

					}
					break;


				case TYPE_INSTANCE:
				{
					PyObject *cls;

					if(container->free == -1)
					{
						// create class instance
						if(!(cls = find_global(obj)))
							goto cleanup;
						container->obj = PyInstance_NewRaw(cls, 0);
						Py_DECREF(cls);
						if(!container->obj)
							goto cleanup;
						UPDATE_SLOT(container->index, container->obj);
						Py_DECREF(obj);
						break;
					}

					if(container->free == -2)
					{
						container->free = 1;
						// set state.
						if(!set_state(container->obj, obj))
							goto cleanup;

						Py_DECREF(obj);
						break;
					}

					error = "invalid container state";
					goto fail;
				}


				case TYPE_NEWOBJ:
				{
					PyObject *cls, *args, *__new__, *state;

					// instantiate the object...
					if(!(args = PyTuple_GetItem(obj, 0)))
						goto cleanup;
					if(!(cls = PyTuple_GetItem(args, 0)))
						goto cleanup;

					__new__ = PyObject_GetAttr(cls, py__new__);
					if(!__new__)
						goto cleanup;

					container->obj = PyObject_CallObject(__new__, args);
					Py_DECREF(__new__);
					if(!container->obj)
						goto cleanup;

					// add as shared object, if neccessary...
					UPDATE_SLOT(container->index, container->obj);

					// is there state data?
					if(PyTuple_GET_SIZE(obj) > 1)
					{
						state = PyTuple_GET_ITEM(obj, 1);
						if(!set_state(container->obj, state))
							goto cleanup;
					}

					Py_DECREF(obj);

					// switch to list iterator
					LIST_ITERATOR;
					break;
				}


				case TYPE_REDUCE:
				{
					PyObject *callable, *args, *state;

					if(!(args = PyTuple_GetItem(obj, 1)))
						goto cleanup;
					if(!(callable = PyTuple_GET_ITEM(obj, 0)))
						goto cleanup;

					if(!(container->obj = PyObject_CallObject(callable, args)))
						goto cleanup;

					UPDATE_SLOT(container->index, container->obj);

					if(PyTuple_GET_SIZE(obj) > 2)
					{
						state = PyTuple_GET_ITEM(obj, 2);
						if(!set_state(container->obj, state))
							goto cleanup;
					}

					Py_DECREF(obj);

					// switch to list iterator
					LIST_ITERATOR;
					break;
				}


				case TYPE_LIST_ITERATOR:
					if(type == TYPE_MARK)
					{
						// clear mark so nested iterator containers do not get terminated prematurely.
						type = -1;

						// decref the append method
						Py_XDECREF(container->obj2);
						container->obj2 = NULL;
						container->type = TYPE_DICT_ITERATOR;
						break;
					}

					if(!container->obj2)
					{
						// grab the append method from the container and keep
						// it around for speed.
						if(!(container->obj2 = PyObject_GetAttr(container->obj, pyappend)))
							goto cleanup;
					}

					if(!PyObject_CallFunctionObjArgs(container->obj2, obj, NULL))
						goto cleanup;

#if MARSHAL_DEBUG
					DEBUG_INDENT;
					printf("Appended %08lx to %08lx\r\n", obj, container->obj);
#endif // MARSHAL_DEBUG

					Py_DECREF(obj);
					break;


				case TYPE_DICT_ITERATOR:
					if(type == TYPE_MARK)
					{
						// clear mark so nested iterator containers do not get terminated prematurely.
						type = -1;

						// we're done with dict iter. container is finished.
						container->free = 1;
						break;
					}
					POPULATE_DICT(container->obj2, obj);
					break;


				case TYPE_DICT:
					POPULATE_DICT(obj, container->obj2);
					break;


				case 0:
					// we're at the root. return the object to caller.
					result = obj;

					// avoid decreffing this object.
					obj = NULL;
					goto cleanup;
			}

			container->free--;
			if(container->free)
				// still room in this container.
				// break out of container handling to get next object for it.
				break;

			// this container is done, it is the next object to put into the
			// container under it!
			obj = container->obj;

			// switch context to said older container
			POP_CONTAINER;
		}

		// we've processed the object. clear it for next one.
		obj = NULL;
	}

	// if we get here, we're out of data, but it's a "clean" eof; we ran out
	// of data while expecting a new object...
	error = "Not enough objects in stream";

fail:
	PyErr_Format(UnmarshalError, "%s - type:0x%02x ctype:0x%02x len:%d share:%d pos:%d size:%d", error, type, container->type, (int)length, shared, (int)(s-stream), (int)(size));

cleanup:
	// on any error the current object we were working on will be unassociated
	// with anything, decref it. if decode was succesful or an object failed to
	// be created, it will be NULL anyway.
	Py_XDECREF(obj);

	// same story for containers...
	while(container->type)
	{
		Py_XDECREF(container->obj);
		// possibly unassociated object for dict entry?
		if(container->type == TYPE_DICT || container->type == TYPE_DICT_ITERATOR)
		{
			Py_XDECREF(container->obj2);
		}

		POP_CONTAINER;
	}

	if(shared_obj)
	{
		/* shared object list held a safety ref to all objects, decref em */
		int i;
		for(i=0; i<shared_mapsize; i++)
			Py_XDECREF(shared_obj[i]);

		/* and free the list */
		PyMem_FREE(shared_obj);
	}
	return result;
}
Exemplo n.º 6
0
static PyObject *
complex_subtype_from_string(PyTypeObject *type, PyObject *v)
{
    const char *s, *start;
    char *end;
    double x=0.0, y=0.0, z;
    int got_bracket=0;
#ifdef Py_USING_UNICODE
    char *s_buffer = NULL;
#endif
    Py_ssize_t len;

    if (PyString_Check(v)) {
        s = PyString_AS_STRING(v);
        len = PyString_GET_SIZE(v);
    }
#ifdef Py_USING_UNICODE
    else if (PyUnicode_Check(v)) {
        s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);
        if (s_buffer == NULL)
            return PyErr_NoMemory();
        if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
                                    PyUnicode_GET_SIZE(v),
                                    s_buffer,
                                    NULL))
            goto error;
        s = s_buffer;
        len = strlen(s);
    }
#endif
    else if (PyObject_AsCharBuffer(v, &s, &len)) {
        PyErr_SetString(PyExc_TypeError,
                        "complex() arg is not a string");
        return NULL;
    }

    /* position on first nonblank */
    start = s;
    while (Py_ISSPACE(*s))
        s++;
    if (*s == '(') {
        /* Skip over possible bracket from repr(). */
        got_bracket = 1;
        s++;
        while (Py_ISSPACE(*s))
            s++;
    }

    /* a valid complex string usually takes one of the three forms:

         <float>                  - real part only
         <float>j                 - imaginary part only
         <float><signed-float>j   - real and imaginary parts

       where <float> represents any numeric string that's accepted by the
       float constructor (including 'nan', 'inf', 'infinity', etc.), and
       <signed-float> is any string of the form <float> whose first
       character is '+' or '-'.

       For backwards compatibility, the extra forms

         <float><sign>j
         <sign>j
         j

       are also accepted, though support for these forms may be removed from
       a future version of Python.
    */

    /* first look for forms starting with <float> */
    z = PyOS_string_to_double(s, &end, NULL);
    if (z == -1.0 && PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_ValueError))
            PyErr_Clear();
        else
            goto error;
    }
    if (end != s) {
        /* all 4 forms starting with <float> land here */
        s = end;
        if (*s == '+' || *s == '-') {
            /* <float><signed-float>j | <float><sign>j */
            x = z;
            y = PyOS_string_to_double(s, &end, NULL);
            if (y == -1.0 && PyErr_Occurred()) {
                if (PyErr_ExceptionMatches(PyExc_ValueError))
                    PyErr_Clear();
                else
                    goto error;
            }
            if (end != s)
                /* <float><signed-float>j */
                s = end;
            else {
                /* <float><sign>j */
                y = *s == '+' ? 1.0 : -1.0;
                s++;
            }
            if (!(*s == 'j' || *s == 'J'))
                goto parse_error;
            s++;
        }
        else if (*s == 'j' || *s == 'J') {
            /* <float>j */
            s++;
            y = z;
        }
        else
            /* <float> */
            x = z;
    }
    else {
        /* not starting with <float>; must be <sign>j or j */
        if (*s == '+' || *s == '-') {
            /* <sign>j */
            y = *s == '+' ? 1.0 : -1.0;
            s++;
        }
        else
            /* j */
            y = 1.0;
        if (!(*s == 'j' || *s == 'J'))
            goto parse_error;
        s++;
    }

    /* trailing whitespace and closing bracket */
    while (Py_ISSPACE(*s))
        s++;
    if (got_bracket) {
        /* if there was an opening parenthesis, then the corresponding
           closing parenthesis should be right here */
        if (*s != ')')
            goto parse_error;
        s++;
        while (Py_ISSPACE(*s))
            s++;
    }

    /* we should now be at the end of the string */
    if (s-start != len)
        goto parse_error;


#ifdef Py_USING_UNICODE
    if (s_buffer)
        PyMem_FREE(s_buffer);
#endif
    return complex_subtype_from_doubles(type, x, y);

parse_error:
    PyErr_SetString(PyExc_ValueError,
                    "complex() arg is a malformed string");
error:
#ifdef Py_USING_UNICODE
    if (s_buffer)
        PyMem_FREE(s_buffer);
#endif
    return NULL;
}
Exemplo n.º 7
0
static int
tok_nextc(register struct tok_state *tok)
{
    for (;;) {
        if (tok->cur != tok->inp) {
            return Py_CHARMASK(*tok->cur++); /* Fast path */
        }
        if (tok->done != E_OK)
            return EOF;
        if (tok->fp == NULL) {
            char *end = strchr(tok->inp, '\n');
            if (end != NULL)
                end++;
            else {
                end = strchr(tok->inp, '\0');
                if (end == tok->inp) {
                    tok->done = E_EOF;
                    return EOF;
                }
            }
            if (tok->start == NULL)
                tok->buf = tok->cur;
            tok->line_start = tok->cur;
            tok->lineno++;
            tok->inp = end;
            return Py_CHARMASK(*tok->cur++);
        }
        if (tok->prompt != NULL) {
            char *newtok = PyOS_Readline(stdin, stdout, tok->prompt);
            if (tok->nextprompt != NULL)
                tok->prompt = tok->nextprompt;
            if (newtok == NULL)
                tok->done = E_INTR;
            else if (*newtok == '\0') {
                PyMem_FREE(newtok);
                tok->done = E_EOF;
            }
#if !defined(PGEN) && defined(Py_USING_UNICODE)
            else if (tok_stdin_decode(tok, &newtok) != 0)
                PyMem_FREE(newtok);
#endif
            else if (tok->start != NULL) {
                size_t start = tok->start - tok->buf;
                size_t oldlen = tok->cur - tok->buf;
                size_t newlen = oldlen + strlen(newtok);
                char *buf = tok->buf;
                buf = (char *)PyMem_REALLOC(buf, newlen+1);
                tok->lineno++;
                if (buf == NULL) {
                    PyMem_FREE(tok->buf);
                    tok->buf = NULL;
                    PyMem_FREE(newtok);
                    tok->done = E_NOMEM;
                    return EOF;
                }
                tok->buf = buf;
                tok->cur = tok->buf + oldlen;
                tok->line_start = tok->cur;
                strcpy(tok->buf + oldlen, newtok);
                PyMem_FREE(newtok);
                tok->inp = tok->buf + newlen;
                tok->end = tok->inp + 1;
                tok->start = tok->buf + start;
            }
            else {
                tok->lineno++;
                if (tok->buf != NULL)
                    PyMem_FREE(tok->buf);
                tok->buf = newtok;
                tok->line_start = tok->buf;
                tok->cur = tok->buf;
                tok->line_start = tok->buf;
                tok->inp = strchr(tok->buf, '\0');
                tok->end = tok->inp + 1;
            }
        }
        else {
            int done = 0;
            Py_ssize_t cur = 0;
            char *pt;
            if (tok->start == NULL) {
                if (tok->buf == NULL) {
                    tok->buf = (char *)
                        PyMem_MALLOC(BUFSIZ);
                    if (tok->buf == NULL) {
                        tok->done = E_NOMEM;
                        return EOF;
                    }
                    tok->end = tok->buf + BUFSIZ;
                }
                if (decoding_fgets(tok->buf, (int)(tok->end - tok->buf),
                          tok) == NULL) {
                    tok->done = E_EOF;
                    done = 1;
                }
                else {
                    tok->done = E_OK;
                    tok->inp = strchr(tok->buf, '\0');
                    done = tok->inp[-1] == '\n';
                }
            }
            else {
                cur = tok->cur - tok->buf;
                if (decoding_feof(tok)) {
                    tok->done = E_EOF;
                    done = 1;
                }
                else
                    tok->done = E_OK;
            }
            tok->lineno++;
            /* Read until '\n' or EOF */
            while (!done) {
                Py_ssize_t curstart = tok->start == NULL ? -1 :
                          tok->start - tok->buf;
                Py_ssize_t curvalid = tok->inp - tok->buf;
                Py_ssize_t newsize = curvalid + BUFSIZ;
                char *newbuf = tok->buf;
                newbuf = (char *)PyMem_REALLOC(newbuf,
                                               newsize);
                if (newbuf == NULL) {
                    tok->done = E_NOMEM;
                    tok->cur = tok->inp;
                    return EOF;
                }
                tok->buf = newbuf;
                tok->inp = tok->buf + curvalid;
                tok->end = tok->buf + newsize;
                tok->start = curstart < 0 ? NULL :
                         tok->buf + curstart;
                if (decoding_fgets(tok->inp,
                               (int)(tok->end - tok->inp),
                               tok) == NULL) {
                    /* Break out early on decoding
                       errors, as tok->buf will be NULL
                     */
                    if (tok->decoding_erred)
                        return EOF;
                    /* Last line does not end in \n,
                       fake one */
                    strcpy(tok->inp, "\n");
                }
                tok->inp = strchr(tok->inp, '\0');
                done = tok->inp[-1] == '\n';
            }
            if (tok->buf != NULL) {
                tok->cur = tok->buf + cur;
                tok->line_start = tok->cur;
                /* replace "\r\n" with "\n" */
                /* For Mac leave the \r, giving a syntax error */
                pt = tok->inp - 2;
                if (pt >= tok->buf && *pt == '\r') {
                    *pt++ = '\n';
                    *pt = '\0';
                    tok->inp = pt;
                }
            }
        }
        if (tok->done != E_OK) {
            if (tok->prompt != NULL)
                PySys_WriteStderr("\n");
            tok->cur = tok->inp;
            return EOF;
        }
    }
    /*NOTREACHED*/
}
Exemplo n.º 8
0
static void
calcfirstset(grammar *g, dfa *d)
{
    int i, j;
    state *s;
    arc *a;
    int nsyms;
    int *sym;
    int nbits;
    static bitset dummy;
    bitset result;
    int type;
    dfa *d1;
    label *l0;

#ifndef NDEBUG
    printf("Calculate FIRST set for '%.*s'\n",
           (int)d->d_name_length, d->d_name);
#endif

    if (dummy == NULL)
        dummy = newbitset(1);
    if (d->d_first == dummy) {
        fprintf(stderr, "Left-recursion for '%.*s'\n",
                (int)d->d_name_length, d->d_name);
        return;
    }
    if (d->d_first != NULL) {
        fprintf(stderr, "Re-calculating FIRST set for '%.*s' ???\n",
                (int)d->d_name_length, d->d_name);
    }
    d->d_first = dummy;

    l0 = g->g_ll.ll_label;
    nbits = g->g_ll.ll_nlabels;
    result = newbitset(nbits);

    sym = (int *)PyMem_MALLOC(sizeof(int));
    if (sym == NULL)
        Py_FatalError("no mem for new sym in calcfirstset");
    nsyms = 1;
    sym[0] = findlabel(&g->g_ll, d->d_type, UC(NULL), 0);

    s = &d->d_state[d->d_initial];
    for (i = 0; i < s->s_narcs; i++) {
        a = &s->s_arc[i];
        for (j = 0; j < nsyms; j++) {
            if (sym[j] == a->a_lbl)
                break;
        }
        if (j >= nsyms) { /* New label */
            sym = (int *)PyMem_REALLOC(sym,
                                       sizeof(int) * (nsyms + 1));
            if (sym == NULL)
                Py_FatalError(
                    "no mem to resize sym in calcfirstset");
            sym[nsyms++] = a->a_lbl;
            type = l0[a->a_lbl].lb_type;
            if (ISNONTERMINAL(type)) {
                d1 = PyGrammar_FindDFA(g, type);
                if (d1->d_first == dummy) {
                    fprintf(stderr, "Left-recursion below '%.*s'\n",
                            (int)d->d_name_length, d->d_name);
                }
                else {
                    if (d1->d_first == NULL)
                        calcfirstset(g, d1);
                    mergebitset(result,
                                d1->d_first, nbits);
                }
            }
            else if (ISTERMINAL(type)) {
                addbit(result, a->a_lbl);
            }
        }
    }
    d->d_first = result;

    PyMem_FREE(sym);
}
Exemplo n.º 9
0
PyCodeObject *
PyCode_New(int argcount, int kwonlyargcount,
           int nlocals, int stacksize, int flags,
           PyObject *code, PyObject *consts, PyObject *names,
           PyObject *varnames, PyObject *freevars, PyObject *cellvars,
           PyObject *filename, PyObject *name, int firstlineno,
           PyObject *lnotab)
{
    PyCodeObject *co;
    unsigned char *cell2arg = NULL;
    Py_ssize_t i, n_cellvars;

    /* Check argument types */
    if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 ||
        code == NULL ||
        consts == NULL || !PyTuple_Check(consts) ||
        names == NULL || !PyTuple_Check(names) ||
        varnames == NULL || !PyTuple_Check(varnames) ||
        freevars == NULL || !PyTuple_Check(freevars) ||
        cellvars == NULL || !PyTuple_Check(cellvars) ||
        name == NULL || !PyUnicode_Check(name) ||
        filename == NULL || !PyUnicode_Check(filename) ||
        lnotab == NULL || !PyBytes_Check(lnotab) ||
        !PyObject_CheckReadBuffer(code)) {
        PyErr_BadInternalCall();
        return NULL;
    }

    /* Ensure that the filename is a ready Unicode string */
    if (PyUnicode_READY(filename) < 0)
        return NULL;

    n_cellvars = PyTuple_GET_SIZE(cellvars);
    intern_strings(names);
    intern_strings(varnames);
    intern_strings(freevars);
    intern_strings(cellvars);
    /* Intern selected string constants */
    for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) {
        PyObject *v = PyTuple_GetItem(consts, i);
        if (!all_name_chars(v))
            continue;
        PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i));
    }
    /* Create mapping between cells and arguments if needed. */
    if (n_cellvars) {
        Py_ssize_t total_args = argcount + kwonlyargcount +
            ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
        Py_ssize_t alloc_size = sizeof(unsigned char) * n_cellvars;
        int used_cell2arg = 0;
        cell2arg = PyMem_MALLOC(alloc_size);
        if (cell2arg == NULL)
            return NULL;
        memset(cell2arg, CO_CELL_NOT_AN_ARG, alloc_size);
        /* Find cells which are also arguments. */
        for (i = 0; i < n_cellvars; i++) {
            Py_ssize_t j;
            PyObject *cell = PyTuple_GET_ITEM(cellvars, i);
            for (j = 0; j < total_args; j++) {
                PyObject *arg = PyTuple_GET_ITEM(varnames, j);
                if (!PyUnicode_Compare(cell, arg)) {
                    cell2arg[i] = j;
                    used_cell2arg = 1;
                    break;
                }
            }
        }
        if (!used_cell2arg) {
            PyMem_FREE(cell2arg);
            cell2arg = NULL;
        }
    }
    co = PyObject_NEW(PyCodeObject, &PyCode_Type);
    if (co == NULL) {
        if (cell2arg)
            PyMem_FREE(cell2arg);
        return NULL;
    }
    co->co_argcount = argcount;
    co->co_kwonlyargcount = kwonlyargcount;
    co->co_nlocals = nlocals;
    co->co_stacksize = stacksize;
    co->co_flags = flags;
    Py_INCREF(code);
    co->co_code = code;
    Py_INCREF(consts);
    co->co_consts = consts;
    Py_INCREF(names);
    co->co_names = names;
    Py_INCREF(varnames);
    co->co_varnames = varnames;
    Py_INCREF(freevars);
    co->co_freevars = freevars;
    Py_INCREF(cellvars);
    co->co_cellvars = cellvars;
    co->co_cell2arg = cell2arg;
    Py_INCREF(filename);
    co->co_filename = filename;
    Py_INCREF(name);
    co->co_name = name;
    co->co_firstlineno = firstlineno;
    Py_INCREF(lnotab);
    co->co_lnotab = lnotab;
    co->co_zombieframe = NULL;
    co->co_weakreflist = NULL;
    return co;
}
Exemplo n.º 10
0
PyObject *
PyModule_Create2(struct PyModuleDef* module, int module_api_version)
{
    PyObject *d, *v, *n;
    PyMethodDef *ml;
    const char* name;
    PyModuleObject *m;
    PyInterpreterState *interp = PyThreadState_Get()->interp;
    if (interp->modules == NULL)
        Py_FatalError("Python import machinery not initialized");
    if (PyType_Ready(&moduledef_type) < 0)
        return NULL;
    if (module->m_base.m_index == 0) {
        max_module_number++;
        Py_REFCNT(module) = 1;
        Py_TYPE(module) = &moduledef_type;
        module->m_base.m_index = max_module_number;
    }
    name = module->m_name;
    if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) {
        int err;
        err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
            "Python C API version mismatch for module %.100s: "
            "This Python has API version %d, module %.100s has version %d.",
             name,
             PYTHON_API_VERSION, name, module_api_version);
        if (err)
            return NULL;
    }
    /* Make sure name is fully qualified.

       This is a bit of a hack: when the shared library is loaded,
       the module name is "package.module", but the module calls
       PyModule_Create*() with just "module" for the name.  The shared
       library loader squirrels away the true name of the module in
       _Py_PackageContext, and PyModule_Create*() will substitute this
       (if the name actually matches).
    */
    if (_Py_PackageContext != NULL) {
        char *p = strrchr(_Py_PackageContext, '.');
        if (p != NULL && strcmp(module->m_name, p+1) == 0) {
            name = _Py_PackageContext;
            _Py_PackageContext = NULL;
        }
    }
    if ((m = (PyModuleObject*)PyModule_New(name)) == NULL)
        return NULL;

    if (module->m_size > 0) {
        m->md_state = PyMem_MALLOC(module->m_size);
        if (!m->md_state) {
            PyErr_NoMemory();
            Py_DECREF(m);
            return NULL;
        }
        memset(m->md_state, 0, module->m_size);
    }

    d = PyModule_GetDict((PyObject*)m);
    if (module->m_methods != NULL) {
        n = PyUnicode_FromString(name);
        if (n == NULL) {
            Py_DECREF(m);
            return NULL;
        }
        for (ml = module->m_methods; ml->ml_name != NULL; ml++) {
            if ((ml->ml_flags & METH_CLASS) ||
                (ml->ml_flags & METH_STATIC)) {
                PyErr_SetString(PyExc_ValueError,
                                "module functions cannot set"
                                " METH_CLASS or METH_STATIC");
                Py_DECREF(n);
                Py_DECREF(m);
                return NULL;
            }
            v = PyCFunction_NewEx(ml, (PyObject*)m, n);
            if (v == NULL) {
                Py_DECREF(n);
                Py_DECREF(m);
                return NULL;
            }
            if (PyDict_SetItemString(d, ml->ml_name, v) != 0) {
                Py_DECREF(v);
                Py_DECREF(n);
                Py_DECREF(m);
                return NULL;
            }
            Py_DECREF(v);
        }
        Py_DECREF(n);
    }
    if (module->m_doc != NULL) {
        v = PyUnicode_FromString(module->m_doc);
        if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) {
            Py_XDECREF(v);
            Py_DECREF(m);
            return NULL;
        }
        Py_DECREF(v);
    }
    m->md_def = module;
    return (PyObject*)m;
}
Exemplo n.º 11
0
void *
PyMem_Malloc(size_t nbytes)
{
	return PyMem_MALLOC(nbytes);
}
Exemplo n.º 12
0
/* Would be nice if python had this built in */
void PyC_RunQuicky(const char *filepath, int n, ...)
{
	FILE *fp= fopen(filepath, "r");

	if(fp) {
		PyGILState_STATE gilstate= PyGILState_Ensure();

		va_list vargs;	

		int *sizes= PyMem_MALLOC(sizeof(int) * (n / 2));
		int i;

		PyObject *py_dict = PyC_DefaultNameSpace(filepath);
		PyObject *values= PyList_New(n / 2); /* namespace owns this, dont free */

		PyObject *py_result, *ret;

		PyObject *struct_mod= PyImport_ImportModule("struct");
		PyObject *calcsize= PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */
		PyObject *pack= PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */
		PyObject *unpack= PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */

		Py_DECREF(struct_mod);

		va_start(vargs, n);
		for (i=0; i * 2<n; i++) {
			char *format = va_arg(vargs, char *);
			void *ptr = va_arg(vargs, void *);

			ret= PyObject_CallFunction(calcsize, (char *)"s", format);

			if(ret) {
				sizes[i]= PyLong_AsSsize_t(ret);
				Py_DECREF(ret);
				ret = PyObject_CallFunction(unpack, (char *)"sy#", format, (char *)ptr, sizes[i]);
			}

			if(ret == NULL) {
				printf("PyC_InlineRun error, line:%d\n", __LINE__);
				PyErr_Print();
				PyErr_Clear();

				PyList_SET_ITEM(values, i, Py_None); /* hold user */
				Py_INCREF(Py_None);

				sizes[i]= 0;
			}
			else {
				if(PyTuple_GET_SIZE(ret) == 1) {
					/* convenience, convert single tuples into single values */
					PyObject *tmp= PyTuple_GET_ITEM(ret, 0);
					Py_INCREF(tmp);
					Py_DECREF(ret);
					ret = tmp;
				}

				PyList_SET_ITEM(values, i, ret); /* hold user */
			}
		}
		va_end(vargs);
		
		/* set the value so we can access it */
		PyDict_SetItemString(py_dict, "values", values);

		py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict);

		fclose(fp);

		if(py_result) {

			/* we could skip this but then only slice assignment would work
			 * better not be so strict */
			values= PyDict_GetItemString(py_dict, "values");

			if(values && PyList_Check(values)) {

				/* dont use the result */
				Py_DECREF(py_result);
				py_result= NULL;

				/* now get the values back */
				va_start(vargs, n);
				for (i=0; i*2 <n; i++) {
					char *format = va_arg(vargs, char *);
					void *ptr = va_arg(vargs, void *);
					
					PyObject *item;
					PyObject *item_new;
					/* prepend the string formatting and remake the tuple */
					item= PyList_GET_ITEM(values, i);
					if(PyTuple_CheckExact(item)) {
						int ofs= PyTuple_GET_SIZE(item);
						item_new= PyTuple_New(ofs + 1);
						while(ofs--) {
							PyObject *member= PyTuple_GET_ITEM(item, ofs);
							PyTuple_SET_ITEM(item_new, ofs + 1, member);
							Py_INCREF(member);
						}

						PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format));
					}
					else {
						item_new= Py_BuildValue("sO", format, item);
					}

					ret = PyObject_Call(pack, item_new, NULL);

					if(ret) {
						/* copy the bytes back into memory */
						memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]);
						Py_DECREF(ret);
					}
					else {
						printf("PyC_InlineRun error on arg '%d', line:%d\n", i, __LINE__);
						PyC_ObSpit("failed converting:", item_new);
						PyErr_Print();
						PyErr_Clear();
					}

					Py_DECREF(item_new);
				}
				va_end(vargs);
			}
			else {
				printf("PyC_InlineRun error, 'values' not a list, line:%d\n", __LINE__);
			}
		}
Exemplo n.º 13
0
PyCodeObject *
PyCode_New(int argcount, int kwonlyargcount,
           int nlocals, int stacksize, int flags,
           PyObject *code, PyObject *consts, PyObject *names,
           PyObject *varnames, PyObject *freevars, PyObject *cellvars,
           PyObject *filename, PyObject *name, int firstlineno,
           PyObject *lnotab)
{
    PyCodeObject *co;
    unsigned char *cell2arg = NULL;
    Py_ssize_t i, n_cellvars;

    // We originally had a Py_GUARD here, and all was well.  It was never hit
    // by normal parallel contexts.  Then, after misusing datrie, it was
    // suddenly being hit -- turns out Cython calls PyCode_New() when an
    // exception occurs in order to do stuff.  I've since perused the body and
    // nothing immediately stands out as being unsafe for calling in a
    // parallel context (i.e. no random mallocs or static storage), so, let's
    // remove the guard and see what happens.
    //Py_GUARD();

    /* Check argument types */
    if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 ||
        code == NULL ||
        consts == NULL || !PyTuple_Check(consts) ||
        names == NULL || !PyTuple_Check(names) ||
        varnames == NULL || !PyTuple_Check(varnames) ||
        freevars == NULL || !PyTuple_Check(freevars) ||
        cellvars == NULL || !PyTuple_Check(cellvars) ||
        name == NULL || !PyUnicode_Check(name) ||
        filename == NULL || !PyUnicode_Check(filename) ||
        lnotab == NULL || !PyBytes_Check(lnotab) ||
        !PyObject_CheckReadBuffer(code)) {
        PyErr_BadInternalCall();
        return NULL;
    }

    /* Ensure that the filename is a ready Unicode string */
    if (PyUnicode_READY(filename) < 0)
        return NULL;

    n_cellvars = PyTuple_GET_SIZE(cellvars);
    intern_strings(names);
    intern_strings(varnames);
    intern_strings(freevars);
    intern_strings(cellvars);
    /* Intern selected string constants */
    for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) {
        PyObject *v = PyTuple_GetItem(consts, i);
        if (!all_name_chars(v))
            continue;
        PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i));
    }
    /* Create mapping between cells and arguments if needed. */
    if (n_cellvars) {
        Py_ssize_t total_args = argcount + kwonlyargcount +
            ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
        Py_ssize_t alloc_size = sizeof(unsigned char) * n_cellvars;
        int used_cell2arg = 0;
        cell2arg = PyMem_MALLOC(alloc_size);
        if (cell2arg == NULL)
            return NULL;
        memset(cell2arg, CO_CELL_NOT_AN_ARG, alloc_size);
        /* Find cells which are also arguments. */
        for (i = 0; i < n_cellvars; i++) {
            Py_ssize_t j;
            PyObject *cell = PyTuple_GET_ITEM(cellvars, i);
            for (j = 0; j < total_args; j++) {
                PyObject *arg = PyTuple_GET_ITEM(varnames, j);
                if (!PyUnicode_Compare(cell, arg)) {
                    cell2arg[i] = j;
                    used_cell2arg = 1;
                    break;
                }
            }
        }
        if (!used_cell2arg) {
            PyMem_FREE(cell2arg);
            cell2arg = NULL;
        }
    }
    co = PyObject_NEW(PyCodeObject, &PyCode_Type);
    if (co == NULL) {
        if (cell2arg)
            PyMem_FREE(cell2arg);
        return NULL;
    }
    co->co_argcount = argcount;
    co->co_kwonlyargcount = kwonlyargcount;
    co->co_nlocals = nlocals;
    co->co_stacksize = stacksize;
    co->co_flags = flags;
    Py_INCREF(code);
    co->co_code = code;
    Py_INCREF(consts);
    co->co_consts = consts;
    Py_INCREF(names);
    co->co_names = names;
    Py_INCREF(varnames);
    co->co_varnames = varnames;
    Py_INCREF(freevars);
    co->co_freevars = freevars;
    Py_INCREF(cellvars);
    co->co_cellvars = cellvars;
    co->co_cell2arg = cell2arg;
    Py_INCREF(filename);
    co->co_filename = filename;
    Py_INCREF(name);
    co->co_name = name;
    co->co_firstlineno = firstlineno;
    Py_INCREF(lnotab);
    co->co_lnotab = lnotab;
    co->co_zombieframe = NULL;
    co->co_weakreflist = NULL;
    return co;
}
Exemplo n.º 14
0
/*
   mymemreplace

   Return a string in which all occurrences of PAT in memory STR are
   replaced with SUB.

   If length of PAT is less than length of STR or there are no occurrences
   of PAT in STR, then the original string is returned. Otherwise, a new
   string is allocated here and returned.

   on return, out_len is:
       the length of output string, or
       -1 if the input string is returned, or
       unchanged if an error occurs (no memory).

   return value is:
       the new string allocated locally, or
       NULL if an error occurred.
*/
static char *
mymemreplace(const char *str, Py_ssize_t len,		/* input string */
             const char *pat, Py_ssize_t pat_len,	/* pattern string to find */
             const char *sub, Py_ssize_t sub_len,	/* substitution string */
             Py_ssize_t count,				/* number of replacements */
	     Py_ssize_t *out_len)
{
	char *out_s;
	char *new_s;
	Py_ssize_t nfound, offset, new_len;

	if (len == 0 || pat_len > len)
		goto return_same;

	/* find length of output string */
	nfound = mymemcnt(str, len, pat, pat_len);
	if (count < 0)
		count = PY_SSIZE_T_MAX;
	else if (nfound > count)
		nfound = count;
	if (nfound == 0)
		goto return_same;

	new_len = len + nfound*(sub_len - pat_len);
	if (new_len == 0) {
		/* Have to allocate something for the caller to free(). */
		out_s = (char *)PyMem_MALLOC(1);
		if (out_s == NULL)
			return NULL;
		out_s[0] = '\0';
	}
	else {
		assert(new_len > 0);
		new_s = (char *)PyMem_MALLOC(new_len);
		if (new_s == NULL)
			return NULL;
		out_s = new_s;

		for (; count > 0 && len > 0; --count) {
			/* find index of next instance of pattern */
			offset = mymemfind(str, len, pat, pat_len);
			if (offset == -1)
				break;

			/* copy non matching part of input string */
			memcpy(new_s, str, offset);
			str += offset + pat_len;
			len -= offset + pat_len;

			/* copy substitute into the output string */
			new_s += offset;
			memcpy(new_s, sub, sub_len);
			new_s += sub_len;
		}
		/* copy any remaining values into output string */
		if (len > 0)
			memcpy(new_s, str, len);
	}
	*out_len = new_len;
	return out_s;

  return_same:
	*out_len = -1;
	return (char *)str; /* cast away const */
}
Exemplo n.º 15
0
int
PyModule_ExecDef(PyObject *module, PyModuleDef *def)
{
    PyModuleDef_Slot *cur_slot;
    const char *name;
    int ret;

    name = PyModule_GetName(module);
    if (name == NULL) {
        return -1;
    }

    if (def->m_size >= 0) {
        PyModuleObject *md = (PyModuleObject*)module;
        if (md->md_state == NULL) {
            /* Always set a state pointer; this serves as a marker to skip
             * multiple initialization (importlib.reload() is no-op) */
            md->md_state = PyMem_MALLOC(def->m_size);
            if (!md->md_state) {
                PyErr_NoMemory();
                return -1;
            }
            memset(md->md_state, 0, def->m_size);
        }
    }

    if (def->m_slots == NULL) {
        return 0;
    }

    for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) {
        switch (cur_slot->slot) {
            case Py_mod_create:
                /* handled in PyModule_FromDefAndSpec2 */
                break;
            case Py_mod_exec:
                ret = ((int (*)(PyObject *))cur_slot->value)(module);
                if (ret != 0) {
                    if (!PyErr_Occurred()) {
                        PyErr_Format(
                            PyExc_SystemError,
                            "execution of module %s failed without setting an exception",
                            name);
                    }
                    return -1;
                }
                if (PyErr_Occurred()) {
                    PyErr_Format(
                        PyExc_SystemError,
                        "execution of module %s raised unreported exception",
                        name);
                    return -1;
                }
                break;
            default:
                PyErr_Format(
                    PyExc_SystemError,
                    "module %s initialized with unknown slot %i",
                    name, cur_slot->slot);
                return -1;
        }
    }
    return 0;
}
Exemplo n.º 16
0
PyObject *
PyModule_Create2(struct PyModuleDef* module, int module_api_version)
{
    const char* name;
    PyModuleObject *m;
    PyInterpreterState *interp = PyThreadState_Get()->interp;
    if (interp->modules == NULL)
        Py_FatalError("Python import machinery not initialized");
    if (!PyModuleDef_Init(module))
        return NULL;
    name = module->m_name;
    if (!check_api_version(name, module_api_version)) {
        return NULL;
    }
    if (module->m_slots) {
        PyErr_Format(
            PyExc_SystemError,
            "module %s: PyModule_Create is incompatible with m_slots", name);
        return NULL;
    }
    /* Make sure name is fully qualified.

       This is a bit of a hack: when the shared library is loaded,
       the module name is "package.module", but the module calls
       PyModule_Create*() with just "module" for the name.  The shared
       library loader squirrels away the true name of the module in
       _Py_PackageContext, and PyModule_Create*() will substitute this
       (if the name actually matches).
    */
    if (_Py_PackageContext != NULL) {
        const char *p = strrchr(_Py_PackageContext, '.');
        if (p != NULL && strcmp(module->m_name, p+1) == 0) {
            name = _Py_PackageContext;
            _Py_PackageContext = NULL;
        }
    }
    if ((m = (PyModuleObject*)PyModule_New(name)) == NULL)
        return NULL;

    if (module->m_size > 0) {
        m->md_state = PyMem_MALLOC(module->m_size);
        if (!m->md_state) {
            PyErr_NoMemory();
            Py_DECREF(m);
            return NULL;
        }
        memset(m->md_state, 0, module->m_size);
    }

    if (module->m_methods != NULL) {
        if (PyModule_AddFunctions((PyObject *) m, module->m_methods) != 0) {
            Py_DECREF(m);
            return NULL;
        }
    }
    if (module->m_doc != NULL) {
        if (PyModule_SetDocString((PyObject *) m, module->m_doc) != 0) {
            Py_DECREF(m);
            return NULL;
        }
    }
    m->md_def = module;
    return (PyObject*)m;
}
Exemplo n.º 17
0
/**
 * PyOS_ascii_strtod:
 * @nptr:    the string to convert to a numeric value.
 * @endptr:  if non-%NULL, it returns the character after
 *           the last character used in the conversion.
 *
 * Converts a string to a #gdouble value.
 * This function behaves like the standard strtod() function
 * does in the C locale. It does this without actually
 * changing the current locale, since that would not be
 * thread-safe.
 *
 * This function is typically used when reading configuration
 * files or other non-user input that should be locale independent.
 * To handle input from the user you should normally use the
 * locale-sensitive system strtod() function.
 *
 * If the correct value would cause overflow, plus or minus %HUGE_VAL
 * is returned (according to the sign of the value), and %ERANGE is
 * stored in %errno. If the correct value would cause underflow,
 * zero is returned and %ERANGE is stored in %errno.
 * If memory allocation fails, %ENOMEM is stored in %errno.
 *
 * This function resets %errno before calling strtod() so that
 * you can reliably detect overflow and underflow.
 *
 * Return value: the #gdouble value.
 **/
double
PyOS_ascii_strtod(const char *nptr, char **endptr)
{
    char *fail_pos;
    double val = -1.0;
#ifndef ANDROID
    struct lconv *locale_data;
#endif
    const char *decimal_point;
    size_t decimal_point_len;
    const char *p, *decimal_point_pos;
    const char *end = NULL; /* Silence gcc */
    const char *digits_pos = NULL;
    int negate = 0;

    assert(nptr != NULL);

    fail_pos = NULL;

#ifdef ANDROID
    decimal_point = ".";
#else
    locale_data = localeconv();
    decimal_point = locale_data->decimal_point;
#endif
    decimal_point_len = strlen(decimal_point);

    assert(decimal_point_len != 0);

    decimal_point_pos = NULL;

    /* We process any leading whitespace and the optional sign manually,
       then pass the remainder to the system strtod.  This ensures that
       the result of an underflow has the correct sign. (bug #1725)  */

    p = nptr;
    /* Skip leading space */
    while (ISSPACE(*p))
        p++;

    /* Process leading sign, if present */
    if (*p == '-') {
        negate = 1;
        p++;
    } else if (*p == '+') {
        p++;
    }

    /* What's left should begin with a digit, a decimal point, or one of
       the letters i, I, n, N. It should not begin with 0x or 0X */
    if ((!ISDIGIT(*p) &&
         *p != '.' && *p != 'i' && *p != 'I' && *p != 'n' && *p != 'N')
        ||
        (*p == '0' && (p[1] == 'x' || p[1] == 'X')))
    {
        if (endptr)
            *endptr = (char*)nptr;
        errno = EINVAL;
        return val;
    }
    digits_pos = p;

    if (decimal_point[0] != '.' ||
        decimal_point[1] != 0)
    {
        while (ISDIGIT(*p))
            p++;

        if (*p == '.')
        {
            decimal_point_pos = p++;

            while (ISDIGIT(*p))
                p++;

            if (*p == 'e' || *p == 'E')
                p++;
            if (*p == '+' || *p == '-')
                p++;
            while (ISDIGIT(*p))
                p++;
            end = p;
        }
        else if (strncmp(p, decimal_point, decimal_point_len) == 0)
        {
            /* Python bug #1417699 */
            if (endptr)
                *endptr = (char*)nptr;
            errno = EINVAL;
            return val;
        }
        /* For the other cases, we need not convert the decimal
           point */
    }

    /* Set errno to zero, so that we can distinguish zero results
       and underflows */
    errno = 0;

    if (decimal_point_pos)
    {
        char *copy, *c;

        /* We need to convert the '.' to the locale specific decimal
           point */
        copy = (char *)PyMem_MALLOC(end - digits_pos +
                                    1 + decimal_point_len);
        if (copy == NULL) {
            if (endptr)
                *endptr = (char *)nptr;
            errno = ENOMEM;
            return val;
        }

        c = copy;
        memcpy(c, digits_pos, decimal_point_pos - digits_pos);
        c += decimal_point_pos - digits_pos;
        memcpy(c, decimal_point, decimal_point_len);
        c += decimal_point_len;
        memcpy(c, decimal_point_pos + 1,
               end - (decimal_point_pos + 1));
        c += end - (decimal_point_pos + 1);
        *c = 0;

        val = strtod(copy, &fail_pos);

        if (fail_pos)
        {
            if (fail_pos > decimal_point_pos)
                fail_pos = (char *)digits_pos +
                    (fail_pos - copy) -
                    (decimal_point_len - 1);
            else
                fail_pos = (char *)digits_pos +
                    (fail_pos - copy);
        }

        PyMem_FREE(copy);

    }
    else {
        val = strtod(digits_pos, &fail_pos);
    }

    if (fail_pos == digits_pos)
        fail_pos = (char *)nptr;

    if (negate && fail_pos != nptr)
        val = -val;

    if (endptr)
        *endptr = fail_pos;

    return val;
}