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;
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
    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
    }
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
    }
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
    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;
    }
Exemplo n.º 13
0
    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;
    }
Exemplo n.º 14
0
/*
 * 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);
}