diff --git a/itext.tests/itext.sign.tests/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest.cs b/itext.tests/itext.sign.tests/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest.cs index 2b444482d5..9db676ffe2 100644 --- a/itext.tests/itext.sign.tests/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest.cs +++ b/itext.tests/itext.sign.tests/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest.cs @@ -468,6 +468,43 @@ public virtual void TaggedDocRemoveStructTreeElementTest(bool continueValidation } } + [NUnit.Framework.TestCaseSource("CreateParameters")] + public virtual void AnnotationModificationAllowedTabsChangesTest(bool continueValidationAfterFail) { + SetUp(continueValidationAfterFail); + using (PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "annotationModificationAllowedTabsChangesTest.pdf" + ))) { + DocumentRevisionsValidator validator = builder.BuildDocumentRevisionsValidator(); + ValidationReport report = validator.ValidateAllDocumentRevisions(validationContext, document); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.VALID).HasNumberOfLogs + (0)); + } + } + + [NUnit.Framework.TestCaseSource("CreateParameters")] + public virtual void AnnotationModificationNotAllowedTabsChangesTest(bool continueValidationAfterFail) { + SetUp(continueValidationAfterFail); + using (PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "annotationModificationNotAllowedTabsChangesTest.pdf" + ))) { + DocumentRevisionsValidator validator = builder.BuildDocumentRevisionsValidator(); + ValidationReport report = validator.ValidateAllDocumentRevisions(validationContext, document); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.INVALID).HasNumberOfFailures + (1).HasLogItem((l) => l.WithCheckName(DocumentRevisionsValidator.DOC_MDP_CHECK).WithMessage(DocumentRevisionsValidator + .TABS_MODIFIED).WithStatus(ReportItem.ReportItemStatus.INVALID))); + } + } + + [NUnit.Framework.TestCaseSource("CreateParameters")] + public virtual void AnnotationModificationNotAllowedTabsSetToDefaultTest(bool continueValidationAfterFail) { + SetUp(continueValidationAfterFail); + using (PdfDocument document = new PdfDocument(new PdfReader(SOURCE_FOLDER + "annotationModificationNotAllowedTabsSetToDefaultTest.pdf" + ))) { + DocumentRevisionsValidator validator = builder.BuildDocumentRevisionsValidator(); + ValidationReport report = validator.ValidateAllDocumentRevisions(validationContext, document); + AssertValidationReport.AssertThat(report, (a) => a.HasStatus(ValidationReport.ValidationResult.VALID).HasNumberOfLogs + (0)); + } + } + [NUnit.Framework.TestCaseSource("CreateParameters")] public virtual void OutlinesNotModifiedTest(bool continueValidationAfterFail) { SetUp(continueValidationAfterFail); diff --git a/itext.tests/itext.sign.tests/resources/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest/annotationModificationAllowedTabsChangesTest.pdf b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest/annotationModificationAllowedTabsChangesTest.pdf new file mode 100644 index 0000000000..9db70e7eee Binary files /dev/null and b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest/annotationModificationAllowedTabsChangesTest.pdf differ diff --git a/itext.tests/itext.sign.tests/resources/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest/annotationModificationNotAllowedTabsChangesTest.pdf b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest/annotationModificationNotAllowedTabsChangesTest.pdf new file mode 100644 index 0000000000..95a551a793 Binary files /dev/null and b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest/annotationModificationNotAllowedTabsChangesTest.pdf differ diff --git a/itext.tests/itext.sign.tests/resources/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest/annotationModificationNotAllowedTabsSetToDefaultTest.pdf b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest/annotationModificationNotAllowedTabsSetToDefaultTest.pdf new file mode 100644 index 0000000000..a29f030a66 Binary files /dev/null and b/itext.tests/itext.sign.tests/resources/itext/signatures/validation/DocumentRevisionsValidatorIntegrationTest/annotationModificationNotAllowedTabsSetToDefaultTest.pdf differ diff --git a/itext/itext.sign/itext/signatures/validation/DocumentRevisionsValidator.cs b/itext/itext.sign/itext/signatures/validation/DocumentRevisionsValidator.cs index 68df7c62b9..20f9ffb19a 100644 --- a/itext/itext.sign/itext/signatures/validation/DocumentRevisionsValidator.cs +++ b/itext/itext.sign/itext/signatures/validation/DocumentRevisionsValidator.cs @@ -152,6 +152,10 @@ public class DocumentRevisionsValidator { internal const String PAGE_MODIFIED = "Page was unexpectedly modified."; //\endcond +//\cond DO_NOT_DOCUMENT + internal const String TABS_MODIFIED = "Tabs entry in a page dictionary was unexpectedly modified."; +//\endcond + //\cond DO_NOT_DOCUMENT internal const String PERMISSIONS_REMOVED = "Permissions dictionary was removed from the catalog."; //\endcond @@ -1510,15 +1514,21 @@ private bool ComparePages(PdfDictionary prevPages, PdfDictionary currPages, Vali previousPageCopy.Remove(PdfName.Annots); previousPageCopy.Remove(PdfName.Parent); previousPageCopy.Remove(PdfName.StructParents); + previousPageCopy.Remove(PdfName.Tabs); PdfDictionary currentPageCopy = new PdfDictionary(currentKid); currentPageCopy.Remove(PdfName.Annots); currentPageCopy.Remove(PdfName.Parent); currentPageCopy.Remove(PdfName.StructParents); + currentPageCopy.Remove(PdfName.Tabs); if (!ComparePdfObjects(previousPageCopy, currentPageCopy, usuallyModifiedObjects) || !CompareIndirectReferencesObjNums (previousKid.Get(PdfName.Parent), currentKid.Get(PdfName.Parent), report, "Page parent")) { report.AddReportItem(new ReportItem(DOC_MDP_CHECK, PAGE_MODIFIED, ReportItem.ReportItemStatus.INVALID)); return false; } + if (!CompareTabs(previousKid.GetAsName(PdfName.Tabs), currentKid.GetAsName(PdfName.Tabs))) { + report.AddReportItem(new ReportItem(DOC_MDP_CHECK, TABS_MODIFIED, ReportItem.ReportItemStatus.INVALID)); + return false; + } PdfArray prevNotModifiableAnnots = GetAnnotsNotAllowedToBeModified(previousKid); PdfArray currNotModifiableAnnots = GetAnnotsNotAllowedToBeModified(currentKid); if (!ComparePageAnnotations(prevNotModifiableAnnots, currNotModifiableAnnots, report)) { @@ -1533,6 +1543,13 @@ private bool ComparePages(PdfDictionary prevPages, PdfDictionary currPages, Vali return true; } + private bool CompareTabs(PdfName previousTabs, PdfName currentTabs) { + if (GetAccessPermissions() == AccessPermissions.ANNOTATION_MODIFICATION) { + return true; + } + return Object.Equals(previousTabs, currentTabs) || (previousTabs == null && currentTabs.Equals(PdfName.S)); + } + private void CollectRemovedAndAddedAnnotations(PdfArray previousAnnotations, PdfArray currentAnnotations) { ValidationReport dummyReport = new ValidationReport(); IList prevAnnots = new List(); diff --git a/port-hash b/port-hash index 31eca6a608..82e8c5e5ee 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -8d4fbb6308e2126af33891bf5ad981ec9f2fd81b +ce35dbce51bd8c3f1b01e78313f1f5a2a02201ff