sbmlteam/libsbml

Segmentation fault with some operations after failed strict conversion

avandecreme opened this issue · 3 comments

The following program seg fault when run with the following uncompressed file.

printParentDocIsNull(SBMLDocument_t * d)
{
  Model_t *m = SBMLDocument_getModel(d);
  SBMLDocument_t *d2 = SBase_getSBMLDocument((SBase_t *)m);
  printf("Parent doc is null: %i\n", d2 == NULL);
}


int
main (int argc, char *argv[])
{
  int success;
  SBMLDocument_t *d = readSBML(argv[1]);
  printParentDocIsNull(d);
  success = SBMLDocument_setLevelAndVersionStrict(d, 3, 2);
  printf("Strict Success: %d\n", success);
  printParentDocIsNull(d);
  success = SBMLDocument_setLevelAndVersionNonStrict(d, 3, 2);
  printf("Non Strict Success: %d\n", success);
  printParentDocIsNull(d);
  SBMLDocument_checkConsistency(d);

  SBMLDocument_free(d);
  return 0;
}

Result in:

Parent doc is null: 0
Strict Success: 0
Parent doc is null: 1
Non Strict Success: 1
Parent doc is null: 1
Segmentation fault (core dumped)

I tracked down the issue to the fact when failing to do a strict conversion, we restore the model of the document to a stored copy here:

mDocument->mModel = currentModel; // so we have to set it again

However, copying a model does not copy the mSBML field on SBase:

, mSBML (NULL)

This is put in evidence by the Parent doc is null outputs above.

This then cause the crash when running the consistency check on unique ids because the following line trust that m.getSBMLDocument() will return a non null value:

doCheckId((SBase&)(*m.getSBMLDocument()));

I am able to fix that specific issue by adding the following line when cloning the model in the SBMLLevelVersionConverter:

          currentModel->connectToParent(mDocument);

However, I am not sure this is the best approach because all other SBase (reactions, compartments...) of the model will still be missing there back link to the document.

Any idea how to best fix this?

Thanks for the report.
Yes I need to think about this - there are other places where functions like this will recurse down the whole tree but I need to look at this before I'm convinced this is the right approach here

I can see exactly where this is happening but it will only happen when a model has been converted but then fails validation. Do you happen to have a small example which will save me trying to find one? Thanks

Sorry I've just spotted it