Fix StackOverflowError on schema cycles that carry no $ref - #928
Conversation
There was a problem hiding this comment.
All reported issues were addressed across 3 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
Both review points were valid, and chasing the second one turned up a deeper cause. I have reworked the fix rather than patching the original approach. On the false negative: confirmed. On the mixed wrapper/bare pair: also confirmed. Reverting just the reference normalization makes that fixture overflow. It had passed earlier only because the first issue was masking it, gutting the wrapper and ending the recursion by accident. What the first approach missed entirely: The recursion is now guarded on the identity of the compared schema pair, scoped to the current path. That covers the flattened case and makes the wrapped and mixed cases fall out for free, so Verified: |
Comparing a spec against itself overflows the stack when schemas form a reference cycle that no
$refsurvives.resolveComposedSchemainlines anallOftarget's properties into the wrapping schema and then clears theallOf. Two wrappers in a cycle therefore end up holding each other's properties with neither a$refnor anallOfleft on either one, andcomputeDeferredDiffonly consults its recursion guard when both sides carry a bare$ref, so nothing stops the descent.Guarding on the identity of the schema pair being compared covers that case, and also the simpler ones where a cycle passes through an
allOf-wrapped reference on one or both sides. The guard is scoped to the current path, so sibling occurrences of the same schema are still diffed.Changes:
(left, right)schema pair inRecursiveSchemaSet, entering beforecomputeDiffForRealand leaving after it./mvnw clean verifypasses (core 273 tests, maven 13 tests, 0 failures). Also checked against a ~540KB generated spec that reproduced the original overflow: it now compares clean, and a type change made deep inside the cycle is still reported.Claude assisted with this change.