Summary
Iso8211FieldReader mis-parses binary format controls of the form bXY where the second digit (width) is 8 — e.g. b48 (8-byte) inside the very common composite control (3b48,10b14). All such subfields are read with a 4-byte width, which shifts every subsequent subfield in the field by 12 bytes and corrupts the decoded values.
This is the field control used by the S-100 / S-101 DSSI (Data Set Structure Information) field, so it affects every real S-101 ENC cell: the coordinate/sounding multiplication factors (CMFX/CMFY/CMFZ) are read as 0, and the record counts are read as the (mis-shifted) factor values.
Reproduced with EncDotNet.Iso8211 0.5.0.
Field definition (DSSI)
Declared FormatControls (read back from the DDR of a real cell): (3b48,10b14)
Subfield names (13): DCOX DCOY DCOZ CMFX CMFY CMFZ NOIR NOPN NOMN NOCN NOXN NOSN NOFR
Per S-100 Part 10a §10a-6.1.2.2, DCOX/DCOY/DCOZ are b48 (8-byte) origin shifts; the remaining ten are b14 (4-byte) unsigned integers. Total width = 3×8 + 10×4 = 64 bytes.
Raw field bytes (64)
00 00 00 00 00 00 00 00 DCOX b48 = 0
00 00 00 00 00 00 00 00 DCOY b48 = 0
00 00 00 00 00 00 00 00 DCOZ b48 = 0
80 96 98 00 CMFX b14 = 10000000
80 96 98 00 CMFY b14 = 10000000
64 00 00 00 CMFZ b14 = 100
55 00 00 00 NOIR b14 = 85
C0 12 00 00 NOPN b14 = 4800
05 00 00 00 NOMN b14 = 5
45 15 00 00 NOCN b14 = 5445
2B 05 00 00 NOXN b14 = 1323
7A 04 00 00 NOSN b14 = 1146
0E 0C 00 00 NOFR b14 = 3086
Hex blob: 00000000000000000000000000000000000000000000000080969800809698006400000055000000C012000005000000451500002B0500007A0400000E0C0000
This grouping decodes cleanly and the record counts are sane (85 info records, 4800 points, etc.).
Observed (buggy) decode
Iso8211FieldReader returns the subfields as if all of them were b14 (4-byte), starting at offset 0:
| Subfield |
Expected |
Actual (buggy) |
| CMFX |
10000000 |
0 |
| CMFY |
10000000 |
0 |
| CMFZ |
100 |
0 |
| NOIR |
85 |
10000000 |
| NOPN |
4800 |
10000000 |
| NOMN |
5 |
100 |
Reflecting over fieldDefinition.SubfieldDefinitions shows DCOX/DCOY/DCOZ with Format=b14, Width=4 (should be b48, Width=8). So the defect is in how the (3b48,10b14) format control is expanded into per-subfield widths — the 8 width of b48 is lost and 4 is used instead.
Impact
- Any consumer of DSSI reads
CMFX=CMFY=CMFZ=0. Downstream S-101 code masks the X/Y loss with a hard-coded 1e7 fallback, but the Z (sounding/height) factor defaults wrongly, so charted soundings come out 10× too deep (a real S-101 cell with CMFZ=100 decoded as the S-57 fallback of 10). On a Portsmouth Harbour cell this turns ~12.9 m soundings into ~129 m.
- More generally, every field using a
bX8 width (8-byte binary) is mis-read, and any field that mixes bX8 with following subfields will have all later subfields shifted.
Suggested fix
In the binary format-control parser, treat the second digit of a bWN control as the byte width (N), supporting N ∈ {1,2,3,4,8} (ISO/IEC 8211). Ensure (3b48,10b14) expands to three 8-byte subfields followed by ten 4-byte subfields. A regression test over the DSSI blob above (asserting CMFZ=100, NOIR=85) would lock it in.
Summary
Iso8211FieldReadermis-parses binary format controls of the formbXYwhere the second digit (width) is 8 — e.g.b48(8-byte) inside the very common composite control(3b48,10b14). All such subfields are read with a 4-byte width, which shifts every subsequent subfield in the field by 12 bytes and corrupts the decoded values.This is the field control used by the S-100 / S-101 DSSI (Data Set Structure Information) field, so it affects every real S-101 ENC cell: the coordinate/sounding multiplication factors (
CMFX/CMFY/CMFZ) are read as0, and the record counts are read as the (mis-shifted) factor values.Reproduced with
EncDotNet.Iso82110.5.0.Field definition (DSSI)
Declared
FormatControls(read back from the DDR of a real cell):(3b48,10b14)Subfield names (13):
DCOX DCOY DCOZ CMFX CMFY CMFZ NOIR NOPN NOMN NOCN NOXN NOSN NOFRPer S-100 Part 10a §10a-6.1.2.2,
DCOX/DCOY/DCOZareb48(8-byte) origin shifts; the remaining ten areb14(4-byte) unsigned integers. Total width = 3×8 + 10×4 = 64 bytes.Raw field bytes (64)
Hex blob:
00000000000000000000000000000000000000000000000080969800809698006400000055000000C012000005000000451500002B0500007A0400000E0C0000This grouping decodes cleanly and the record counts are sane (85 info records, 4800 points, etc.).
Observed (buggy) decode
Iso8211FieldReaderreturns the subfields as if all of them wereb14(4-byte), starting at offset 0:Reflecting over
fieldDefinition.SubfieldDefinitionsshowsDCOX/DCOY/DCOZwithFormat=b14, Width=4(should beb48, Width=8). So the defect is in how the(3b48,10b14)format control is expanded into per-subfield widths — the8width ofb48is lost and 4 is used instead.Impact
CMFX=CMFY=CMFZ=0. Downstream S-101 code masks the X/Y loss with a hard-coded1e7fallback, but the Z (sounding/height) factor defaults wrongly, so charted soundings come out 10× too deep (a real S-101 cell with CMFZ=100 decoded as the S-57 fallback of 10). On a Portsmouth Harbour cell this turns ~12.9 m soundings into ~129 m.bX8width (8-byte binary) is mis-read, and any field that mixesbX8with following subfields will have all later subfields shifted.Suggested fix
In the binary format-control parser, treat the second digit of a
bWNcontrol as the byte width (N), supportingN ∈ {1,2,3,4,8}(ISO/IEC 8211). Ensure(3b48,10b14)expands to three 8-byte subfields followed by ten 4-byte subfields. A regression test over the DSSI blob above (assertingCMFZ=100,NOIR=85) would lock it in.