[ https://issues.apache.org/jira/browse/PDFBOX-837?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13791359#comment-13791359 ]
Martin Brown edited comment on PDFBOX-837 at 10/10/13 10:00 AM: ---------------------------------------------------------------- StandardSecurityHandler.computeRevisionNumber() refers to PDF Spec 1.6 p98. This says: {panel} [Revision] A number specifying which revision of the standard security handler should be used to interpret this dictionary: • 2 if the document is encrypted with a V value less than 2 (see Table 3.18) and does not have any of the access permissions set (by means of the P entry, below) that are designated “Revision 3 or greater” in Table 3.20 • 3 if the document is encrypted with a V value of 2 or 3, or has any “Revision 3 or greater” access permissions set • 4 if the document is encrypted with a V value of 4 {panel} However, the current code in computeRevisionNumber() is looking at the first test where V == 2 rather than V < 2. Following the spec, the method should look like this: {code} private int computeRevisionNumber() { if(version < 2 && !policy.getPermissions().canFillInForm() && !policy.getPermissions().canExtractForAccessibility() && !policy.getPermissions().canPrintDegraded() ) { return 2; } return 3; } {code} was (Author: martin_w_brown): StandardSecurityHandler.computeRevisionNumber() refers to PDF Spec 1.6 p98. This says: {panel} [Revision] A number specifying which revision of the standard security handler should be used to interpret this dictionary: • 2 if the document is encrypted with a V value less than 2 (see Table 3.18) and does not have any of the access permissions set (by means of the P entry, below) that are designated “Revision 3 or greater” in Table 3.20 • 3 if the document is encrypted with a V value of 2 or 3, or has any “Revision 3 or greater” access permissions set • 4 if the document is encrypted with a V value of 4 {panel} However, the current code in computeRevisionNumber() is looking at the first test where V == 2 rather than V < 2. Following the spec, the method should look like this: {code} private int computeRevisionNumber() { if(version < 2 && !policy.getPermissions().canFillInForm() && !policy.getPermissions().canExtractForAccessibility() && !policy.getPermissions().canPrintDegraded() ) { return 2; } return 3; } {code} > Wrong RevisionNumber when disabling all permissions and using 128bit > encryption > ------------------------------------------------------------------------------- > > Key: PDFBOX-837 > URL: https://issues.apache.org/jira/browse/PDFBOX-837 > Project: PDFBox > Issue Type: Bug > Components: PDModel > Affects Versions: 1.2.1 > Reporter: Bernd Engelhardt > Attachments: StandardSecurityHandler_patch.patch > > > When disabling all permissions and using a 128bit encryption the following > exception is thrown when saving the PDF document: > org.apache.pdfbox.exceptions.COSVisitorException: Error: Expected length=5 > actual=16 > at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1022) > at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:911) > at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:892) > at pdfbox.Main.main(Main.java:53) > This is reproducable with the following code: > public class Main { > public static void main(String[] args) { > try { > AccessPermission ap = new AccessPermission(); > StandardProtectionPolicy spp = null; > ap.setCanAssembleDocument(false); > ap.setCanExtractContent(false); > ap.setCanExtractForAccessibility(false); > ap.setCanFillInForm(false); > ap.setCanModify(false); > ap.setCanModifyAnnotations(false); > ap.setCanPrint(false); > ap.setCanPrintDegraded(false); > spp = new StandardProtectionPolicy(null, null, ap); > spp.setEncryptionKeyLength(128); > PDDocument document = null; > FileInputStream sourceFile = new FileInputStream(new > File("C:\\Web\\NetBeansProjects\\pdfBox\\test.pdf")); > document = PDDocument.load(sourceFile); > document.protect(spp); > > document.save("C:\\Web\\NetBeansProjects\\pdfBox\\test_encrypted.pdf"); > document.close(); > } catch (Exception ex) { > Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, > ex); > } > } > } > The problem is based on "computeRevisionNumber" in > "StandardSecurityHandler.java". If all flags are disabled, the routine > returns a value of 2. But if the 128bit encryption is enabled, the revision > should be 3. If not, the method "computeUserPassword" will fail. > A solution would be to check the key length in "computeRevisionNumber". > private int computeRevisionNumber() > { > if(version == 2 > && !policy.getPermissions().canFillInForm() > && !policy.getPermissions().canExtractForAccessibility() > && !policy.getPermissions().canPrintDegraded() > && keyLength == 40 ) > { > return 2; > } > return 3; > } -- This message was sent by Atlassian JIRA (v6.1#6144)