Stop the partnerships file gaining blank lines on every save - #610
Merged
uhurusurfa merged 1 commit intoSep 16, 2026
Merged
Conversation
The parser keeps the newlines and indentation between elements as text nodes. The serializer that stores the partnerships sets INDENT so it adds indentation of its own, and it cannot remove the nodes that are already there, so storing a document read from disk wrote the original whitespace plus a fresh layer of it. Every save therefore grew the file. Measured against the shipped partnerships file, five saves took it from 10 blank lines and 9062 bytes to 253 blank lines and 12824 bytes, adding roughly 60 lines each time with no bound. Any change through the console or the API stores the file, and each save is preceded by a numbered backup, so the growth accumulated over the life of a deployment. The layout whitespace is now discarded when the file is parsed, leaving the serializer as the only thing deciding the layout. Saving is idempotent as a result, and a file that has already accumulated blank lines is tidied the next time it is stored rather than needing to be repaired by hand. Only text nodes that are entirely whitespace are removed, so no value can be affected. Nothing in a partnerships file carries text content in any case: every value is held in an attribute. Note that org.openas2.upgrades.MigratePollingModuleConfig writes its output the same way and has the same defect, but it runs once by hand and its partnerships output is tidied by the first load after this change, so it is left alone.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Storing the partnerships file adds a fresh layer of whitespace to it each time, without bound.
Cause
Two halves that each look fine alone.
loadPartnershipsFilekeeps the newlines and indentation between elements as text nodes:storePartnershipthen asks the serializer to add indentation of its own:The serializer cannot remove nodes that are already in the document, so it writes the original whitespace plus a new layer. The next load turns that into more text nodes, and it compounds.
Measured against the shipped partnerships.xml
Roughly 60 blank lines and 960 bytes per save. Every change made through the console or the REST API stores the file, and each save is preceded by a numbered backup, so each bloated generation is also kept on disk.
Fix
Discard the layout whitespace when the file is parsed, leaving the serializer as the only thing deciding the layout. Done on load rather than on save so that every write path benefits.
After the fix the same run is stable at 115 lines and 7,928 bytes, byte identical across five saves. A file that has already accumulated blank lines is also tidied the next time it is stored, so an affected deployment repairs itself rather than needing the file cleaned up by hand.
Only text nodes that are entirely whitespace are removed, using
//text()[normalize-space(.) = ''], so no value can be affected. Nothing in a partnerships file carries text content in any case as every value is held in an attribute.Testing
177 tests pass, 4 new. Removing the fix fails two of them.
repeatedSavesDoNotGrowTheFilerequires five consecutive saves to produce a byte identical fileaFileThatAlreadyAccumulatedBlankLinesIsTidiedOnTheNextSavetakes a file damaged the way the bug damages it and requires the next save to clean itsavingDoesNotChangeAnyElementOrAttributeflattens the document into every element with its sorted attributes and values and requires the lists to be identical across a save, so any change to the data would failtheStoredFileIsStillReadableAndIndentedchecks the output is still well formed and still indentedorg.openas2.upgrades.MigratePollingModuleConfigwrites its output the same way and has the same defect, but it is run once by hand and its partnerships output is tidied by the first load after this change, so it is left alone.