Repository navigation
sbe: refuse a value its (sbe.encoding) primitive cannot hold (#133) - #143
Conversation
db81e1c to
95517ac
Compare
0529a25 to
448b8af
Compare
95517ac to
43eabbe
Compare
448b8af to
456dd6e
Compare
456dd6e to
b945fdf
Compare
43eabbe to
3486d29
Compare
|
Rebased onto main 197e05b, after #124 and #137 merged as squashes: 456dd6e → b945fdf. The old #124 and #137 commits were dropped ( |
Marshal narrowed a value to its SBE primitive by keeping the low bits, so an int32 300 under "int8" was written as 44 and read back as 44. The draft says "Emitters MUST reject values that fall outside the narrowed type's range". Unmarshal likewise cut a wire value to the field's low bits. As protowire-go does (#252): the value is read by the field's kind and checked against the primitive's range before it is written; Unmarshal sign-extends per the primitive and checks the result against the field's range before storing it. A double narrowed to float is checked against ±max float. Codec::New refuses (sbe.encoding) on a string or bytes field and a crossing between integers and floating point. A double field under "float", and a float field under "double", used to write and read raw bits of the wrong width; they now convert the value. Tests ported from Go's encoding/sbe/encoding_range_test.go, including its 100-pairing matrix (68 bind and round-trip, 32 are refused).
b945fdf to
72c54f1
Compare
|
Rebased onto main 9525e9b, after #140 merged as a squash: b945fdf → 72c54f1. I dropped #140's old commit with |
Fixes #133.
A value that doesn't fit its
(sbe.encoding)primitive is now refused instead of losing its high bits. Before,int32 v [(sbe.encoding) = "int8"]set to 300 was written as 44 and read back as 44. On read,uint322^31 in anint32field wrapped to a negative number. The draft says "Emitters MUST reject values that fall outside the narrowed type's range". Ported from protowire-go #255 (issue #252).sbe: field M.v: value 300 is outside the range of int8, [-128, 127]. Adoubleunder"float"is checked against ±3.4028234663852886e+38 (NaN and ±Inf pass). An enum, laid out asuint8by default, refuses a value past 255 or below 0.sbe: field M.v: wire value 2147483648 (uint32) does not fit a int32 field, [-2147483648, 2147483647]. A bool still reads any nonzero value as true.(sbe.encoding)on a string or bytes field, and an integer/float crossing, with Go's three texts.Viewis unchanged, as in Go's commit.FieldTemplatestruct. Go's%gin the float messages is reproduced by a smallGoGhelper in the new internalsrc/sbe/encoding_range.h.Also fixed (same code path): a
doublefield under"float"used to write the low 4 bytes of the double's bits, and afloatfield under"double"the float's bits zero-extended. Both read back as garbage. They now convert the value, as Go does. Go's 100-pairing matrix test pins it.Stack and merge order: #123 → #124 → #137 (#134) → #140 (#132) → this PR. Base:
sbe-header-bounds-132. This PR builds on #132's rewrite ofFieldEncodingSizeand its Go-style error wrapping.Evidence, at 0529a25, on macOS:
ctest: 100% passed, 689 of 689. That includes 7SbeEncodingRange.*tests ported from Go'sencoding_range_test.go:Marshal,MarshalFloat,MarshalNested,Unmarshal,KindBind, andMatrix(68 pairings bind and round-trip, 32 are refused, the counts Go asserts). It also includesUnmarshalText, which pins the full read-error text.Marshal,MarshalFloat,MarshalNested,UnmarshalandUnmarshalTextfail.scripts/go_differential.shagainst protowire-go main 207fdfc: exit 1, from the same 450 PXF diff lines as at sbe: tell two schemas' template ids apart (#134) #137 (cmp). Every section ran (954 damaged streams decoded alike,18 SBE schemas converted alike,362 documents), and no differing line mentions sbe. The remaining PXF diffs are pxf: Marshal leaves out an unset (pxf.default) or (pxf.required) field, so it doesn't read back #129, pxf: FormatDocument drops every directive, so a @dataset document formats to nothing #130 and pxf: reject null on a (pxf.required) or @required field #131.--dry-run --Werror: clean.template.cc,marshal.ccandunmarshal.cc: every remaining hit is on a line this PR does not touch. Those lines pass CI's tidy-18.