Checking if a document is readOnly protected results in a NPE
liptga opened this issue · comments
I was developing a unit test for my docx4j code, and I discovered this bug.
Lets suppose we have a docx, which is readonly protected by a password. Then we try to check its protection type:
WordprocessingMLPackage mergedDocument = load(anyProtectedDocumentAsByteArray);
assertThat(mergedDocument.getMainDocumentPart().getDocumentSettingsPart()
.isRestrictEditingWith(STDocProtect.READ_ONLY)).isTrue();
Then we get an NPE:
java.lang.NullPointerException: Cannot invoke "org.docx4j.wml.CTSettings.getDocumentProtection()" because "this.jaxbElement" is null
at org.docx4j.openpackaging.parts.WordprocessingML.DocumentSettingsPart.isRestrictEditingWith(DocumentSettingsPart.java:290)
I noticed, that if I first check the password in my test using org.docx4j.openpackaging.packages.ProtectDocument#validateProtectionPassword
, then the assertion passes. So the validateProtectionPassword changes the state of DocumentSettingsPart
by initializing the jaxbElement
field. If I trigger the safeGetDocumentProtection
method with the debugger before calling isRestrictEditingWith
, then my test also passes.
Without fully understanding the code, I think if the org.docx4j.openpackaging.parts.WordprocessingML.DocumentSettingsPart#isRestrictEditingWith
method would look like below, no error would happen:
public boolean isRestrictEditingWith(STDocProtect editValue) {
CTDocProtect ctDocProtect = **safeGetDocumentProtection()**;
if (ctDocProtect == null) {
return false;
}
return ctDocProtect.isEnforcement() && ctDocProtect.getEdit().equals(editValue);
}
Please note, that in this DocumentSettingsPart
there are a lot of code places, where this.jaxbElement
is read, probably some other places should also be replaced by safeGetDocumentProtection
.