bool BINARY_OPERATION_ADD_BYTES_BYTES_INPLACE(PyObject **operand1, PyObject *operand2) { assert(operand1); CHECK_OBJECT(*operand1); CHECK_OBJECT(operand2); assert(PyBytes_CheckExact(*operand1)); assert(PyBytes_CheckExact(operand2)); if (Py_REFCNT(*operand1) == 1) { return BYTES_ADD_INCREMENTAL(operand1, operand2); } // Could concat bytes here more directly. PyObject *result = PyNumber_InPlaceAdd(*operand1, operand2); if (unlikely(result == NULL)) { return false; } // We got an object handed, that we have to release. Py_DECREF(*operand1); // That's our return value then. As we use a dedicated variable, it's // OK that way. *operand1 = result; return true; }
NUITKA_MAY_BE_UNUSED static bool BYTES_ADD_INCREMENTAL(PyObject **operand1, PyObject *operand2) { assert(PyBytes_CheckExact(*operand1)); assert(PyBytes_CheckExact(operand2)); // Buffer Py_buffer wb; wb.len = -1; if (PyObject_GetBuffer(operand2, &wb, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "can't concat %s to %s", Py_TYPE(operand2)->tp_name, Py_TYPE(*operand1)->tp_name); return false; } Py_ssize_t oldsize = PyBytes_GET_SIZE(*operand1); if (oldsize > PY_SSIZE_T_MAX - wb.len) { PyErr_NoMemory(); PyBuffer_Release(&wb); return false; } if (_PyBytes_Resize(operand1, oldsize + wb.len) < 0) { PyBuffer_Release(&wb); return false; } memcpy(PyBytes_AS_STRING(*operand1) + oldsize, wb.buf, wb.len); PyBuffer_Release(&wb); return true; }
static PyObject * _winapi_Overlapped_GetOverlappedResult_impl(OverlappedObject *self, int wait) /*[clinic end generated code: output=bdd0c1ed6518cd03 input=194505ee8e0e3565]*/ { BOOL res; DWORD transferred = 0; DWORD err; Py_BEGIN_ALLOW_THREADS res = GetOverlappedResult(self->handle, &self->overlapped, &transferred, wait != 0); Py_END_ALLOW_THREADS err = res ? ERROR_SUCCESS : GetLastError(); switch (err) { case ERROR_SUCCESS: case ERROR_MORE_DATA: case ERROR_OPERATION_ABORTED: self->completed = 1; self->pending = 0; break; case ERROR_IO_INCOMPLETE: break; default: self->pending = 0; return PyErr_SetExcFromWindowsErr(PyExc_IOError, err); } if (self->completed && self->read_buffer != NULL) { assert(PyBytes_CheckExact(self->read_buffer)); if (transferred != PyBytes_GET_SIZE(self->read_buffer) && _PyBytes_Resize(&self->read_buffer, transferred)) return NULL; } return Py_BuildValue("II", (unsigned) transferred, (unsigned) err); }
virtual const void *getFontTable(LETag tag) const { #if PY_MAJOR_VERSION >= 3 PyObject *key = PyUnicode_FromStringAndSize(NULL, 4); Py_UNICODE *s = PyUnicode_AS_UNICODE(key); #else PyObject *key = PyString_FromStringAndSize(NULL, 4); char *s = PyString_AS_STRING(key); #endif for (int i = 0; i < 4; ++i) { s[3 - i] = tag & 0xff; tag >>= 8; } PyObject *result = PyDict_GetItem(tables, key); if (result == NULL) { result = PyObject_CallMethodObjArgs((PyObject *) self, getFontTable_NAME, key, NULL); if (result == NULL) { if (PyErr_ExceptionMatches(PyExc_KeyError)) PyErr_Clear(); Py_DECREF(key); return NULL; } #if PY_MAJOR_VERSION >= 3 if (!PyBytes_CheckExact(result)) #else if (!PyString_CheckExact(result)) #endif { PyErr_SetObject(PyExc_TypeError, result); Py_DECREF(result); Py_DECREF(key); return NULL; } PyDict_SetItem(tables, key, result); Py_DECREF(result); Py_DECREF(key); } else Py_DECREF(key); #if PY_MAJOR_VERSION >= 3 return PyBytes_AS_STRING(result); #else return PyString_AS_STRING(result); #endif }
int crypto_byte_converter(PyObject *input, void* output) { char **message = output; if (input == Py_None) { *message = NULL; } else if (PyBytes_CheckExact(input)) { *message = PyBytes_AsString(input); } else { return 0; } return 1; }
static int inner_atohl(PyObject *o, unsigned long *ip_ul){ struct in_addr buf; char *ip_addr; #ifdef IS_PY3K if(PyUnicode_CheckExact(o)){ ip_addr = PyUnicode_AsUTF8(o); } else if (PyBytes_CheckExact(o)){ ip_addr = PyBytes_AsString(o); } else if (PyByteArray_CheckExact(o)){ ip_addr = PyByteArray_AsString(o); #else if(PyUnicode_CheckExact(o) || PyString_CheckExact(o)){ ip_addr = PyString_AsString(o); } else if (PyByteArray_CheckExact(o)){ ip_addr = PyByteArray_AsString(o); #endif } else { PyErr_SetString(PyExc_TypeError, "should be built-in string/bytes/byte array"); return 0; } if (ip_addr == NULL){ return 0; } if (inet_aton(ip_addr, &buf)){ *ip_ul = ntohl(buf.s_addr); return 1; }else{ PyErr_SetString(PyExc_ValueError, "illegal IP address string"); return 0; } } static PyObject * ip_store_atohl(PyObject *self, PyObject *o){ unsigned long ip_ul; if(inner_atohl(o, &ip_ul)){ return PyLong_FromUnsignedLong(ip_ul); }else{ return NULL; } }
static PyObject * overlapped_GetOverlappedResult(OverlappedObject *self, PyObject *waitobj) { int wait; BOOL res; DWORD transferred = 0; DWORD err; wait = PyObject_IsTrue(waitobj); if (wait < 0) return NULL; Py_BEGIN_ALLOW_THREADS res = GetOverlappedResult(self->handle, &self->overlapped, &transferred, wait != 0); Py_END_ALLOW_THREADS err = res ? ERROR_SUCCESS : GetLastError(); switch (err) { case ERROR_SUCCESS: case ERROR_MORE_DATA: case ERROR_OPERATION_ABORTED: self->completed = 1; self->pending = 0; break; case ERROR_IO_INCOMPLETE: break; default: self->pending = 0; return PyErr_SetExcFromWindowsErr(PyExc_IOError, err); } if (self->completed && self->read_buffer != NULL) { assert(PyBytes_CheckExact(self->read_buffer)); if (transferred != PyBytes_GET_SIZE(self->read_buffer) && _PyBytes_Resize(&self->read_buffer, transferred)) return NULL; } return Py_BuildValue("II", (unsigned) transferred, (unsigned) err); }
int set_str_list( const char* propname, PyObject* value, Py_ssize_t len, Py_ssize_t maxlen, char (*dest)[72]) { PyObject* str = NULL; Py_ssize_t input_len; Py_ssize_t i = 0; if (check_delete(propname, value)) { return -1; } if (maxlen == 0) { maxlen = 68; } if (!PySequence_Check(value)) { PyErr_Format( PyExc_TypeError, "'%s' must be a sequence of strings", propname); return -1; } if (PySequence_Size(value) != len) { PyErr_Format( PyExc_ValueError, "len(%s) must be %u", propname, (unsigned int)len); return -1; } /* We go through the list twice, once to verify that the list is in the correct format, and then again to do the data copy. This way, we won't partially copy the contents and then throw an exception. */ for (i = 0; i < len; ++i) { str = PySequence_GetItem(value, i); if (str == NULL) { return -1; } if (!(PyBytes_CheckExact(str) || PyUnicode_CheckExact(str))) { PyErr_Format( PyExc_TypeError, "'%s' must be a sequence of bytes or strings", propname); Py_DECREF(str); return -1; } input_len = PySequence_Size(str); if (input_len > maxlen) { PyErr_Format( PyExc_ValueError, "Each entry in '%s' must be less than %u characters", propname, (unsigned int)maxlen); Py_DECREF(str); return -1; } else if (input_len == -1) { Py_DECREF(str); return -1; } Py_DECREF(str); } for (i = 0; i < len; ++i) { str = PySequence_GetItem(value, i); if (str == NULL) { /* Theoretically, something has gone really wrong here, since we've already verified the list. */ PyErr_Clear(); PyErr_Format( PyExc_RuntimeError, "Input values have changed underneath us. Something is seriously wrong."); return -1; } if (set_string(propname, str, dest[i], maxlen)) { PyErr_Clear(); PyErr_Format( PyExc_RuntimeError, "Input values have changed underneath us. Something is seriously wrong."); Py_DECREF(str); return -1; } Py_DECREF(str); } return 0; }
PyObject* _PyCode_ConstantKey(PyObject *op) { PyObject *key; /* Py_None and Py_Ellipsis are singleton */ if (op == Py_None || op == Py_Ellipsis || PyLong_CheckExact(op) || PyBool_Check(op) || PyBytes_CheckExact(op) || PyUnicode_CheckExact(op) /* code_richcompare() uses _PyCode_ConstantKey() internally */ || PyCode_Check(op)) { key = PyTuple_Pack(2, Py_TYPE(op), op); } else if (PyFloat_CheckExact(op)) { double d = PyFloat_AS_DOUBLE(op); /* all we need is to make the tuple different in either the 0.0 * or -0.0 case from all others, just to avoid the "coercion". */ if (d == 0.0 && copysign(1.0, d) < 0.0) key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None); else key = PyTuple_Pack(2, Py_TYPE(op), op); } else if (PyComplex_CheckExact(op)) { Py_complex z; int real_negzero, imag_negzero; /* For the complex case we must make complex(x, 0.) different from complex(x, -0.) and complex(0., y) different from complex(-0., y), for any x and y. All four complex zeros must be distinguished.*/ z = PyComplex_AsCComplex(op); real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0; imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0; /* use True, False and None singleton as tags for the real and imag * sign, to make tuples different */ if (real_negzero && imag_negzero) { key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True); } else if (imag_negzero) { key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False); } else if (real_negzero) { key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None); } else { key = PyTuple_Pack(2, Py_TYPE(op), op); } } else if (PyTuple_CheckExact(op)) { Py_ssize_t i, len; PyObject *tuple; len = PyTuple_GET_SIZE(op); tuple = PyTuple_New(len); if (tuple == NULL) return NULL; for (i=0; i < len; i++) { PyObject *item, *item_key; item = PyTuple_GET_ITEM(op, i); item_key = _PyCode_ConstantKey(item); if (item_key == NULL) { Py_DECREF(tuple); return NULL; } PyTuple_SET_ITEM(tuple, i, item_key); } key = PyTuple_Pack(3, Py_TYPE(op), op, tuple); Py_DECREF(tuple); } else if (PyFrozenSet_CheckExact(op)) { Py_ssize_t pos = 0; PyObject *item; Py_hash_t hash; Py_ssize_t i, len; PyObject *tuple, *set; len = PySet_GET_SIZE(op); tuple = PyTuple_New(len); if (tuple == NULL) return NULL; i = 0; while (_PySet_NextEntry(op, &pos, &item, &hash)) { PyObject *item_key; item_key = _PyCode_ConstantKey(item); if (item_key == NULL) { Py_DECREF(tuple); return NULL; } assert(i < len); PyTuple_SET_ITEM(tuple, i, item_key); i++; } set = PyFrozenSet_New(tuple); Py_DECREF(tuple); if (set == NULL) return NULL; key = PyTuple_Pack(3, Py_TYPE(op), op, set); Py_DECREF(set); return key; } else { /* for other types, use the object identifier as a unique identifier * to ensure that they are seen as unequal. */ PyObject *obj_id = PyLong_FromVoidPtr(op); if (obj_id == NULL) return NULL; key = PyTuple_Pack(3, Py_TYPE(op), op, obj_id); Py_DECREF(obj_id); } return key; }
int main(int argc, char *argv[]) { char *inpath, *outpath; FILE *infile, *outfile = NULL; struct stat st; size_t text_size, data_size, n; char *text; unsigned char *data; PyObject *code, *marshalled; if (argc != 3) { fprintf(stderr, "need to specify input and output paths\n"); return 2; } inpath = argv[1]; outpath = argv[2]; infile = fopen(inpath, "rb"); if (infile == NULL) { fprintf(stderr, "cannot open '%s' for reading\n", inpath); return 1; } if (fstat(fileno(infile), &st)) { fclose(infile); fprintf(stderr, "cannot fstat '%s'\n", inpath); return 1; } text_size = st.st_size; text = (char *) malloc(text_size + 1); if (text == NULL) { fclose(infile); fprintf(stderr, "could not allocate %ld bytes\n", (long) text_size); return 1; } n = fread(text, 1, text_size, infile); fclose(infile); infile = NULL; if (n < text_size) { fprintf(stderr, "read too short: got %ld instead of %ld bytes\n", (long) n, (long) text_size); return 1; } text[text_size] = '\0'; Py_NoUserSiteDirectory++; Py_NoSiteFlag++; Py_IgnoreEnvironmentFlag++; Py_SetProgramName(L"./_freeze_importlib"); /* Don't install importlib, since it could execute outdated bytecode. */ _Py_InitializeEx_Private(1, 0); code = Py_CompileStringExFlags(text, "<frozen importlib._bootstrap>", Py_file_input, NULL, 0); if (code == NULL) goto error; marshalled = PyMarshal_WriteObjectToString(code, Py_MARSHAL_VERSION); Py_DECREF(code); if (marshalled == NULL) goto error; assert(PyBytes_CheckExact(marshalled)); data = (unsigned char *) PyBytes_AS_STRING(marshalled); data_size = PyBytes_GET_SIZE(marshalled); outfile = fopen(outpath, "wb"); if (outfile == NULL) { fprintf(stderr, "cannot open '%s' for writing\n", outpath); return 1; } fprintf(outfile, "%s\n", header); fprintf(outfile, "unsigned char _Py_M__importlib[] = {\n"); for (n = 0; n < data_size; n += 16) { size_t i, end = Py_MIN(n + 16, data_size); fprintf(outfile, " "); for (i = n; i < end; i++) { fprintf(outfile, "%d,", (unsigned int) data[i]); } fprintf(outfile, "\n"); } fprintf(outfile, "};\n"); Py_DECREF(marshalled); Py_Finalize(); if (infile) fclose(infile); if (outfile) { if (ferror(outfile)) { fprintf(stderr, "error when writing to '%s'\n", outpath); fclose(outfile); return 1; } fclose(outfile); } return 0; error: PyErr_Print(); Py_Finalize(); if (infile) fclose(infile); if (outfile) fclose(outfile); return 1; }
int set_str_list( const char* propname, PyObject* value, Py_ssize_t len, Py_ssize_t maxlen, char (*dest)[72]) { PyObject* str = NULL; char* str_char = NULL; Py_ssize_t str_len = 0; Py_ssize_t i = 0; if (check_delete(propname, value)) { return -1; } if (maxlen == 0) { maxlen = 68; } if (!PySequence_Check(value)) { PyErr_Format( PyExc_TypeError, "'%s' must be a sequence of strings", propname); return -1; } if (PySequence_Size(value) != len) { PyErr_Format( PyExc_ValueError, "len(%s) must be %u", propname, (unsigned int)len); return -1; } /* We go through the list twice, once to verify that the list is in the correct format, and then again to do the data copy. This way, we won't partially copy the contents and then throw an exception. */ for (i = 0; i < len; ++i) { str = PySequence_GetItem(value, i); if (str == NULL) { return -1; } #if PY3K if (!PyBytes_CheckExact(str)) { #else if (!PyString_CheckExact(str)) { #endif PyErr_Format( PyExc_TypeError, #if PY3K "'%s' must be a sequence of bytes", #else "'%s' must be a sequence of strings", #endif propname); Py_DECREF(str); return -1; } #if PY3K if (PyBytes_Size(str) > maxlen) { #else if (PyString_Size(str) > maxlen) { #endif PyErr_Format( PyExc_TypeError, #if PY3K "Each bytes in '%s' must be less than %u characters", #else "Each string in '%s' must be less than %u characters", #endif propname, (unsigned int)maxlen); Py_DECREF(str); return -1; } Py_DECREF(str); } for (i = 0; i < len; ++i) { str = PySequence_GetItem(value, i); if (str == NULL) { /* Theoretically, something has gone really wrong here, since we've already verified the list. */ PyErr_Format( PyExc_RuntimeError, "Input values have changed underneath us. Something is seriously wrong."); return -1; } /* We already know its a string of the correct length */ #if PY3K if (PyBytes_AsStringAndSize(str, &str_char, &str_len)) { #else if (PyString_AsStringAndSize(str, &str_char, &str_len)) { #endif /* Theoretically, something has gone really wrong here, since we've already verified the list. */ PyErr_Format( PyExc_RuntimeError, "Input values have changed underneath us. Something is seriously wrong."); Py_DECREF(str); return -1; } strncpy(dest[i], str_char, (size_t)maxlen); Py_DECREF(str); } return 0; } /*@null@*/ PyObject* get_pscards( /*@unused@*/ const char* propname, struct pscard* ps, int nps) { PyObject* result = NULL; PyObject* subresult = NULL; Py_ssize_t i = 0; if (nps < 0) { PyErr_SetString(PyExc_ValueError, "Object has no pscards"); return NULL; } result = PyList_New((Py_ssize_t)nps); if (result == NULL) { return NULL; } for (i = 0; i < (Py_ssize_t)nps; ++i) { subresult = Py_BuildValue("iis", ps[i].i, ps[i].m, ps[i].value); if (subresult == NULL) { Py_DECREF(result); return NULL; } if (PyList_SetItem(result, i, subresult)) { Py_DECREF(subresult); Py_DECREF(result); return NULL; } } return result; } int set_pscards( /*@unused@*/ const char* propname, PyObject* value, struct pscard** ps, int *nps, int *npsmax) { PyObject* subvalue = NULL; Py_ssize_t i = 0; Py_ssize_t size = 0; int ival = 0; int mval = 0; const char* strvalue = 0; void* newmem = NULL; if (!PySequence_Check(value)) return -1; size = PySequence_Size(value); if (size > 0x7fffffff) { /* Must be a 32-bit size */ return -1; } if (size > (Py_ssize_t)*npsmax) { newmem = malloc(sizeof(struct pscard) * size); if (newmem == NULL) { PyErr_SetString(PyExc_MemoryError, "Could not allocate memory."); return -1; } free(*ps); *ps = newmem; *npsmax = (int)size; } /* Verify the entire list for correct types first, so we don't have to undo anything copied into the canonical array. */ for (i = 0; i < size; ++i) { subvalue = PySequence_GetItem(value, i); if (subvalue == NULL) { return -1; } if (!PyArg_ParseTuple(subvalue, "iis", &ival, &mval, &strvalue)) { Py_DECREF(subvalue); return -1; } Py_DECREF(subvalue); } for (i = 0; i < size; ++i) { subvalue = PySequence_GetItem(value, i); if (subvalue == NULL) { return -1; } if (!PyArg_ParseTuple(subvalue, "iis", &ival, &mval, &strvalue)) { Py_DECREF(subvalue); return -1; } Py_DECREF(subvalue); (*ps)[i].i = ival; (*ps)[i].m = mval; strncpy((*ps)[i].value, strvalue, 72); (*ps)[i].value[71] = '\0'; (*nps) = (int)(i + 1); } return 0; } /*@null@*/ PyObject* get_pvcards( /*@unused@*/ const char* propname, struct pvcard* pv, int npv) { PyObject* result = NULL; PyObject* subresult = NULL; Py_ssize_t i = 0; if (npv < 0) { PyErr_SetString(PyExc_ValueError, "Object has no pvcards"); return NULL; } result = PyList_New((Py_ssize_t)npv); if (result == NULL) { return NULL; } for (i = 0; i < (Py_ssize_t)npv; ++i) { subresult = Py_BuildValue("iid", pv[i].i, pv[i].m, pv[i].value); if (subresult == NULL) { Py_DECREF(result); return NULL; } if (PyList_SetItem(result, i, subresult)) { Py_DECREF(subresult); Py_DECREF(result); return NULL; } } return result; }
PyObject* DetachValue() { // At this point, Trim should have been called by PostRead. if (bytesUsed == SQL_NULL_DATA || buffer == 0) Py_RETURN_NONE; if (usingStack) { if (dataType == SQL_C_CHAR) return PyBytes_FromStringAndSize(buffer, bytesUsed); if (dataType == SQL_C_BINARY) { #if PY_VERSION_HEX >= 0x02060000 return PyByteArray_FromStringAndSize(buffer, bytesUsed); #else return PyBytes_FromStringAndSize(buffer, bytesUsed); #endif } if (sizeof(SQLWCHAR) == Py_UNICODE_SIZE) return PyUnicode_FromUnicode((const Py_UNICODE*)buffer, bytesUsed / element_size); return PyUnicode_FromSQLWCHAR((const SQLWCHAR*)buffer, bytesUsed / element_size); } if (bufferOwner && PyUnicode_CheckExact(bufferOwner)) { if (PyUnicode_Resize(&bufferOwner, bytesUsed / element_size) == -1) return 0; PyObject* tmp = bufferOwner; bufferOwner = 0; buffer = 0; return tmp; } if (bufferOwner && PyBytes_CheckExact(bufferOwner)) { if (_PyBytes_Resize(&bufferOwner, bytesUsed) == -1) return 0; PyObject* tmp = bufferOwner; bufferOwner = 0; buffer = 0; return tmp; } #if PY_VERSION_HEX >= 0x02060000 if (bufferOwner && PyByteArray_CheckExact(bufferOwner)) { if (PyByteArray_Resize(bufferOwner, bytesUsed) == -1) return 0; PyObject* tmp = bufferOwner; bufferOwner = 0; buffer = 0; return tmp; } #endif // We have allocated our own SQLWCHAR buffer and must now copy it to a Unicode object. I(bufferOwner == 0); PyObject* result = PyUnicode_FromSQLWCHAR((const SQLWCHAR*)buffer, bytesUsed / element_size); if (result == 0) return false; pyodbc_free(buffer); buffer = 0; return result; }
bool AllocateMore(SQLLEN cbAdd) { // cbAdd // The number of bytes (cb --> count of bytes) to add. if (cbAdd == 0) return true; SQLLEN newSize = bufferSize + cbAdd; if (usingStack) { // This is the first call and `buffer` points to stack memory. Allocate a new object and copy the stack // data into it. char* stackBuffer = buffer; if (dataType == SQL_C_CHAR) { bufferOwner = PyBytes_FromStringAndSize(0, newSize); buffer = bufferOwner ? PyBytes_AS_STRING(bufferOwner) : 0; } else if (dataType == SQL_C_BINARY) { #if PY_VERSION_HEX >= 0x02060000 bufferOwner = PyByteArray_FromStringAndSize(0, newSize); buffer = bufferOwner ? PyByteArray_AS_STRING(bufferOwner) : 0; #else bufferOwner = PyBytes_FromStringAndSize(0, newSize); buffer = bufferOwner ? PyBytes_AS_STRING(bufferOwner) : 0; #endif } else if (sizeof(SQLWCHAR) == Py_UNICODE_SIZE) { // Allocate directly into a Unicode object. bufferOwner = PyUnicode_FromUnicode(0, newSize / element_size); buffer = bufferOwner ? (char*)PyUnicode_AsUnicode(bufferOwner) : 0; } else { // We're Unicode, but SQLWCHAR and Py_UNICODE don't match, so maintain our own SQLWCHAR buffer. bufferOwner = 0; buffer = (char*)pyodbc_malloc((size_t)newSize); } if (buffer == 0) return false; usingStack = false; memcpy(buffer, stackBuffer, (size_t)bufferSize); bufferSize = newSize; return true; } if (bufferOwner && PyUnicode_CheckExact(bufferOwner)) { if (PyUnicode_Resize(&bufferOwner, newSize / element_size) == -1) return false; buffer = (char*)PyUnicode_AsUnicode(bufferOwner); } #if PY_VERSION_HEX >= 0x02060000 else if (bufferOwner && PyByteArray_CheckExact(bufferOwner)) { if (PyByteArray_Resize(bufferOwner, newSize) == -1) return false; buffer = PyByteArray_AS_STRING(bufferOwner); } #else else if (bufferOwner && PyBytes_CheckExact(bufferOwner)) { if (_PyBytes_Resize(&bufferOwner, newSize) == -1) return false; buffer = PyBytes_AS_STRING(bufferOwner); } #endif else { char* tmp = (char*)realloc(buffer, (size_t)newSize); if (tmp == 0) return false; buffer = tmp; } bufferSize = newSize; return true; }
/* * Given a tuple of bytes and None objects, join them into a * a single bytes object with sizes. */ static PyObject * _pack_tuple_data(PyObject *tup) { PyObject *rob; Py_ssize_t natts; Py_ssize_t catt; char *buf = NULL; char *bufpos = NULL; Py_ssize_t bufsize = 0; if (!PyTuple_Check(tup)) { PyErr_Format( PyExc_TypeError, "pack_tuple_data requires a tuple, given %s", PyObject_TypeName(tup) ); return(NULL); } natts = PyTuple_GET_SIZE(tup); if (natts == 0) return(PyBytes_FromString("")); /* discover buffer size and valid att types */ for (catt = 0; catt < natts; ++catt) { PyObject *ob; ob = PyTuple_GET_ITEM(tup, catt); if (ob == Py_None) { bufsize = bufsize + 4; } else if (PyBytes_CheckExact(ob)) { bufsize = bufsize + PyBytes_GET_SIZE(ob) + 4; } else { PyErr_Format( PyExc_TypeError, "cannot serialize attribute %d, expected bytes() or None, got %s", (int) catt, PyObject_TypeName(ob) ); return(NULL); } } buf = malloc(bufsize); if (buf == NULL) { PyErr_Format( PyExc_MemoryError, "failed to allocate %d bytes of memory for packing tuple data", bufsize ); return(NULL); } bufpos = buf; for (catt = 0; catt < natts; ++catt) { PyObject *ob; ob = PyTuple_GET_ITEM(tup, catt); if (ob == Py_None) { uint32_t attsize = 0xFFFFFFFFL; /* Indicates NULL */ memcpy(bufpos, &attsize, 4); bufpos = bufpos + 4; } else { Py_ssize_t size = PyBytes_GET_SIZE(ob); uint32_t msg_size; if (size > 0xFFFFFFFE) { PyErr_Format(PyExc_OverflowError, "data size of %d is greater than attribute capacity", catt ); } msg_size = local_ntohl((uint32_t) size); memcpy(bufpos, &msg_size, 4); bufpos = bufpos + 4; memcpy(bufpos, PyBytes_AS_STRING(ob), PyBytes_GET_SIZE(ob)); bufpos = bufpos + PyBytes_GET_SIZE(ob); } } rob = PyBytes_FromStringAndSize(buf, bufsize); free(buf); return(rob); }