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]

Reply via email to