xlsx: don't let x15:workbookPr reset the date1904 flag - #708
Conversation
| Some(v) => v == b"1" || v == b"true", | ||
| None => false, | ||
| }; | ||
| // Only update the flag when the attribute is present. The |
There was a problem hiding this comment.
This comment is referring to the what the patch is fixing and not to what the code is doing. Change it to something like
// Set the 1904 date flag, if present.
| // A 1904-system workbook whose extLst also contains an <x15:workbookPr> | ||
| // extension element (which shares the "workbookPr" local name but carries | ||
| // no date1904 attribute) must still be read on the 1904 epoch. See #706. | ||
| let mut xls: Xlsx<_> = wb("date_1904_extlst.xlsx"); |
There was a problem hiding this comment.
This doesn't need to be mut. Also the variable should be called xlsx and not xls.
|
Thanks for the fix. I have made some comments inline. Please address them and rebase and force push the changes to your branch. Then mark the comments as "resolved". Also, reduce the commit message down to 1-2 lines max. |
b807e50 to
12654b3
Compare
|
Pushed a fix for the red CI. The failure was mine: the test I added had a One-character change, no behaviour difference. Verified locally with the same commands CI runs: Disclosure: I use AI assistance in my work, and I review and verify everything before it goes out. |
read_workbook matched the "workbookPr" local name, but that also matches the namespaced extension element <x15:workbookPr> that modern Excel writes inside <extLst>. That element never carries a date1904 attribute, and it appears after the real <workbookPr> in the stream, so it reset is_1904 back to false. A genuine 1904-system workbook was then read on the 1900 epoch, shifting every date 1462 days (4 years and a day) earlier. Only assign is_1904 when the date1904 attribute is actually present; the field already defaults to false, so a bare <workbookPr/> still means 1900-system. Fixes tafia#706
12654b3 to
c605e7b
Compare
|
Both review comments addressed — apologies, I acted on the CI failure yesterday and only picked up the
// Set the 1904 date flag, if present. The attribute is
// optional here because `<x15:workbookPr>` inside `<extLst>`
// shares this local name and never carries `date1904`.I kept one clause on why the attribute is optional, since without it the
Verified with the same commands CI runs: Disclosure: I use AI assistance in my work, and I review and verify everything before it goes out. |
|
Merged. Thanks. |
Summary
Fixes #706. A genuine 1904-system xlsx workbook is read on the 1900 epoch when its
<extLst>contains an<x15:workbookPr>element (which modern Excel writes), shifting every date 1462 days (4 years + 1 day) earlier.Root cause
read_workbookmatches theworkbookPrlocal name:local_name()strips the namespace prefix, so the extension element<x15:workbookPr>(inside<extLst>) also matches. It never carriesdate1904and appears after the real<workbookPr date1904="1"/>, so theNone => falsearm resetsis_1904back tofalse.has_1904_epoch()then returnsfalseand the +1462-day offset is dropped.Fix
Only assign
is_1904when thedate1904attribute is actually present; the field already defaults tofalse, so a bare<workbookPr/>still means 1900-system.Test
Added
date_xlsx_1904_extlstwith a fixture (tests/date_1904_extlst.xlsx) = a 1904 workbook whoseextLstalso contains<x15:workbookPr>. Before the fixhas_1904_epoch()isfalse(test fails); after, it istrue, and the existing date tests still pass.Disclosure: prepared with AI assistance (Claude); I reviewed it and verified the red-green test and the date test suite.