Skip to content

fix: clone DataFormatData in WriteCellStyle.merge to avoid mutating cached annotation style#957

Open
nkuprins wants to merge 1 commit into
apache:mainfrom
nkuprins:fix-writecellstyle-dataformat-clone
Open

fix: clone DataFormatData in WriteCellStyle.merge to avoid mutating cached annotation style#957
nkuprins wants to merge 1 commit into
apache:mainfrom
nkuprins:fix-writecellstyle-dataformat-clone

Conversation

@nkuprins

@nkuprins nkuprins commented Jul 18, 2026

Copy link
Copy Markdown

Purpose of the pull request

Closed: #956

What's changed?

WriteCellStyle.merge copied the source's DataFormatData into the target by reference. Because the annotation-driven style source is parsed once and cached, a later merge from another style source (e.g. a registered HorizontalCellStyleStrategy) wrote into that shared object and permanently changed the cached @ContentStyle(dataFormat) - producing the wrong number format on rows where the strategy defines no format, and (with CacheLocationEnum.MEMORY) on later, unrelated writes of the same bean class.

The fix clones the DataFormatData before assigning it, exactly like writeFont is already cloned a few lines below in the same method:

- target.setDataFormatData(source.getDataFormatData());
+ target.setDataFormatData(source.getDataFormatData().clone());

Added ContentStyleDataFormatPollutionTest with two regression tests that assert on the number format of the written file (via the testkit's ExcelAssertions):

  • annotationFormatSurvivesStyleStrategyInSameWrite - default config: a row whose strategy style has no data format must keep the annotation's #,##0.00.
  • annotationFormatSurvivesAcrossWritesWithMemoryCache - MEMORY cache location: a follow-up write with no custom handlers must keep the annotation's format.

Both tests fail on main (format comes out 0.00) and pass with the fix. The full fesod-sheet suite passes with the fix applied (673 tests, 0 failures, 0 errors, 0 skipped), confirming no behavior change for styles that don't involve a shared DataFormatData.

Checklist

  • I have read the Contributor Guide.
  • I have written the necessary doc or comment.
  • I have added the necessary unit tests and all cases have passed.

…ached annotation style

A registered cell style strategy could permanently change the cached
@ContentStyle(dataFormat) of a field, because WriteCellStyle.merge copied
the source DataFormatData by reference and a later merge then wrote into
the shared object. Clone it like writeFont on the line below.

Closes apache#956

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes a subtle style-caching mutation bug in fesod-sheet where WriteCellStyle.merge previously copied DataFormatData by reference, allowing later merges (e.g., from a HorizontalCellStyleStrategy) to corrupt the cached annotation-driven @ContentStyle(dataFormat) metadata and produce incorrect number formats.

Changes:

  • Clone DataFormatData when assigning it during WriteCellStyle.merge to prevent shared-reference mutation of cached annotation style metadata.
  • Add ContentStyleDataFormatPollutionTest regression coverage to ensure the annotation format survives (1) within the same write when a strategy provides no format, and (2) across writes when CacheLocationEnum.MEMORY is used.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/style/WriteCellStyle.java Prevents cached annotation DataFormatData from being aliased/mutated by cloning on merge assignment.
fesod-sheet/src/test/java/org/apache/fesod/sheet/style/ContentStyleDataFormatPollutionTest.java Adds regression tests that assert on the written file’s number formats to prevent recurrence (same-write + MEMORY-cache scenarios).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

[Bug] Cell style strategy corrupts the cached @ContentStyle(dataFormat) of other rows

2 participants