Commit 7d5a4f98 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Buffers: format string check rewrite up to standards of the old one

parent 28434b74
...@@ -595,7 +595,7 @@ def get_type_information_cname(code, dtype, maxdepth=None): ...@@ -595,7 +595,7 @@ def get_type_information_cname(code, dtype, maxdepth=None):
dtype=dtype, maxdepth=maxdepth) dtype=dtype, maxdepth=maxdepth)
return name return name
def type_information_code(proto, impl, name, structinfo_name, dtype): def type_information_code(proto, impl, name, structinfo_name, dtype, maxdepth):
# Output the run-time type information (__Pyx_TypeInfo) for given dtype. # Output the run-time type information (__Pyx_TypeInfo) for given dtype.
# Use through get_type_information_cname # Use through get_type_information_cname
# #
...@@ -754,7 +754,8 @@ static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, ...@@ -754,7 +754,8 @@ static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
ctx->root.offset = 0; ctx->root.offset = 0;
ctx->head = stack; ctx->head = stack;
ctx->head->field = &ctx->root; ctx->head->field = &ctx->root;
ctx->fmt_offset = ctx->head->parent_offset = 0; ctx->fmt_offset = 0;
ctx->head->parent_offset = 0;
ctx->packmode = '@'; ctx->packmode = '@';
ctx->new_count = 1; ctx->new_count = 1;
ctx->enc_count = 0; ctx->enc_count = 0;
...@@ -763,6 +764,7 @@ static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, ...@@ -763,6 +764,7 @@ static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
while (type->typegroup == 'S') { while (type->typegroup == 'S') {
++ctx->head; ++ctx->head;
ctx->head->field = type->fields; ctx->head->field = type->fields;
ctx->head->parent_offset = 0;
type = type->fields->type; type = type->fields->type;
} }
} }
...@@ -920,8 +922,10 @@ static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { ...@@ -920,8 +922,10 @@ static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
} }
static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
char group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); char group;
size_t size, offset; size_t size, offset;
if (ctx->enc_type == 0) return 0;
group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
do { do {
__Pyx_StructField* field = ctx->head->field; __Pyx_StructField* field = ctx->head->field;
__Pyx_TypeInfo* type = field->type; __Pyx_TypeInfo* type = field->type;
...@@ -942,8 +946,10 @@ static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { ...@@ -942,8 +946,10 @@ static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
if (type->size != size || type->typegroup != group) { if (type->size != size || type->typegroup != group) {
if (type->typegroup == 'C' && type->fields != NULL) { if (type->typegroup == 'C' && type->fields != NULL) {
/* special case -- treat as struct rather than complex number */ /* special case -- treat as struct rather than complex number */
size_t parent_offset = ctx->head->parent_offset + field->offset;
++ctx->head; ++ctx->head;
ctx->head->field = type->fields; ctx->head->field = type->fields;
ctx->head->parent_offset = parent_offset;
continue; continue;
} }
...@@ -952,12 +958,12 @@ static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { ...@@ -952,12 +958,12 @@ static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
} }
offset = ctx->head->parent_offset + field->offset; offset = ctx->head->parent_offset + field->offset;
/* if (ctx->fmt_offset != offset) { if (ctx->fmt_offset != offset) {
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
"Buffer dtype mismatch; next field is at offset %"PY_FORMAT_SIZE_T"d " "Buffer dtype mismatch; next field is at offset %"PY_FORMAT_SIZE_T"d "
"but %"PY_FORMAT_SIZE_T"d expected", ctx->fmt_offset, offset); "but %"PY_FORMAT_SIZE_T"d expected", ctx->fmt_offset, offset);
return -1; return -1;
}*/ }
ctx->fmt_offset += size; ctx->fmt_offset += size;
...@@ -1001,13 +1007,11 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha ...@@ -1001,13 +1007,11 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
while (1) { while (1) {
switch(*ts) { switch(*ts) {
case 0: case 0:
if (ctx->enc_type != 0) { if (ctx->enc_type != 0 && ctx->head == NULL) {
if (ctx->head == NULL) {
__Pyx_BufFmt_RaiseExpected(ctx); __Pyx_BufFmt_RaiseExpected(ctx);
return NULL; return NULL;
} }
if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
}
if (ctx->head != NULL) { if (ctx->head != NULL) {
__Pyx_BufFmt_RaiseExpected(ctx); __Pyx_BufFmt_RaiseExpected(ctx);
return NULL; return NULL;
...@@ -1063,7 +1067,14 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha ...@@ -1063,7 +1067,14 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
case '}': /* end of substruct; either repeat or move on */ case '}': /* end of substruct; either repeat or move on */
++ts; ++ts;
return ts; return ts;
case 'x':
if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
ctx->fmt_offset += ctx->new_count;
ctx->new_count = 1;
ctx->enc_count = 0;
ctx->enc_type = 0;
++ts;
break;
case 'Z': case 'Z':
got_Z = 1; got_Z = 1;
++ts; ++ts;
...@@ -1080,11 +1091,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha ...@@ -1080,11 +1091,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
ctx->enc_count += ctx->new_count; ctx->enc_count += ctx->new_count;
} else { } else {
/* New type */ /* New type */
if (ctx->enc_type != 0) { if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) {
return NULL;
}
}
ctx->enc_count = ctx->new_count; ctx->enc_count = ctx->new_count;
ctx->enc_type = *ts; ctx->enc_type = *ts;
ctx->is_complex = got_Z; ctx->is_complex = got_Z;
......
...@@ -272,18 +272,18 @@ cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset ...@@ -272,18 +272,18 @@ cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset
if (end - f) - (new_offset - offset[0]) < 15: # this should leave room for "T{" and "}" as well if (end - f) - (new_offset - offset[0]) < 15: # this should leave room for "T{" and "}" as well
raise RuntimeError("Format string allocated too short, see comment in numpy.pxd") raise RuntimeError("Format string allocated too short, see comment in numpy.pxd")
new_byteorder = child.byteorder # new_byteorder = child.byteorder
if new_byteorder == '|': new_byteorder = '=' # if new_byteorder == '|': new_byteorder = '='
# if byteorder[0] != new_byteorder: # if byteorder[0] != new_byteorder:
# f[0] = new_byteorder # f[0] = new_byteorder
# f += 1 # f += 1
# byteorder[0] = new_byteorder # byteorder[0] = new_byteorder
# Output padding bytes # Output padding bytes
while offset[0] < new_offset: # while offset[0] < new_offset:
f[0] = 120 # "x"; pad byte # f[0] = 120 # "x"; pad byte
f += 1 # f += 1
offset[0] += 1 # offset[0] += 1
offset[0] += child.itemsize offset[0] += child.itemsize
......
...@@ -154,6 +154,20 @@ def char3int(fmt): ...@@ -154,6 +154,20 @@ def char3int(fmt):
>>> char3int("ci2i") >>> char3int("ci2i")
>>> char3int("c@i@2i") >>> char3int("c@i@2i")
Extra pad bytes (assuming int size is 4 or more)
>>> char3int("cxiii")
>>> char3int("c3xiii")
>>> char3int("cxxxiii")
Standard alignment (assming int size is 4)
>>> char3int("=c3xiii")
>>> char3int("=cxxx@iii")
>>> char3int("=ciii")
Traceback (most recent call last):
...
ValueError: Buffer dtype mismatch; next field is at offset 1 but 4 expected
Error:
>>> char3int("cii") >>> char3int("cii")
Traceback (most recent call last): Traceback (most recent call last):
... ...
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment