Skip to content

Commit 4eb6304

Browse files
committed
FOP-3292 Remove character max index restriction
1 parent 2819378 commit 4eb6304

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

fop-core/src/main/java/org/apache/fop/pdf/PDFName.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.IOException;
2323
import java.io.OutputStream;
2424
import java.io.Serializable;
25+
import java.nio.charset.StandardCharsets;
2526

2627
import org.apache.commons.io.output.CountingOutputStream;
2728

@@ -56,14 +57,16 @@ static String escapeName(String name) {
5657
if (name.startsWith("/")) {
5758
skipFirst = true;
5859
}
59-
for (int i = (skipFirst ? 1 : 0), c = name.length(); i < c; i++) {
60-
char ch = name.charAt(i);
6160

62-
if (ch < 33 || ch > 126 || ESCAPED_NAME_CHARS.indexOf(ch) >= 0) {
63-
sb.append('#');
64-
toHex(ch, sb);
61+
name = name.substring(skipFirst ? 1 : 0);
62+
63+
byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
64+
for (byte nameByte : nameBytes) {
65+
int currentChar = nameByte & 255;
66+
if (currentChar < 33 || currentChar > 126 || ESCAPED_NAME_CHARS.indexOf(currentChar) >= 0) {
67+
toHex(currentChar, sb);
6568
} else {
66-
sb.append(ch);
69+
sb.append((char)nameByte);
6770
}
6871
}
6972
return sb.toString();
@@ -73,13 +76,10 @@ static String escapeName(String name) {
7376
= {'0', '1', '2', '3', '4', '5', '6', '7',
7477
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
7578

76-
private static void toHex(char ch, StringBuilder sb) {
77-
if (ch >= 256) {
78-
throw new IllegalArgumentException(
79-
"Only 8-bit characters allowed by this implementation");
80-
}
81-
sb.append(DIGITS[ch >>> 4 & 0x0F]);
82-
sb.append(DIGITS[ch & 0x0F]);
79+
private static void toHex(int currentChar, StringBuilder sb) {
80+
sb.append('#');
81+
sb.append(DIGITS[currentChar >>> 4 & 0x0F]);
82+
sb.append(DIGITS[currentChar & 0x0F]);
8383
}
8484

8585
/** {@inheritDoc} */

fop-core/src/test/java/org/apache/fop/pdf/PDFNameTestCase.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.io.ByteArrayOutputStream;
2323
import java.io.IOException;
24+
import java.nio.charset.StandardCharsets;
2425

2526
import org.junit.Before;
2627
import org.junit.Test;
@@ -65,6 +66,9 @@ public void testEscapeName() {
6566
assertEquals("/Test", PDFName.escapeName("/Test"));
6667
// Test with a space in the middle
6768
assertEquals("/Test#20test", PDFName.escapeName("Test test"));
69+
// Test with chars whose index are over 256
70+
assertEquals("/BCDEEE+#EF#BC#AD#EF#BC#B3#20#E3#82#B4#E3#82#B7#E3#83#83#E3#82#AF",
71+
PDFName.escapeName("BCDEEE+MS ゴシック"));
6872
// Test that all chars apart from ASCII '!' --> '~' are escaped
6973
nonEscapedCharactersTests();
7074
escapedCharactersTests();
@@ -76,11 +80,17 @@ private void escapedCharactersTests() {
7680
str += Integer.toHexString(i & 0x0f).toUpperCase();
7781
assertEquals("/#" + str, PDFName.escapeName(String.valueOf(i)));
7882
}
79-
for (char i = '~' + 1; i < 256; i++) {
80-
String str = Integer.toHexString(i >>> 4 & 0x0f).toUpperCase();
81-
str += Integer.toHexString(i & 0x0f).toUpperCase();
82-
assertEquals("/#" + str, PDFName.escapeName(String.valueOf(i)));
83+
for (char i = 128; i < 256; i++) {
84+
byte[] bytes = String.valueOf(i).getBytes(StandardCharsets.UTF_8);
85+
StringBuilder str = new StringBuilder("/");
86+
for (byte b : bytes) {
87+
str.append("#");
88+
str.append(Integer.toHexString(b >>> 4 & 0x0f).toUpperCase());
89+
str.append(Integer.toHexString(b & 0x0f).toUpperCase());
90+
}
91+
assertEquals(str.toString(), PDFName.escapeName(String.valueOf(i)));
8392
}
93+
8494
checkCharacterIsEscaped('#');
8595
checkCharacterIsEscaped('%');
8696
checkCharacterIsEscaped('(');

0 commit comments

Comments
 (0)