This is an automated email from the ASF dual-hosted git repository.
delei pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fesod.git
The following commit(s) were added to refs/heads/main by this push:
new d80dc969 fix: XLS BIFF8 encryption not applied due to premature
password clearing (#959)
d80dc969 is described below
commit d80dc969820790dc8d7e7eeb174a1139ce4b3330
Author: ian zhang <[email protected]>
AuthorDate: Sat Jul 25 14:18:51 2026 +0800
fix: XLS BIFF8 encryption not applied due to premature password clearing
(#959)
* fix: XLS BIFF8 encryption not applied due to premature password clearing
The refactor in 7fe23f0 added a finally block in
WorkBookUtil.createWorkBook()
that clears the Biff8EncryptionKey ThreadLocal immediately after setting it.
However, workbook.write() (which applies BIFF8 encryption) runs later in
WriteContextImpl.finish(). At that point the password is already null, so
the file content is never encrypted - only a write-protection flag is set.
Fix: Remove the premature clearing. The password is correctly cleared by
WriteContextImpl.clearEncrypt03() after workbook.write() completes.
Tests:
- Update WorkBookUtilTest to verify password remains set after
createWorkBook()
- Add EncryptDataTest.xlsPasswordWrite_isActuallyEncrypted to verify that
reading an encrypted XLS without a password fails
* style: fix spotless formatting in EncryptDataTest
Merge the assertThrows lambda argument onto a single line to comply
with the project Spotless formatting rules.
* fix: address Copilot review comments on PR #959
- WorkBookUtil: use !StringUtils.isEmpty() instead of != null to prevent
empty password ThreadLocal leak (clearEncrypt03 returns early for
empty passwords)
- EncryptDataTest: use EncryptedDocumentException instead of Exception
for more precise assertion of encryption failure
---
.../org/apache/fesod/sheet/util/WorkBookUtil.java | 10 ++-----
.../fesod/sheet/readwrite/EncryptDataTest.java | 34 ++++++++++++++++++++++
.../apache/fesod/sheet/util/WorkBookUtilTest.java | 5 +++-
3 files changed, 41 insertions(+), 8 deletions(-)
diff --git
a/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/WorkBookUtil.java
b/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/WorkBookUtil.java
index a8e1d076..24438420 100644
--- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/WorkBookUtil.java
+++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/WorkBookUtil.java
@@ -92,13 +92,9 @@ public class WorkBookUtil {
}
writeWorkbookHolder.setCachedWorkbook(hssfWorkbook);
writeWorkbookHolder.setWorkbook(hssfWorkbook);
- if (writeWorkbookHolder.getPassword() != null) {
- try {
-
Biff8EncryptionKey.setCurrentUserPassword(writeWorkbookHolder.getPassword());
-
hssfWorkbook.writeProtectWorkbook(writeWorkbookHolder.getPassword(),
StringUtils.EMPTY);
- } finally {
- Biff8EncryptionKey.setCurrentUserPassword(null);
- }
+ if (!StringUtils.isEmpty(writeWorkbookHolder.getPassword())) {
+
Biff8EncryptionKey.setCurrentUserPassword(writeWorkbookHolder.getPassword());
+
hssfWorkbook.writeProtectWorkbook(writeWorkbookHolder.getPassword(),
StringUtils.EMPTY);
}
return;
case CSV:
diff --git
a/fesod-sheet/src/test/java/org/apache/fesod/sheet/readwrite/EncryptDataTest.java
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/readwrite/EncryptDataTest.java
index 1741d581..1eb375ee 100644
---
a/fesod-sheet/src/test/java/org/apache/fesod/sheet/readwrite/EncryptDataTest.java
+++
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/readwrite/EncryptDataTest.java
@@ -39,8 +39,10 @@ import
org.apache.fesod.sheet.testkit.listeners.CollectingReadListener;
import org.apache.fesod.sheet.testkit.models.SimpleData;
import org.apache.fesod.sheet.testkit.params.ExcelFormatSource;
import org.apache.fesod.sheet.write.builder.ExcelWriterBuilder;
+import org.apache.poi.EncryptedDocumentException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
/**
@@ -104,4 +106,36 @@ public class EncryptDataTest extends AbstractExcelTest {
Assertions.assertEquals(10, dataList.size());
Assertions.assertNotNull(dataList.get(0).getName());
}
+
+ /**
+ * Verifies that an XLS file written with a password is actually encrypted
at the BIFF8 record level,
+ * not merely flagged as write-protected. Without the correct password,
reading the file content
+ * must fail.
+ */
+ @Test
+ void xlsPasswordWrite_isActuallyEncrypted() throws Exception {
+ File file = createTempFile("enc-verify", ExcelFormat.XLS);
+
+ // Write an encrypted XLS file
+ FesodSheet.write(file, SimpleData.class)
+ .excelType(ExcelTypeEnum.XLS)
+ .password(PASSWORD)
+ .sheet()
+ .doWrite(TestDataBuilder.simpleData(10));
+
+ // Reading without the password must fail because the content is
BIFF8-encrypted
+ Assertions.assertThrows(EncryptedDocumentException.class, () ->
FesodSheet.read(
+ file, SimpleData.class, new
CollectingReadListener<SimpleData>())
+ .excelType(ExcelTypeEnum.XLS)
+ .sheet()
+ .doReadSync());
+
+ // Reading with the correct password must succeed
+ List<SimpleData> dataList = FesodSheet.read(file, SimpleData.class,
new CollectingReadListener<SimpleData>())
+ .excelType(ExcelTypeEnum.XLS)
+ .password(PASSWORD)
+ .sheet()
+ .doReadSync();
+ Assertions.assertEquals(10, dataList.size());
+ }
}
diff --git
a/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/WorkBookUtilTest.java
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/WorkBookUtilTest.java
index 71355369..0b2db0ff 100644
---
a/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/WorkBookUtilTest.java
+++
b/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/WorkBookUtilTest.java
@@ -231,7 +231,10 @@ class WorkBookUtilTest {
// Verify
Mockito.verify(writeWorkbookHolder).setWorkbook(Mockito.any(HSSFWorkbook.class));
- Assertions.assertNull(Biff8EncryptionKey.getCurrentUserPassword());
+ // The BIFF8 encryption password must remain set after
createWorkBook() so that
+ // workbook.write() (called later in WriteContextImpl.finish()) can
apply encryption.
+ // WriteContextImpl.clearEncrypt03() clears it after writing completes.
+ Assertions.assertEquals("123456",
Biff8EncryptionKey.getCurrentUserPassword());
}
@Test
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]