Skip to content

Read polymer Sgroups from V3000 molfiles - #293

Open
cm-beilstein wants to merge 7 commits into
devfrom
fix/146-v3000-polymer
Open

cm-beilstein wants to merge 7 commits into
devfrom
fix/146-v3000-polymer

Conversation

@cm-beilstein

@cm-beilstein cm-beilstein commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #146.

With -Polymers, a V3000 molfile gave Error 101 where the equivalent V2000 one gave a polymer InChI. Two causes in mol_fmt3.c:

  • The V3000 atom reader always dropped * atoms, so bonds pointed at missing atoms. They are now kept when polymers are on.
  • The SGROUP block was skipped entirely. Polymer Sgroups (SRU/MON/COP/MOD/CRO/MER: ATOMS, XBONDS, BRKXYZ, CONNECT, SUBTYPE, LABEL) are now read into the same structures the V2000 M S** lines fill. Other Sgroup types are skipped.

Without -Polymers behaviour is unchanged.

Also fixed:

  • MolfileV3000ReadSGroup looped forever on a file truncated before END SGROUP.
  • inchi_ios_str_getc (ichi_io.c) read past the terminating NUL, causing a buffer over-read in the next inchi_sgets on such input.

Tests (test_github_146): V2000 and V3000 polyethyleneoxide give the same InChI; truncated SGROUP block with and without -Polymers returns an error instead of hanging.

Known limits / open:

  • V3000 haptic bonds use a * atom as centre; with -Polymers that star is now kept. Untested combination, left as is.
  • Without -Polymers, V3000 star atoms are still dropped while V2000 gives a Zz InChI.
  • Quoted LABEL values are not unquoted.

cm-beilstein and others added 4 commits October 26, 2026 10:08
Reproduces GH #146: the V2000 polyethyleneoxide molfile gives a
polymer InChI with -Polymers, the equivalent V3000 molfile fails
with error 101 because the V3000 reader drops star atoms and skips
the SGROUP block. The V3000 test fails until V3000 polymer reading
is implemented.

Refs #146

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With -Polymers, V2000 polymer molfiles give a polymer InChI, but the
equivalent V3000 file failed with error 101: the V3000 reader always
dropped star atoms and skipped the whole SGROUP block.

Keep star atoms when polymers are treated (they are the SRU end
groups, as in V2000) and parse SRU/MON/COP/MOD/CRO/MER Sgroup lines
(ATOMS, XBONDS, BRKXYZ, CONNECT, SUBTYPE, LABEL) into the same
sgroups the V2000 M  STY/SAL/SBL/... lines fill. Other Sgroup types
are skipped; a malformed polymer Sgroup is reported as an error.
Without -Polymers nothing changes.

Fixes #146

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A V3000 molfile that ends inside the SGROUP block (no END SGROUP)
makes MolfileV3000ReadSGroup loop forever. The test feeds such a file
with and without -Polymers and expects an error return; it runs the
call in a thread and exits with failure after a timeout so a hang
fails the test instead of blocking ctest.

Refs #146

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MolfileV3000ReadSGroup looped forever when the input ended (or a
non-V30 line came) before END SGROUP. Leave the loop when no line can
be read, so the existing "No V3000 SGroup end marker" error is
reported.

Ending there exposed a read past the input buffer: the API sets the
string stream length to strlen + 1, so inchi_ios_str_getc consumed
the terminating NUL and later inchi_sgets started beyond it. Make
getc stop at the NUL.

Refs #146

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Unit Test Coverage Report

Coverage Regression Summary

Metric PR (%) Base (%) Difference (pp)
Lines 26.2 25.4 +0.80
Branches 17.4 16.8 +0.60

Find details on the base coverage at https://iupac-inchi.github.io/InChI/coverage/index.html

Find details on this PR's coverage by downloading coverage-reports-40313986464 and opening html/index.html

@cm-beilstein
cm-beilstein requested review from djb-rwth and nnuk October 26, 2026 10:01
cm-beilstein and others added 3 commits October 26, 2026 12:16
A 79-char LABEL fills MOL_FMT_SGROUP.smt[80] exactly; read_upto_delim
then writes one NUL past it into alist.item, which ASan reports as a
heap-buffer-overflow when the atom list is read. A trailing BRKXYZ
keyword without value makes V3000ReadBracket compare an uninitialised
buffer; ASan cannot see that, so this test documents the expected
error return only.

Refs #146

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
read_upto_delim accepts a token of maxlen - 1 chars, copies it with
mystrncpy(field, p, n + 1), which already NUL-terminates at field[n],
and then wrote field[n + 1] = '\0' one byte past the buffer. A 79-char
V3000 Sgroup LABEL thus overwrote alist.item after smt[80].

Drop the redundant write. All other callers (V3000 field, keyword,
list and haptic readers in mol_fmt3.c) only read field as a string
ending at field[n], so they are unaffected.

Refs #146

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With a trailing BRKXYZ keyword and no value the line pointer is NULL,
read_upto_delim returns -1 without writing field, and strcmp then
read the uninitialised buffer. Fail on the read error first.

Refs #146

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

V3 molfile of polyethyleneoxide creates error

1 participant