diff --git a/src/dataencode.cpp b/src/dataencode.cpp index d2d90c6bd..0a302c250 100644 --- a/src/dataencode.cpp +++ b/src/dataencode.cpp @@ -520,7 +520,7 @@ void from_wire_field(Buffer& buf, TypeStore& ctxt, const FieldDesc* desc, const switch (desc->code.code) { case TypeCode::Union: { Size select{}; - from_wire(buf, select); + from_wire(buf, select, true); if(select.size==size_t(-1)) { fld = Value(); return; @@ -627,7 +627,7 @@ void from_wire_field(Buffer& buf, TypeStore& ctxt, const FieldDesc* desc, const for(auto& elem : arr) { if(from_wire_as(buf)!=0) { // strictly 1 or 0 Size select{}; - from_wire(buf, select); + from_wire(buf, select, true); if(select.size==size_t(-1)) { // null element. treated the same as 0 case (which is what actually happens) diff --git a/src/pvaproto.h b/src/pvaproto.h index f090d7ea9..402a4bfff 100644 --- a/src/pvaproto.h +++ b/src/pvaproto.h @@ -282,7 +282,7 @@ void to_wire(Buffer& buf, const Size& size) } inline -void from_wire(Buffer& buf, Size& size) +void from_wire(Buffer& buf, Size& size, bool allow_null=false) { if(!buf.ensure(1)) { buf.fault(__FILE__, __LINE__); @@ -292,17 +292,16 @@ void from_wire(Buffer& buf, Size& size) if(s<254) { size.size = s; - } else if(s==255) { - // special "null" used to encode empty Union - size.size = size_t(-1); - } else if(s==254) { uint32_t ls = 0; from_wire(buf, ls); size.size = ls; + } else if(s==255 && allow_null) { + // special "null" used to encode empty Union and (sometimes) empty string + size.size = size_t(-1); + } else { - // unreachable (64-bit size so far not used) buf.fault(__FILE__, __LINE__); } } @@ -331,7 +330,7 @@ inline void from_wire(Buffer& buf, std::string& s) { Size len{0}; - from_wire(buf, len); + from_wire(buf, len, true); if(len.size==size_t(-1)) { s.clear(); diff --git a/test/testxcode.cpp b/test/testxcode.cpp index 600a54009..b577fda25 100644 --- a/test/testxcode.cpp +++ b/test/testxcode.cpp @@ -1161,6 +1161,20 @@ void testRegressCNEN() testTrue(prototype2.equalType(prototypeE))<<" "<