Skip to content

Commit c5a3120

Browse files
authored
Merge branch 'master' into feature/mvn-build
2 parents 4ea8307 + 0f3a6d4 commit c5a3120

6 files changed

Lines changed: 77 additions & 66 deletions

File tree

.github/workflows/maven.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ jobs:
1010
runs-on: ${{ matrix.os }}
1111
strategy:
1212
matrix:
13-
os: [ubuntu-latest, windows-latest, macos-latest]
14-
java: [21, 24, 25, 26, '27-ea']
13+
os: [ubuntu-latest, macos-latest, windows-latest]
14+
java: [21, 25, '27-ea'] # Only LTS and latest
1515
name: Build with Java ${{ matrix.java }} on ${{ matrix.os }}
1616
steps:
1717
- uses: actions/checkout@v5

openpdf-core/src/main/java/org/openpdf/text/html/HtmlWriter.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ public void open() {
329329
super.open();
330330
try {
331331
writeComment(Document.getVersion());
332-
writeComment("CreationDate: " + new Date().toString());
332+
writeComment("CreationDate: " + new Date());
333333
addTabs(1);
334334
writeEnd(HtmlTags.HEAD);
335335
addTabs(1);
@@ -467,7 +467,7 @@ protected void writeJavaScript(Header header) throws IOException {
467467
addTabs(2);
468468
writeStart(HtmlTags.SCRIPT);
469469
write(HtmlTags.LANGUAGE, HtmlTags.JAVASCRIPT);
470-
if (markup.size() > 0) {
470+
if (!markup.isEmpty()) {
471471
/* JavaScript reference example:
472472
*
473473
* <script language="JavaScript" src="/myPath/MyFunctions.js"/>
@@ -629,7 +629,7 @@ protected void write(Element element, int indent) throws IOException {
629629
if (attributes != null && attributes.get(Chunk.NEWPAGE) != null) {
630630
return;
631631
}
632-
boolean tag = isOtherFont(chunk.getFont()) || markup.size() > 0;
632+
boolean tag = isOtherFont(chunk.getFont()) || !markup.isEmpty();
633633
if (tag) {
634634
// start span tag
635635
addTabs(indent);

openpdf-core/src/main/java/org/openpdf/text/pdf/OcspClientBouncyCastle.java

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
*
8686
* This library is free software; you can redistribute it and/or modify it
8787
* under the terms of the MPL as stated above or under the terms of the GNU
88-
* Library General Public License as published by the Free Software Foundation;
88+
* Library General Public License as published by the Free Software Foundation,
8989
* either version 2 of the License, or any later version.
9090
*
9191
* This library is distributed in the hope that it will be useful, but WITHOUT
@@ -108,8 +108,10 @@
108108
import java.math.BigInteger;
109109
import java.net.HttpURLConnection;
110110
import java.net.Proxy;
111+
import java.net.URI;
111112
import java.net.URL;
112113
import java.security.Provider;
114+
import java.security.SecureRandom;
113115
import java.security.Security;
114116
import java.security.cert.CertificateEncodingException;
115117
import java.security.cert.X509Certificate;
@@ -153,6 +155,7 @@ public class OcspClientBouncyCastle implements OcspClient {
153155
* HTTP proxy used to access the OCSP URL
154156
*/
155157
private Proxy proxy;
158+
private static final Random RANDOM_INSTANCE = new SecureRandom();
156159

157160
/**
158161
* Creates an instance of an OcspClient that will be using BouncyCastle.
@@ -185,10 +188,6 @@ private static OCSPReq generateOCSPRequest(X509Certificate issuerCert,
185188
Security.addProvider(prov);
186189

187190
// Generate the id for the certificate we are looking for
188-
// OJO... Modificacion de
189-
// Felix--------------------------------------------------
190-
// CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert,
191-
// serialNumber);
192191
// Example from
193192
// http://grepcode.com/file/repo1.maven.org/maven2/org.bouncycastle/bcmail-jdk16/1.46/org/bouncycastle/cert/ocsp/test/OCSPTest.java
194193
DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder()
@@ -203,19 +202,10 @@ private static OCSPReq generateOCSPRequest(X509Certificate issuerCert,
203202

204203
gen.addRequest(id);
205204

206-
// create details for nonce extension
207-
// Vector oids = new Vector();
208-
// Vector values = new Vector();
209-
// oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
210-
// values.add(new X509Extension(false, new DEROctetString(new
211-
// DEROctetString(PdfEncryption.createDocumentId()).getEncoded())));
212-
// gen.setRequestExtensions(new X509Extensions(oids, values));
213-
214205
// Add nonce extension
215206
ExtensionsGenerator extGen = new ExtensionsGenerator();
216207
byte[] nonce = new byte[16];
217-
Random rand = new Random();
218-
rand.nextBytes(nonce);
208+
RANDOM_INSTANCE.nextBytes(nonce);
219209

220210
extGen.addExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false,
221211
new DEROctetString(nonce));
@@ -236,7 +226,7 @@ public byte[] getEncoded() {
236226
OCSPReq request = generateOCSPRequest(rootCert,
237227
checkCert.getSerialNumber());
238228
byte[] array = request.getEncoded();
239-
URL urlt = new URL(url);
229+
URL urlt = new URI(url).toURL();
240230
Proxy tmpProxy = proxy == null ? Proxy.NO_PROXY : proxy;
241231
HttpURLConnection con = (HttpURLConnection) urlt.openConnection(tmpProxy);
242232
con.setRequestProperty("Content-Type", "application/ocsp-request");

openpdf-core/src/main/java/org/openpdf/text/pdf/PdfReader.java

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,13 @@ public class PdfReader implements PdfViewerPreferences, Closeable {
9292
static final PdfName[] pageInhCandidates = {PdfName.MEDIABOX,
9393
PdfName.ROTATE, PdfName.RESOURCES, PdfName.CROPBOX};
9494

95-
private static final byte[] endstream = PdfEncodings
96-
.convertToBytes("endstream", null);
95+
private static final String ENDSTREAM = "endstream";
96+
private static final byte[] endstreamBytes = PdfEncodings
97+
.convertToBytes(ENDSTREAM, null);
9798
private static final byte[] endobj = PdfEncodings.convertToBytes("endobj", null);
99+
private static final String FALSE = "false";
100+
private static final String ILLEGAL_LENGTH_VALUE = "illegal.length.value";
101+
public static final String BAD_USER_PASSWORD = "bad.user.password";
98102
private final PdfViewerPreferencesImp viewerPreferences = new PdfViewerPreferencesImp();
99103
protected PRTokeniser tokens;
100104
// Each xref pair is a position
@@ -1482,12 +1486,12 @@ private void readDecryptedDocObj() throws IOException {
14821486
o = enc.get(PdfName.LENGTH);
14831487
if (!o.isNumber()) {
14841488
throw new InvalidPdfException(
1485-
MessageLocalization.getComposedMessage("illegal.length.value"));
1489+
MessageLocalization.getComposedMessage(ILLEGAL_LENGTH_VALUE));
14861490
}
14871491
lengthValue = ((PdfNumber) o).intValue();
14881492
if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) {
14891493
throw new InvalidPdfException(
1490-
MessageLocalization.getComposedMessage("illegal.length.value"));
1494+
MessageLocalization.getComposedMessage(ILLEGAL_LENGTH_VALUE));
14911495
}
14921496
cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128;
14931497
break;
@@ -1513,14 +1517,14 @@ private void readDecryptedDocObj() throws IOException {
15131517
.getComposedMessage("no.compatible.encryption.found"));
15141518
}
15151519
PdfObject em = enc.get(PdfName.ENCRYPTMETADATA);
1516-
if (em != null && em.toString().equals("false")) {
1520+
if (em != null && em.toString().equals(FALSE)) {
15171521
cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA;
15181522
}
15191523
break;
15201524
case 6:
15211525
cryptoMode = PdfWriter.ENCRYPTION_AES_256_V3;
15221526
em = enc.get(PdfName.ENCRYPTMETADATA);
1523-
if (em != null && em.toString().equals("false")) {
1527+
if (em != null && em.toString().equals(FALSE)) {
15241528
cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA;
15251529
}
15261530
break;
@@ -1548,12 +1552,12 @@ private void readDecryptedDocObj() throws IOException {
15481552
o = enc.get(PdfName.LENGTH);
15491553
if (!o.isNumber()) {
15501554
throw new InvalidPdfException(
1551-
MessageLocalization.getComposedMessage("illegal.length.value"));
1555+
MessageLocalization.getComposedMessage(ILLEGAL_LENGTH_VALUE));
15521556
}
15531557
lengthValue = ((PdfNumber) o).intValue();
15541558
if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) {
15551559
throw new InvalidPdfException(
1556-
MessageLocalization.getComposedMessage("illegal.length.value"));
1560+
MessageLocalization.getComposedMessage(ILLEGAL_LENGTH_VALUE));
15571561
}
15581562
cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128;
15591563
recipients = (PdfArray) enc.get(PdfName.RECIPIENTS);
@@ -1582,7 +1586,7 @@ private void readDecryptedDocObj() throws IOException {
15821586
.getComposedMessage("no.compatible.encryption.found"));
15831587
}
15841588
PdfObject em = dic.get(PdfName.ENCRYPTMETADATA);
1585-
if (em != null && em.toString().equals("false")) {
1589+
if (em != null && em.toString().equals(FALSE)) {
15861590
cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA;
15871591
}
15881592

@@ -1634,7 +1638,7 @@ private void readDecryptedDocObj() throws IOException {
16341638
if (!equalsArray(uValue, decrypt.userKey,
16351639
(rValue == 3 || rValue == 4) ? 16 : 32)) {
16361640
throw new BadPasswordException(
1637-
MessageLocalization.getComposedMessage("bad.user.password"));
1641+
MessageLocalization.getComposedMessage(BAD_USER_PASSWORD));
16381642
}
16391643
} else {
16401644
ownerPasswordUsed = true;
@@ -1684,13 +1688,13 @@ decrypt it (revision 6 and later) - ISO 32000-2 section 7.6.4.3.3 */
16841688
// analog of step c of Algorithm 2.A for user password
16851689
hashAlg2B = decrypt.hashAlg2B(password, Arrays.copyOfRange(uValue, 32, 40), null);
16861690
if (!equalsArray(hashAlg2B, uValue, 32)) {
1687-
throw new BadPasswordException(MessageLocalization.getComposedMessage("bad.user.password"));
1691+
throw new BadPasswordException(MessageLocalization.getComposedMessage(BAD_USER_PASSWORD));
16881692
}
16891693
// step e of Algorithm 2.A
16901694
decrypt.setupByUserPassword(documentID, password, uValue, ueValue, oValue, oeValue, pValue);
16911695
// step f of Algorithm 2.A
16921696
if (!decrypt.decryptAndCheckPerms(permsValue)) {
1693-
throw new BadPasswordException(MessageLocalization.getComposedMessage("bad.user.password"));
1697+
throw new BadPasswordException(MessageLocalization.getComposedMessage(BAD_USER_PASSWORD));
16941698
}
16951699
}
16961700
pValue = decrypt.permissions;
@@ -1981,7 +1985,7 @@ private void checkPRStreamLength(PRStream stream) throws IOException {
19811985
String line = tokens.readString(20);
19821986
if (!line.startsWith("\nendstream")
19831987
&& !line.startsWith("\r\nendstream")
1984-
&& !line.startsWith("\rendstream") && !line.startsWith("endstream")) {
1988+
&& !line.startsWith("\rendstream") && !line.startsWith(ENDSTREAM)) {
19851989
calc = true;
19861990
}
19871991
}
@@ -1996,14 +2000,14 @@ private void checkPRStreamLength(PRStream stream) throws IOException {
19962000
if (!tokens.readLineSegment(tline)) {
19972001
break;
19982002
}
1999-
if (equalsn(tline, endstream)) {
2003+
if (equalsn(tline, endstreamBytes)) {
20002004
streamLength = pos - start;
20012005
break;
20022006
}
20032007
if (equalsn(tline, endobj)) {
20042008
tokens.seek(pos - 16);
20052009
String s = tokens.readString(16);
2006-
int index = s.indexOf("endstream");
2010+
int index = s.indexOf(ENDSTREAM);
20072011
if (index >= 0) {
20082012
pos = pos - 16 + index;
20092013
}
@@ -2523,7 +2527,7 @@ protected PdfObject readPRObject() throws IOException {
25232527
return new PdfBoolean(true);
25242528
} // else
25252529
return PdfBoolean.PDFTRUE;
2526-
} else if ("false".equals(sv)) {
2530+
} else if (FALSE.equals(sv)) {
25272531
if (readDepth == 0) {
25282532
return new PdfBoolean(false);
25292533
} // else
@@ -2985,6 +2989,7 @@ public int shuffleSubsetNames() {
29852989
*
29862990
* @return the subset prefix
29872991
*/
2992+
@SuppressWarnings("java:S2245") // weak random is here ok
29882993
private String createRandomSubsetPrefix() {
29892994
String s = "";
29902995
for (int k = 0; k < 6; ++k) {

openpdf-renderer/src/main/java/org/openpdf/renderer/core/OpenPdfCorePageRenderer.java

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@
4040
import org.openpdf.text.pdf.PdfString;
4141

4242
/**
43-
* Renders a single PDF page to a {@link Graphics2D} surface, parsing the page's
44-
* content stream with {@code openpdf-core}'s {@link PdfContentParser} and
45-
* dispatching the resulting operators to Java2D drawing calls.
43+
* Renders a single PDF page to a {@link Graphics2D} surface, parsing the page's content stream with
44+
* {@code openpdf-core}'s {@link PdfContentParser} and dispatching the resulting operators to Java2D drawing calls.
4645
*
4746
* <p>This is the {@code openpdf-core}-driven Java2D rasterizer that backs
4847
* {@link OpenPdfCoreRenderer#renderPage(int, float)}.</p>
@@ -79,7 +78,9 @@ final class OpenPdfCorePageRenderer {
7978

8079
private static final Logger LOG = Logger.getLogger(OpenPdfCorePageRenderer.class.getName());
8180

82-
/** Default user-space resolution of a PDF, in DPI. */
81+
/**
82+
* Default user-space resolution of a PDF, in DPI.
83+
*/
8384
private static final float PDF_USER_SPACE_DPI = 72f;
8485

8586
private final Graphics2D g2;
@@ -115,8 +116,7 @@ private OpenPdfCorePageRenderer(Graphics2D g2, PdfDictionary resources) {
115116
}
116117

117118
/**
118-
* Renders the given page to {@code g2}, sized to {@code targetWidth x targetHeight}
119-
* pixels at the requested DPI.
119+
* Renders the given page to {@code g2}, sized to {@code targetWidth x targetHeight} pixels at the requested DPI.
120120
*
121121
* @param reader the open PDF
122122
* @param pageNumber 1-based page number
@@ -198,8 +198,10 @@ private void processContent(byte[] contentBytes) throws IOException {
198198
}
199199
}
200200

201-
/** Dispatches one operator. Operands include the trailing operator literal at index size-1. */
202-
private void dispatch(String op, List<PdfObject> operands) throws IOException {
201+
/**
202+
* Dispatches one operator. Operands include the trailing operator literal at index size-1.
203+
*/
204+
private void dispatch(String op, List<PdfObject> operands) {
203205
switch (op) {
204206
// --- Graphics state ---
205207
case "q":
@@ -303,8 +305,7 @@ private void dispatch(String op, List<PdfObject> operands) throws IOException {
303305
strokePath();
304306
resetPath();
305307
break;
306-
case "f":
307-
case "F":
308+
case "f", "F":
308309
fillPath(Path2D.WIND_NON_ZERO);
309310
resetPath();
310311
break;
@@ -530,23 +531,33 @@ private Font mapFont(CMapAwareDocumentFont docFont, float size) {
530531
String name = docFont.getPostscriptFontName();
531532
if (name != null) {
532533
String lower = name.toLowerCase();
533-
if (lower.contains("mono") || lower.contains("courier")) {
534-
family = Font.MONOSPACED;
535-
} else if (lower.contains("sans") || lower.contains("helvetica")
536-
|| lower.contains("arial")) {
537-
family = Font.SANS_SERIF;
538-
}
539-
if (lower.contains("bold")) {
540-
style |= Font.BOLD;
541-
}
542-
if (lower.contains("italic") || lower.contains("oblique")) {
543-
style |= Font.ITALIC;
544-
}
534+
family = detectFontFamily(lower, family);
535+
style = detectStyles(lower, style);
545536
}
546537
}
547538
return new Font(family, style, 1).deriveFont(Math.max(size, 0.1f));
548539
}
549540

541+
private static int detectStyles(String lower, int style) {
542+
if (lower.contains("bold")) {
543+
style |= Font.BOLD;
544+
}
545+
if (lower.contains("italic") || lower.contains("oblique")) {
546+
style |= Font.ITALIC;
547+
}
548+
return style;
549+
}
550+
551+
private static String detectFontFamily(String lower, String family) {
552+
if (lower.contains("mono") || lower.contains("courier")) {
553+
family = Font.MONOSPACED;
554+
} else if (lower.contains("sans") || lower.contains("helvetica")
555+
|| lower.contains("arial")) {
556+
family = Font.SANS_SERIF;
557+
}
558+
return family;
559+
}
560+
550561
private CMapAwareDocumentFont lookupFont(String name) {
551562
if (resources == null) {
552563
return null;
@@ -597,8 +608,11 @@ private static float clamp01(float v) {
597608
return v;
598609
}
599610

600-
/** Mutable per-graphics-state snapshot. Not thread-safe. */
611+
/**
612+
* Mutable per-graphics-state snapshot. Not thread-safe.
613+
*/
601614
private static final class GState {
615+
602616
Color fillColor = Color.BLACK;
603617
Color strokeColor = Color.BLACK;
604618
float lineWidth = 1.0f;

0 commit comments

Comments
 (0)