Skip to content

Commit 978504e

Browse files
CompareTool: check objects type before checking their indirect status; improve error message on different streams
1 parent a568a26 commit 978504e

File tree

1 file changed

+46
-19
lines changed

1 file changed

+46
-19
lines changed

kernel/src/main/java/com/itextpdf/kernel/utils/CompareTool.java

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -701,15 +701,15 @@ private boolean compareObjects(PdfObject outObj, PdfObject cmpObj, ObjectPath cu
701701
} else if (cmpDirectObj == null) {
702702
compareResult.addError(currentPath, "Found object which was not expected to be found.");
703703
return false;
704+
} else if (cmpDirectObj.getType() != outDirectObj.getType()) {
705+
compareResult.addError(currentPath, String.format("Types do not match. Expected: %s. Found: %s.", cmpDirectObj.getClass().getSimpleName(), outDirectObj.getClass().getSimpleName()));
706+
return false;
704707
} else if (cmpObj.isIndirectReference() && !outObj.isIndirectReference()) {
705708
compareResult.addError(currentPath, "Expected indirect object.");
706709
return false;
707710
} else if (!cmpObj.isIndirectReference() && outObj.isIndirectReference()) {
708711
compareResult.addError(currentPath, "Expected direct object.");
709712
return false;
710-
} else if (cmpDirectObj.getType() != outDirectObj.getType()) {
711-
compareResult.addError(currentPath, String.format("Types do not match. Expected: %s. Found: %s.", cmpDirectObj.getClass().getSimpleName(), outDirectObj.getClass().getSimpleName()));
712-
return false;
713713
}
714714

715715
if (currentPath != null && cmpObj.isIndirectReference() && outObj.isIndirectReference()) {
@@ -782,29 +782,56 @@ private boolean compareStreamsExtended(PdfStream outStream, PdfStream cmpStream,
782782
if (Arrays.equals(outStreamBytes, cmpStreamBytes)) {
783783
return compareDictionariesExtended(outStream, cmpStream, currentPath, compareResult);
784784
} else {
785+
String errorMessage = "";
785786
if (cmpStreamBytes.length != outStreamBytes.length) {
786-
if (compareResult != null && currentPath != null) {
787-
compareResult.addError(currentPath, String.format("PdfStream. Lengths are different. Expected: %s. Found: %s", cmpStreamBytes.length, outStreamBytes.length));
788-
}
787+
errorMessage += String.format("PdfStream. Lengths are different. Expected: %s. Found: %s", cmpStreamBytes.length, outStreamBytes.length) + "\n";
789788
} else {
790-
for (int i = 0; i < cmpStreamBytes.length; i++) {
791-
if (cmpStreamBytes[i] != outStreamBytes[i]) {
792-
int l = Math.max(0, i - 10);
793-
int r = Math.min(cmpStreamBytes.length, i + 10);
794-
if (compareResult != null && currentPath != null) {
795-
currentPath.pushOffsetToPath(i);
796-
compareResult.addError(currentPath, String.format("PdfStream. The bytes differ at index %s. Expected: %s (%s). Found: %s (%s)",
797-
i, new String(new byte[]{cmpStreamBytes[i]}), new String(cmpStreamBytes, l, r - l).replaceAll("\\r|\\n", ""),
798-
new String(new byte[]{outStreamBytes[i]}), new String(outStreamBytes, l, r - l).replaceAll("\\r|\\n", "")));
799-
currentPath.pop();
800-
}
801-
}
802-
}
789+
errorMessage += "PdfStream. Lengths are the same. But bytes are different:\n";
790+
}
791+
String bytesDifference = findBytesDifference(outStreamBytes, cmpStreamBytes);
792+
if (bytesDifference != null) {
793+
errorMessage += bytesDifference;
794+
}
795+
796+
if (compareResult != null && currentPath != null) {
797+
// currentPath.pushOffsetToPath(firstDifferenceOffset);
798+
compareResult.addError(currentPath, errorMessage);
799+
// currentPath.pop();
803800
}
804801
return false;
805802
}
806803
}
807804

805+
private String findBytesDifference(byte[] outStreamBytes, byte[] cmpStreamBytes) {
806+
int numberOfDifferentBytes = 0;
807+
int firstDifferenceOffset = 0;
808+
for (int i = 0; i < Math.min(cmpStreamBytes.length, outStreamBytes.length); i++) {
809+
if (cmpStreamBytes[i] != outStreamBytes[i]) {
810+
++numberOfDifferentBytes;
811+
if (numberOfDifferentBytes == 1) {
812+
firstDifferenceOffset = i;
813+
}
814+
}
815+
}
816+
String errorMessage = null;
817+
if (numberOfDifferentBytes > 0) {
818+
int l = Math.max(0, firstDifferenceOffset - 10);
819+
int r = Math.min(cmpStreamBytes.length, firstDifferenceOffset + 10);
820+
821+
822+
String cmpByte = new String(new byte[]{cmpStreamBytes[firstDifferenceOffset]});
823+
String cmpByteNeighbours = new String(cmpStreamBytes, l, r - l).replaceAll("\\r|\\n", " ");
824+
String outByte = new String(new byte[]{outStreamBytes[firstDifferenceOffset]});
825+
String outBytesNeighbours = new String(outStreamBytes, l, r - l).replaceAll("\\r|\\n", " ");
826+
errorMessage = String.format("First bytes difference is encountered at index %s. Expected: %s (%s). Found: %s (%s). Total number of different bytes: %s",
827+
firstDifferenceOffset, cmpByte, cmpByteNeighbours, outByte, outBytesNeighbours, numberOfDifferentBytes);
828+
} else { // lengths are different
829+
errorMessage = "Lengths are different, but bytes of the shorter array are the same as the first bytes of the longer one.";
830+
}
831+
832+
return errorMessage;
833+
}
834+
808835
private boolean compareArraysExtended(PdfArray outArray, PdfArray cmpArray, ObjectPath currentPath, CompareResult compareResult) throws IOException {
809836
if (outArray == null) {
810837
if (compareResult != null && currentPath != null)

0 commit comments

Comments
 (0)