Skip to content

Iso8211FieldReader mis-parses 8-byte binary format controls (b48) — DSSI factors decoded as 0, soundings 10× too deep #9

Description

@philliphoff

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions