Skip to content

Commit 4140dc0

Browse files
Fix critical issue with PdfName#compareTo violating compareTo contract
Avoid possibility of not being able to retrieve entries contained in PdfDictionary when there is a number of pdf names with specially encoded characters. ITXT-CR-507
1 parent af6d7bf commit 4140dc0

File tree

3 files changed

+107
-7
lines changed

3 files changed

+107
-7
lines changed

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfName.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -979,12 +979,7 @@ public String getValue() {
979979
*/
980980
@Override
981981
public int compareTo(PdfName o) {
982-
if (value != null && o.value != null) {
983-
return value.compareTo(o.value);
984-
} else if (content != null && o.content != null) {
985-
return compareContent(o);
986-
} else
987-
return getValue().compareTo(o.getValue());
982+
return getValue().compareTo(o.getValue());
988983
}
989984

990985
@Override

kernel/src/test/java/com/itextpdf/kernel/pdf/PdfDictionaryTest.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,4 +465,72 @@ public void testValuesClear() {
465465
Assert.assertEquals(0, dict.values().size());
466466
Assert.assertEquals(0, dict.size());
467467
}
468+
469+
@Test
470+
public void testPdfNamesFetching() {
471+
byte[][] namesBytes = new byte[][] {
472+
// /#C3#9Cberschrift_1
473+
new byte[]{35, 67, 51, 35, 57, 67, 98, 101, 114, 115, 99, 104, 114, 105, 102, 116, 95, 49},
474+
// /#C3#9Cberschrift_2
475+
new byte[]{35, 67, 51, 35, 57, 67, 98, 101, 114, 115, 99, 104, 114, 105, 102, 116, 95, 50},
476+
// /Article
477+
new byte[]{65, 114, 116, 105, 99, 108, 101},
478+
// /Bildunterschrift
479+
new byte[]{66, 105, 108, 100, 117, 110, 116, 101, 114, 115, 99, 104, 114, 105, 102, 116},
480+
// /NormalParagraphStyle
481+
new byte[]{78, 111, 114, 109, 97, 108, 80, 97, 114, 97, 103, 114, 97, 112, 104, 83, 116, 121, 108, 101},
482+
// /Story
483+
new byte[]{83, 116, 111, 114, 121},
484+
// /TOC-1
485+
new byte[]{84, 79, 67, 45, 49,},
486+
// /TOC-2-2
487+
new byte[]{84, 79, 67, 45, 50, 45, 50,},
488+
// /TOC-Head
489+
new byte[]{84, 79, 67, 45, 72, 101, 97, 100,},
490+
// /Tabelle
491+
new byte[]{84, 97, 98, 101, 108, 108, 101,},
492+
// /Tabelle_Head
493+
new byte[]{84, 97, 98, 101, 108, 108, 101, 95, 72, 101, 97, 100,},
494+
// /Tabelle_fett
495+
new byte[]{84, 97, 98, 101, 108, 108, 101, 95, 102, 101, 116, 116,},
496+
// /Text_INFO
497+
new byte[]{84, 101, 120, 116, 95, 73, 78, 70, 79,},
498+
// /Text_Info_Head
499+
new byte[]{84, 101, 120, 116, 95, 73, 110, 102, 111, 95, 72, 101, 97, 100,},
500+
// /Textk#C3#B6rper
501+
new byte[]{84, 101, 120, 116, 107, 35, 67, 51, 35, 66, 54, 114, 112, 101, 114,},
502+
// /Textk#C3#B6rper-Erstzeile
503+
new byte[]{84, 101, 120, 116, 107, 35, 67, 51, 35, 66, 54, 114, 112, 101, 114, 45, 69, 114, 115, 116, 122, 101, 105, 108, 101,},
504+
// /Textk#C3#B6rper_Back
505+
new byte[]{84, 101, 120, 116, 107, 35, 67, 51, 35, 66, 54, 114, 112, 101, 114, 95, 66, 97, 99, 107,},
506+
// /_No_paragraph_style_
507+
new byte[]{95, 78, 111, 95, 112, 97, 114, 97, 103, 114, 97, 112, 104, 95, 115, 116, 121, 108, 101, 95}
508+
};
509+
boolean[] haveValue = new boolean[] {true, true, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false};
510+
List<PdfName> names = new ArrayList<>();
511+
for (int i = 0; i < namesBytes.length; i++) {
512+
byte[] b = namesBytes[i];
513+
PdfName n = new PdfName(b);
514+
names.add(n);
515+
if (haveValue[i]) {
516+
n.generateValue();
517+
}
518+
}
519+
520+
PdfDictionary dict = new PdfDictionary();
521+
for (PdfName name : names) {
522+
dict.put(name, new PdfName("dummy"));
523+
}
524+
525+
PdfName expectedToContain = new PdfName("Article");
526+
boolean found = false;
527+
for (PdfName pdfName : dict.keySet()) {
528+
found = pdfName.equals(expectedToContain);
529+
if (found) {
530+
break;
531+
}
532+
}
533+
Assert.assertTrue(found);
534+
Assert.assertTrue(dict.containsKey(expectedToContain));
535+
}
468536
}

kernel/src/test/java/com/itextpdf/kernel/pdf/PdfNameTest.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ This file is part of the iText (R) project.
4343
package com.itextpdf.kernel.pdf;
4444

4545
import com.itextpdf.test.ITextTest;
46-
import com.itextpdf.test.annotations.type.IntegrationTest;
4746
import com.itextpdf.test.annotations.type.UnitTest;
4847

4948
import org.junit.Assert;
@@ -63,4 +62,42 @@ public void specialCharactersTest(){
6362
Assert.assertEquals(str2, createStringByEscaped(name2.getInternalContent()));
6463
}
6564

65+
@Test
66+
public void basicCompareToTest(){
67+
// /#C3#9Cberschrift_1
68+
byte[] name1Content = new byte[] {35, 67, 51, 35, 57, 67, 98, 101, 114, 115, 99, 104, 114, 105, 102, 116, 95, 49};
69+
// /TOC-1
70+
byte[] name2Content = new byte[] {84, 79, 67, 45, 49};
71+
// /NormalParagraphStyle
72+
byte[] name3Content = new byte[] {78, 111, 114, 109, 97, 108, 80, 97, 114, 97, 103, 114, 97, 112, 104, 83, 116, 121, 108, 101};
73+
74+
// /#C3#9Cberschrift_1, Überschrift_1
75+
PdfName name1 = new PdfName(name1Content);
76+
PdfName name1ContentOnly = new PdfName(name1Content);
77+
// /TOC-1, TOC-1
78+
PdfName name2 = new PdfName(name2Content);
79+
// /NormalParagraphStyle, NormalParagraphStyle
80+
PdfName name3 = new PdfName(name3Content);
81+
name1.generateValue();
82+
name2.generateValue();
83+
84+
int oneToTwo = name1.compareTo(name2);
85+
int twoToOne = name2.compareTo(name1);
86+
87+
int oneToThree = name1.compareTo(name3);
88+
int twoToThree = name2.compareTo(name3);
89+
90+
int oneToOneContent = name1.compareTo(name1ContentOnly);
91+
int oneContentToTwo = name1ContentOnly.compareTo(name2);
92+
93+
double delta = 1e-8;
94+
Assert.assertEquals(Math.signum(oneToTwo), -Math.signum(twoToOne), delta);
95+
96+
Assert.assertEquals(Math.signum(oneToTwo), Math.signum(twoToThree), delta);
97+
Assert.assertEquals(Math.signum(oneToTwo), Math.signum(oneToThree), delta);
98+
99+
Assert.assertEquals(oneToOneContent, 0);
100+
Assert.assertEquals(Math.signum(oneToTwo), Math.signum(oneContentToTwo), delta);
101+
}
102+
66103
}

0 commit comments

Comments
 (0)