Commit 58d9361e authored by Stefan Behnel's avatar Stefan Behnel

fix buffer format validation for sequences of strings in structs

parent 13b89088
...@@ -18,6 +18,8 @@ Bugs fixed ...@@ -18,6 +18,8 @@ Bugs fixed
* C++ destructor calls in extension types could fail to compile in clang. * C++ destructor calls in extension types could fail to compile in clang.
* Buffer format validation failed for sequences of strings in structs.
* Docstrings on extension type attributes in .pxd files were rejected. * Docstrings on extension type attributes in .pxd files were rejected.
......
...@@ -638,8 +638,8 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha ...@@ -638,8 +638,8 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
int got_Z = 0; int got_Z = 0;
while (1) { while (1) {
/* puts(ts); */
switch(*ts) { switch(*ts) {
/* puts(ts); */
case 0: case 0:
if (ctx->enc_type != 0 && ctx->head == NULL) { if (ctx->enc_type != 0 && ctx->head == NULL) {
__Pyx_BufFmt_RaiseExpected(ctx); __Pyx_BufFmt_RaiseExpected(ctx);
...@@ -650,7 +650,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha ...@@ -650,7 +650,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
__Pyx_BufFmt_RaiseExpected(ctx); __Pyx_BufFmt_RaiseExpected(ctx);
return NULL; return NULL;
} }
return ts; return ts;
case ' ': case ' ':
case '\r': case '\r':
case '\n': case '\n':
...@@ -730,23 +730,29 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha ...@@ -730,23 +730,29 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
if (*ts != 'f' && *ts != 'd' && *ts != 'g') { if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
__Pyx_BufFmt_RaiseUnexpectedChar('Z'); __Pyx_BufFmt_RaiseUnexpectedChar('Z');
return NULL; return NULL;
} /* fall through */ }
/* fall through */
case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
case 'l': case 'L': case 'q': case 'Q': case 'l': case 'L': case 'q': case 'Q':
case 'f': case 'd': case 'g': case 'f': case 'd': case 'g':
case 'O': case 's': case 'p': case 'O': case 'p':
if (ctx->enc_type == *ts && got_Z == ctx->is_complex && if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
ctx->enc_packmode == ctx->new_packmode) { ctx->enc_packmode == ctx->new_packmode) {
/* Continue pooling same type */ /* Continue pooling same type */
ctx->enc_count += ctx->new_count; ctx->enc_count += ctx->new_count;
} else { ctx->new_count = 1;
/* New type */ got_Z = 0;
if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; ++ts;
ctx->enc_count = ctx->new_count; break;
ctx->enc_packmode = ctx->new_packmode;
ctx->enc_type = *ts;
ctx->is_complex = got_Z;
} }
/* fall through */
case 's':
/* 's' or new type (cannot be added to current pool) */
if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
ctx->enc_count = ctx->new_count;
ctx->enc_packmode = ctx->new_packmode;
ctx->enc_type = *ts;
ctx->is_complex = got_Z;
++ts; ++ts;
ctx->new_count = 1; ctx->new_count = 1;
got_Z = 0; got_Z = 0;
......
...@@ -377,6 +377,22 @@ def partially_packed_struct_2(fmt): ...@@ -377,6 +377,22 @@ def partially_packed_struct_2(fmt):
fmt, sizeof(PartiallyPackedStruct2)) fmt, sizeof(PartiallyPackedStruct2))
cdef packed struct PackedStructWithCharArrays:
float a
int b
char[5] c
char[3] d
@testcase
def packed_struct_with_strings(fmt):
"""
>>> packed_struct_with_strings("T{f:a:i:b:5s:c:3s:d:}")
"""
cdef object[PackedStructWithCharArrays] buf = MockBuffer(
fmt, sizeof(PackedStructWithCharArrays))
# TODO: empty struct # TODO: empty struct
# TODO: Incomplete structs # TODO: Incomplete structs
# TODO: mixed structs # TODO: mixed structs
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