nissl-lab / npoi

a .NET library that can read/write Office formats without Microsoft Office installed. No COM+, no interop.
Apache License 2.0
5.74k stars 1.43k forks source link

WriteProtectWorkbook record in HSSFWorkbook doesn't work #716

Open CloudyWing opened 2 years ago

CloudyWing commented 2 years ago

My English is very bad, so I use google translation, if the description is not clear, please forgive me>

If directly new HSSFWorkbook(),WriteProtectWorkbook is not workig,The reason is as follows.

The following code is from InternalWorkbook.cs

public static InternalWorkbook CreateWorkbook() {
    ......
    list.Add(InterfaceEndRecord.Instance);
    list.Add(CreateWriteAccess());
    ......
}
......
public void WriteProtectWorkbook(string password, string username) {
    FileSharingRecord fileSharing = FileSharing;
    WriteAccessRecord writeAccessRecord = WriteAccess;
    fileSharing.ReadOnly = 1;
     fileSharing.Password = (short)CryptoFunctions.CreateXorVerifier1(password);
    fileSharing.Username = username;
    writeAccessRecord.Username = username;
}

When 「CreateWriteAccess()」 is executed, it is not pointed to field「writeAccess」, and in 「WriteProtectWorkbook()」, the call of 「FileSharing」 is placed in front of 「WriteAccess」, cause when calls Property 「WriteAccess」, because field 「writeAccess」 is null, WriteAccessRecord is created repeatedly and added to InterfaceEndRecord.

The normal Record order should be as follows. [INTERFACEEND/] [WriteAccess] [FILESHARING]

But the order of this situation is as follow. [INTERFACEEND/] [WriteAccess] [WriteAccess] [FILESHARING]

Although I don’t know the reason, apparently two [WriteAccess] in [INTERFACEEND/] and [FILESHARING] will cause "WriteProtectWorkbook" to not work properly. For the current version to work normally, you must call 「WriteAccess」 before calling 「WriteProtectWorkbook()」

_ = workbook.InternalWorkbook.WriteAccess;
workbook.WriteProtectWorkbook("Your Password", "");

The orderof Records generated at this time is as follows. [INTERFACEEND/] [WriteAccess] [FILESHARING] [WriteAccess]

Although there is still an extra [WriteAccess], it can work at least in version 2.5.5, and the previous version has not yet been tested.

tonyqus commented 2 years ago

Looks you fully understand what's going on. Can you provide a PR?