You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2022/05/14 16:21:06 UTC
svn commit: r1900888 - in /pdfbox/trunk: fontbox/src/main/java/org/apache/fontbox/cff/ fontbox/src/test/java/org/apache/fontbox/cff/ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/
Author: lehmi
Date: Sat May 14 16:21:06 2022
New Revision: 1900888
URL: http://svn.apache.org/viewvc?rev=1900888&view=rev
Log:
PDFBOX-5143: use RandomAccessRead to read a CFF font
Added:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputByteArray.java (with props)
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputRandomAccessRead.java (with props)
pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/DataInputRandomAccessTest.java (with props)
Removed:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFDataInput.java
Modified:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInput.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharStringParser.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharStringParser.java
pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/CFFParserTest.java
pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/DataInputTest.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java?rev=1900888&r1=1900887&r2=1900888&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java Sat May 14 16:21:06 2022
@@ -28,6 +28,7 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.io.RandomAccessRead;
/**
@@ -72,8 +73,9 @@ public class CFFParser
*/
public List<CFFFont> parse(byte[] bytes, ByteSource source) throws IOException
{
+ // TODO do we need to store the source data of the font? It isn't used at all
this.source = source;
- return parse(bytes);
+ return parse(new DataInputByteArray(bytes));
}
/**
@@ -83,16 +85,32 @@ public class CFFParser
* @return the parsed CFF fonts
* @throws IOException If there is an error reading from the stream
*/
- public List<CFFFont> parse(byte[] bytes) throws IOException
+ public List<CFFFont> parse(RandomAccessRead randomAccessRead) throws IOException
{
- CFFDataInput input = new CFFDataInput(bytes);
+ // TODO do we need to store the source data of the font? It isn't used at all
+ byte[] bytes = new byte[(int) randomAccessRead.length()];
+ randomAccessRead.seek(0);
+ randomAccessRead.read(bytes);
+ randomAccessRead.seek(0);
+ this.source = new CFFBytesource(bytes);
+ return parse(new DataInputRandomAccessRead(randomAccessRead));
+ }
+ /**
+ * Parse CFF font using a byte array as input.
+ *
+ * @param bytes the given byte array
+ * @return the parsed CFF fonts
+ * @throws IOException If there is an error reading from the stream
+ */
+ private List<CFFFont> parse(DataInput input) throws IOException
+ {
String firstTag = readTagName(input);
// try to determine which kind of font we have
switch (firstTag)
{
case TAG_OTTO:
- input = createTaggedCFFDataInput(input, bytes);
+ input = createTaggedCFFDataInput(input);
break;
case TAG_TTCF:
throw new IOException("True Type Collection fonts are not supported.");
@@ -130,7 +148,7 @@ public class CFFParser
return fonts;
}
- private CFFDataInput createTaggedCFFDataInput(CFFDataInput input, byte[] bytes) throws IOException
+ private DataInput createTaggedCFFDataInput(DataInput input) throws IOException
{
// this is OpenType font containing CFF data
// so find CFF tag
@@ -150,42 +168,54 @@ public class CFFParser
long length = readLong(input);
if ("CFF ".equals(tagName))
{
- byte[] bytes2 = Arrays.copyOfRange(bytes, (int) offset, (int) (offset + length));
- return new CFFDataInput(bytes2);
+ input.setPosition((int)offset);
+ byte[] bytes2 = input.readBytes((int) length);
+ return new DataInputByteArray(bytes2);
}
}
throw new IOException("CFF tag not found in this OpenType font.");
}
- private static String readTagName(CFFDataInput input) throws IOException
+ private static String readTagName(DataInput input) throws IOException
{
byte[] b = input.readBytes(4);
return new String(b, StandardCharsets.ISO_8859_1);
}
- private static long readLong(CFFDataInput input) throws IOException
+ private static long readLong(DataInput input) throws IOException
+ {
+ return (input.readUnsignedShort() << 16) | input.readUnsignedShort();
+ }
+
+ private static int readOffSize(DataInput input) throws IOException
{
- return (input.readCard16() << 16) | input.readCard16();
+ int offSize = input.readUnsignedByte();
+ if (offSize < 1 || offSize > 4)
+ {
+ throw new IOException("Illegal (< 1 or > 4) offSize value " + offSize
+ + " in CFF font at position " + (input.getPosition() - 1));
+ }
+ return offSize;
}
- private static Header readHeader(CFFDataInput input) throws IOException
+ private static Header readHeader(DataInput input) throws IOException
{
- int major = input.readCard8();
- int minor = input.readCard8();
- int hdrSize = input.readCard8();
- int offSize = input.readOffSize();
+ int major = input.readUnsignedByte();
+ int minor = input.readUnsignedByte();
+ int hdrSize = input.readUnsignedByte();
+ int offSize = readOffSize(input);
return new Header(major, minor, hdrSize, offSize);
}
- private static int[] readIndexDataOffsets(CFFDataInput input) throws IOException
+ private static int[] readIndexDataOffsets(DataInput input) throws IOException
{
- int count = input.readCard16();
+ int count = input.readUnsignedShort();
if (count == 0)
{
return new int[0];
}
- int offSize = input.readOffSize();
- int[] offsets = new int[count+1];
+ int offSize = readOffSize(input);
+ int[] offsets = new int[count + 1];
for (int i = 0; i <= count; i++)
{
int offset = input.readOffset(offSize);
@@ -198,7 +228,7 @@ public class CFFParser
return offsets;
}
- private static byte[][] readIndexData(CFFDataInput input) throws IOException
+ private static byte[][] readIndexData(DataInput input) throws IOException
{
int[] offsets = readIndexDataOffsets(input);
if (offsets.length == 0)
@@ -215,7 +245,7 @@ public class CFFParser
return indexDataValues;
}
- private static String[] readStringIndexData(CFFDataInput input) throws IOException
+ private static String[] readStringIndexData(DataInput input) throws IOException
{
int[] offsets = readIndexDataOffsets(input);
if (offsets.length == 0)
@@ -238,7 +268,7 @@ public class CFFParser
return indexDataValues;
}
- private static DictData readDictData(CFFDataInput input) throws IOException
+ private static DictData readDictData(DataInput input) throws IOException
{
DictData dict = new DictData();
while (input.hasRemaining())
@@ -248,7 +278,7 @@ public class CFFParser
return dict;
}
- private static DictData readDictData(CFFDataInput input, int offset, int dictSize)
+ private static DictData readDictData(DataInput input, int offset, int dictSize)
throws IOException
{
DictData dict = new DictData();
@@ -264,7 +294,7 @@ public class CFFParser
return dict;
}
- private static DictData.Entry readEntry(CFFDataInput input) throws IOException
+ private static DictData.Entry readEntry(DataInput input) throws IOException
{
DictData.Entry entry = new DictData.Entry();
while (true)
@@ -296,7 +326,7 @@ public class CFFParser
return entry;
}
- private static String readOperator(CFFDataInput input, int b0) throws IOException
+ private static String readOperator(DataInput input, int b0) throws IOException
{
if (b0 == 12)
{
@@ -307,7 +337,7 @@ public class CFFParser
}
- private static Integer readIntegerNumber(CFFDataInput input, int b0) throws IOException
+ private static Integer readIntegerNumber(DataInput input, int b0) throws IOException
{
if (b0 == 28)
{
@@ -337,7 +367,7 @@ public class CFFParser
}
}
- private static Double readRealNumber(CFFDataInput input) throws IOException
+ private static Double readRealNumber(DataInput input) throws IOException
{
StringBuilder sb = new StringBuilder();
boolean done = false;
@@ -424,10 +454,10 @@ public class CFFParser
}
}
- private CFFFont parseFont(CFFDataInput input, String name, byte[] topDictIndex) throws IOException
+ private CFFFont parseFont(DataInput input, String name, byte[] topDictIndex) throws IOException
{
// top dict
- CFFDataInput topDictInput = new CFFDataInput(topDictIndex);
+ DataInputByteArray topDictInput = new DataInputByteArray(topDictIndex);
DictData topDict = readDictData(topDictInput);
// we don't support synthetic fonts
@@ -628,7 +658,8 @@ public class CFFParser
/**
* Parse dictionaries specific to a CIDFont.
*/
- private void parseCIDFontDicts(CFFDataInput input, DictData topDict, CFFCIDFont font, int nrOfcharStrings)
+ private void parseCIDFontDicts(DataInput input, DictData topDict, CFFCIDFont font,
+ int nrOfcharStrings)
throws IOException
{
// In a CIDKeyed Font, the Private dictionary isn't in the Top Dict but in the Font dict
@@ -653,7 +684,7 @@ public class CFFParser
for (byte[] bytes : fdIndex)
{
- CFFDataInput fontDictInput = new CFFDataInput(bytes);
+ DataInputByteArray fontDictInput = new DataInputByteArray(bytes);
DictData fontDict = readDictData(fontDictInput);
// read private dict
@@ -734,7 +765,8 @@ public class CFFParser
/**
* Parse dictionaries specific to a Type 1-equivalent font.
*/
- private void parseType1Dicts(CFFDataInput input, DictData topDict, CFFType1Font font, CFFCharset charset)
+ private void parseType1Dicts(DataInput input, DictData topDict, CFFType1Font font,
+ CFFCharset charset)
throws IOException
{
// encoding
@@ -804,9 +836,9 @@ public class CFFParser
return entry != null && entry.hasOperands() ? readString(entry.getNumber(0).intValue()) : null;
}
- private CFFEncoding readEncoding(CFFDataInput dataInput, CFFCharset charset) throws IOException
+ private CFFEncoding readEncoding(DataInput dataInput, CFFCharset charset) throws IOException
{
- int format = dataInput.readCard8();
+ int format = dataInput.readUnsignedByte();
int baseFormat = format & 0x7f;
switch (baseFormat)
@@ -820,15 +852,15 @@ public class CFFParser
}
}
- private Format0Encoding readFormat0Encoding(CFFDataInput dataInput, CFFCharset charset,
+ private Format0Encoding readFormat0Encoding(DataInput dataInput, CFFCharset charset,
int format)
throws IOException
{
- Format0Encoding encoding = new Format0Encoding(dataInput.readCard8());
+ Format0Encoding encoding = new Format0Encoding(dataInput.readUnsignedByte());
encoding.add(0, 0, ".notdef");
for (int gid = 1; gid <= encoding.nCodes; gid++)
{
- int code = dataInput.readCard8();
+ int code = dataInput.readUnsignedByte();
int sid = charset.getSIDForGID(gid);
encoding.add(code, sid, readString(sid));
}
@@ -839,16 +871,16 @@ public class CFFParser
return encoding;
}
- private Format1Encoding readFormat1Encoding(CFFDataInput dataInput, CFFCharset charset,
+ private Format1Encoding readFormat1Encoding(DataInput dataInput, CFFCharset charset,
int format) throws IOException
{
- Format1Encoding encoding = new Format1Encoding(dataInput.readCard8());
+ Format1Encoding encoding = new Format1Encoding(dataInput.readUnsignedByte());
encoding.add(0, 0, ".notdef");
int gid = 1;
for (int i = 0; i < encoding.nRanges; i++)
{
- int rangeFirst = dataInput.readCard8(); // First code in range
- int rangeLeft = dataInput.readCard8(); // Codes left in range (excluding first)
+ int rangeFirst = dataInput.readUnsignedByte(); // First code in range
+ int rangeLeft = dataInput.readUnsignedByte(); // Codes left in range (excluding first)
for (int j = 0; j <= rangeLeft; j++)
{
int sid = charset.getSIDForGID(gid);
@@ -863,15 +895,15 @@ public class CFFParser
return encoding;
}
- private void readSupplement(CFFDataInput dataInput, CFFBuiltInEncoding encoding)
+ private void readSupplement(DataInput dataInput, CFFBuiltInEncoding encoding)
throws IOException
{
- int nSups = dataInput.readCard8();
+ int nSups = dataInput.readUnsignedByte();
encoding.supplement = new CFFBuiltInEncoding.Supplement[nSups];
for (int i = 0; i < nSups; i++)
{
- int code = dataInput.readCard8();
- int sid = dataInput.readSID();
+ int code = dataInput.readUnsignedByte();
+ int sid = dataInput.readUnsignedShort();
encoding.supplement[i] = new CFFBuiltInEncoding.Supplement(code, sid, readString(sid));
encoding.add(encoding.supplement[i]);
}
@@ -884,9 +916,9 @@ public class CFFParser
* @return the FDSelect data
* @throws IOException
*/
- private static FDSelect readFDSelect(CFFDataInput dataInput, int nGlyphs) throws IOException
+ private static FDSelect readFDSelect(DataInput dataInput, int nGlyphs) throws IOException
{
- int format = dataInput.readCard8();
+ int format = dataInput.readUnsignedByte();
switch (format)
{
case 0:
@@ -905,13 +937,13 @@ public class CFFParser
* @return the Format 0 of the FDSelect data
* @throws IOException
*/
- private static Format0FDSelect readFormat0FDSelect(CFFDataInput dataInput, int nGlyphs)
+ private static Format0FDSelect readFormat0FDSelect(DataInput dataInput, int nGlyphs)
throws IOException
{
int[] fds = new int[nGlyphs];
for (int i = 0; i < nGlyphs; i++)
{
- fds[i] = dataInput.readCard8();
+ fds[i] = dataInput.readUnsignedByte();
}
return new Format0FDSelect(fds);
}
@@ -923,17 +955,17 @@ public class CFFParser
* @return the Format 3 of the FDSelect data
* @throws IOException
*/
- private static Format3FDSelect readFormat3FDSelect(CFFDataInput dataInput)
+ private static Format3FDSelect readFormat3FDSelect(DataInput dataInput)
throws IOException
{
- int nbRanges = dataInput.readCard16();
+ int nbRanges = dataInput.readUnsignedShort();
Range3[] range3 = new Range3[nbRanges];
for (int i = 0; i < nbRanges; i++)
{
- range3[i] = new Range3(dataInput.readCard16(), dataInput.readCard8());
+ range3[i] = new Range3(dataInput.readUnsignedShort(), dataInput.readUnsignedByte());
}
- return new Format3FDSelect(range3, dataInput.readCard16());
+ return new Format3FDSelect(range3, dataInput.readUnsignedShort());
}
/**
@@ -1037,10 +1069,10 @@ public class CFFParser
}
}
- private CFFCharset readCharset(CFFDataInput dataInput, int nGlyphs, boolean isCIDFont)
+ private CFFCharset readCharset(DataInput dataInput, int nGlyphs, boolean isCIDFont)
throws IOException
{
- int format = dataInput.readCard8();
+ int format = dataInput.readUnsignedByte();
switch (format)
{
case 0:
@@ -1055,7 +1087,7 @@ public class CFFParser
}
}
- private Format0Charset readFormat0Charset(CFFDataInput dataInput, int nGlyphs,
+ private Format0Charset readFormat0Charset(DataInput dataInput, int nGlyphs,
boolean isCIDFont) throws IOException
{
Format0Charset charset = new Format0Charset(isCIDFont);
@@ -1064,7 +1096,7 @@ public class CFFParser
charset.addCID(0, 0);
for (int gid = 1; gid < nGlyphs; gid++)
{
- charset.addCID(gid, dataInput.readSID());
+ charset.addCID(gid, dataInput.readUnsignedShort());
}
}
else
@@ -1072,14 +1104,14 @@ public class CFFParser
charset.addSID(0, 0, ".notdef");
for (int gid = 1; gid < nGlyphs; gid++)
{
- int sid = dataInput.readSID();
+ int sid = dataInput.readUnsignedShort();
charset.addSID(gid, sid, readString(sid));
}
}
return charset;
}
- private Format1Charset readFormat1Charset(CFFDataInput dataInput, int nGlyphs,
+ private Format1Charset readFormat1Charset(DataInput dataInput, int nGlyphs,
boolean isCIDFont) throws IOException
{
Format1Charset charset = new Format1Charset(isCIDFont);
@@ -1089,8 +1121,8 @@ public class CFFParser
int gid = 1;
while (gid < nGlyphs)
{
- int rangeFirst = dataInput.readSID();
- int rangeLeft = dataInput.readCard8();
+ int rangeFirst = dataInput.readUnsignedShort();
+ int rangeLeft = dataInput.readUnsignedByte();
charset.addRangeMapping(new RangeMapping(gid, rangeFirst, rangeLeft));
gid += rangeLeft + 1;
}
@@ -1101,8 +1133,8 @@ public class CFFParser
int gid = 1;
while (gid < nGlyphs)
{
- int rangeFirst = dataInput.readSID();
- int rangeLeft = dataInput.readCard8() + 1;
+ int rangeFirst = dataInput.readUnsignedShort();
+ int rangeLeft = dataInput.readUnsignedByte() + 1;
for (int j = 0; j < rangeLeft; j++)
{
int sid = rangeFirst + j;
@@ -1114,7 +1146,7 @@ public class CFFParser
return charset;
}
- private Format2Charset readFormat2Charset(CFFDataInput dataInput, int nGlyphs,
+ private Format2Charset readFormat2Charset(DataInput dataInput, int nGlyphs,
boolean isCIDFont) throws IOException
{
Format2Charset charset = new Format2Charset(isCIDFont);
@@ -1124,8 +1156,8 @@ public class CFFParser
int gid = 1;
while (gid < nGlyphs)
{
- int first = dataInput.readSID();
- int nLeft = dataInput.readCard16();
+ int first = dataInput.readUnsignedShort();
+ int nLeft = dataInput.readUnsignedShort();
charset.addRangeMapping(new RangeMapping(gid, first, nLeft));
gid += nLeft + 1;
}
@@ -1136,8 +1168,8 @@ public class CFFParser
int gid = 1;
while (gid < nGlyphs)
{
- int first = dataInput.readSID();
- int nLeft = dataInput.readCard16() + 1;
+ int first = dataInput.readUnsignedShort();
+ int nLeft = dataInput.readUnsignedShort() + 1;
for (int j = 0; j < nLeft; j++)
{
int sid = first + j;
@@ -1580,6 +1612,25 @@ public class CFFParser
}
}
+ /**
+ * Allows bytes to be re-read later by CFFParser.
+ */
+ private static class CFFBytesource implements CFFParser.ByteSource
+ {
+ private final byte[] bytes;
+
+ CFFBytesource(byte[] bytes)
+ {
+ this.bytes = bytes;
+ }
+
+ @Override
+ public byte[] getBytes() throws IOException
+ {
+ return bytes;
+ }
+ }
+
@Override
public String toString()
{
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInput.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInput.java?rev=1900888&r1=1900887&r2=1900888&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInput.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInput.java Sat May 14 16:21:06 2022
@@ -19,42 +19,24 @@ package org.apache.fontbox.cff;
import java.io.IOException;
/**
- * This class contains some functionality to read a byte buffer.
+ * This interface defines some functionality to read a CFF font.
*
* @author Villu Ruusmann
*/
-public class DataInput
+public interface DataInput
{
- private final byte[] inputBuffer;
- private int bufferPosition = 0;
-
- /**
- * Constructor.
- * @param buffer the buffer to be read
- */
- public DataInput(byte[] buffer)
- {
- inputBuffer = buffer;
- }
-
/**
* Determines if there are any bytes left to read or not.
* @return true if there are any bytes left to read
*/
- public boolean hasRemaining()
- {
- return bufferPosition < inputBuffer.length;
- }
+ public boolean hasRemaining() throws IOException;
/**
* Returns the current position.
* @return current position
*/
- public int getPosition()
- {
- return bufferPosition;
- }
+ public int getPosition() throws IOException;
/**
* Sets the current position to the given value.
@@ -62,47 +44,21 @@ public class DataInput
* @param position the given position
* @throws IOException if the new position ist out of range
*/
- public void setPosition(int position) throws IOException
- {
- if (position < 0)
- {
- throw new IOException("position is negative");
- }
- if (position >= inputBuffer.length)
- {
- throw new IOException(
- "New position is out of range " + position + " >= " + inputBuffer.length);
- }
- bufferPosition = position;
- }
+ public void setPosition(int position) throws IOException;
/**
* Read one single byte from the buffer.
* @return the byte
* @throws IOException if an error occurs during reading
*/
- public byte readByte() throws IOException
- {
- if (!hasRemaining())
- {
- throw new IOException("End off buffer reached");
- }
- return inputBuffer[bufferPosition++];
- }
+ public byte readByte() throws IOException;
/**
* Read one single unsigned byte from the buffer.
* @return the unsigned byte as int
* @throws IOException if an error occurs during reading
*/
- public int readUnsignedByte() throws IOException
- {
- if (!hasRemaining())
- {
- throw new IOException("End off buffer reached");
- }
- return inputBuffer[bufferPosition++] & 0xff;
- }
+ public int readUnsignedByte() throws IOException;
/**
* Peeks one single unsigned byte from the buffer.
@@ -111,26 +67,14 @@ public class DataInput
* @return the unsigned byte as int
* @throws IOException if an error occurs during reading
*/
- public int peekUnsignedByte(int offset) throws IOException
- {
- if (offset < 0)
- {
- throw new IOException("offset is negative");
- }
- if (bufferPosition + offset >= inputBuffer.length)
- {
- throw new IOException("Offset position is out of range " + (bufferPosition + offset)
- + " >= " + inputBuffer.length);
- }
- return inputBuffer[bufferPosition + offset] & 0xff;
- }
+ public int peekUnsignedByte(int offset) throws IOException;
/**
* Read one single short value from the buffer.
* @return the short value
* @throws IOException if an error occurs during reading
*/
- public short readShort() throws IOException
+ default short readShort() throws IOException
{
return (short) readUnsignedShort();
}
@@ -140,7 +84,7 @@ public class DataInput
* @return the unsigned short value as int
* @throws IOException if an error occurs during reading
*/
- public int readUnsignedShort() throws IOException
+ default int readUnsignedShort() throws IOException
{
int b1 = readUnsignedByte();
int b2 = readUnsignedByte();
@@ -152,7 +96,7 @@ public class DataInput
* @return the int value
* @throws IOException if an error occurs during reading
*/
- public int readInt() throws IOException
+ default int readInt() throws IOException
{
int b1 = readUnsignedByte();
int b2 = readUnsignedByte();
@@ -167,24 +111,23 @@ public class DataInput
* @return an array with containing the bytes from the buffer
* @throws IOException if an error occurs during reading
*/
- public byte[] readBytes(int length) throws IOException
+ public byte[] readBytes(int length) throws IOException;
+
+ public int length() throws IOException;
+
+ /**
+ * Read the offset from the buffer.
+ * @param offSize the given offsize
+ * @return the offset
+ * @throws IOException if an error occurs during reading
+ */
+ default int readOffset(int offSize) throws IOException
{
- if (length < 0)
+ int value = 0;
+ for (int i = 0; i < offSize; i++)
{
- throw new IOException("length is negative");
+ value = value << 8 | readUnsignedByte();
}
- if (inputBuffer.length - bufferPosition < length)
- {
- throw new IOException("Premature end of buffer reached");
- }
- byte[] bytes = new byte[length];
- System.arraycopy(inputBuffer, bufferPosition, bytes, 0, length);
- bufferPosition += length;
- return bytes;
- }
-
- public int length()
- {
- return inputBuffer.length;
+ return value;
}
}
\ No newline at end of file
Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputByteArray.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputByteArray.java?rev=1900888&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputByteArray.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputByteArray.java Sat May 14 16:21:06 2022
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.fontbox.cff;
+
+import java.io.IOException;
+
+/**
+ * This class implements the DataInput interface using a byte buffer as source.
+ *
+ * @author Villu Ruusmann
+ */
+public class DataInputByteArray implements DataInput
+{
+
+ private final byte[] inputBuffer;
+ private int bufferPosition = 0;
+
+ /**
+ * Constructor.
+ * @param buffer the buffer to be read
+ */
+ public DataInputByteArray(byte[] buffer)
+ {
+ inputBuffer = buffer;
+ }
+
+ /**
+ * Determines if there are any bytes left to read or not.
+ * @return true if there are any bytes left to read
+ */
+ @Override
+ public boolean hasRemaining() throws IOException
+ {
+ return bufferPosition < inputBuffer.length;
+ }
+
+ /**
+ * Returns the current position.
+ * @return current position
+ */
+ @Override
+ public int getPosition()
+ {
+ return bufferPosition;
+ }
+
+ /**
+ * Sets the current position to the given value.
+ *
+ * @param position the given position
+ * @throws IOException if the new position ist out of range
+ */
+ @Override
+ public void setPosition(int position) throws IOException
+ {
+ if (position < 0)
+ {
+ throw new IOException("position is negative");
+ }
+ if (position >= inputBuffer.length)
+ {
+ throw new IOException(
+ "New position is out of range " + position + " >= " + inputBuffer.length);
+ }
+ bufferPosition = position;
+ }
+
+ /**
+ * Read one single byte from the buffer.
+ * @return the byte
+ * @throws IOException if an error occurs during reading
+ */
+ @Override
+ public byte readByte() throws IOException
+ {
+ if (!hasRemaining())
+ {
+ throw new IOException("End off buffer reached");
+ }
+ return inputBuffer[bufferPosition++];
+ }
+
+ /**
+ * Read one single unsigned byte from the buffer.
+ * @return the unsigned byte as int
+ * @throws IOException if an error occurs during reading
+ */
+ @Override
+ public int readUnsignedByte() throws IOException
+ {
+ if (!hasRemaining())
+ {
+ throw new IOException("End off buffer reached");
+ }
+ return inputBuffer[bufferPosition++] & 0xff;
+ }
+
+ /**
+ * Peeks one single unsigned byte from the buffer.
+ *
+ * @param offset offset to the byte to be peeked
+ * @return the unsigned byte as int
+ * @throws IOException if an error occurs during reading
+ */
+ @Override
+ public int peekUnsignedByte(int offset) throws IOException
+ {
+ if (offset < 0)
+ {
+ throw new IOException("offset is negative");
+ }
+ if (bufferPosition + offset >= inputBuffer.length)
+ {
+ throw new IOException("Offset position is out of range " + (bufferPosition + offset)
+ + " >= " + inputBuffer.length);
+ }
+ return inputBuffer[bufferPosition + offset] & 0xff;
+ }
+
+ /**
+ * Read a number of single byte values from the buffer.
+ * @param length the number of bytes to be read
+ * @return an array with containing the bytes from the buffer
+ * @throws IOException if an error occurs during reading
+ */
+ @Override
+ public byte[] readBytes(int length) throws IOException
+ {
+ if (length < 0)
+ {
+ throw new IOException("length is negative");
+ }
+ if (inputBuffer.length - bufferPosition < length)
+ {
+ throw new IOException("Premature end of buffer reached");
+ }
+ byte[] bytes = new byte[length];
+ System.arraycopy(inputBuffer, bufferPosition, bytes, 0, length);
+ bufferPosition += length;
+ return bytes;
+ }
+
+ @Override
+ public int length() throws IOException
+ {
+ return inputBuffer.length;
+ }
+}
\ No newline at end of file
Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputByteArray.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputRandomAccessRead.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputRandomAccessRead.java?rev=1900888&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputRandomAccessRead.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputRandomAccessRead.java Sat May 14 16:21:06 2022
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.fontbox.cff;
+
+import java.io.IOException;
+import org.apache.pdfbox.io.RandomAccessRead;
+
+/**
+ * This class implements the DataInput interface using a RandomAccessRead as source.
+ */
+public class DataInputRandomAccessRead implements DataInput
+{
+
+ private final RandomAccessRead randomAccessRead;
+
+ /**
+ * Constructor.
+ *
+ * @param randomAccessRead the source to be read from
+ */
+ public DataInputRandomAccessRead(RandomAccessRead randomAccessRead)
+ {
+ this.randomAccessRead = randomAccessRead;
+ }
+
+ /**
+ * Determines if there are any bytes left to read or not.
+ * @return true if there are any bytes left to read
+ */
+ @Override
+ public boolean hasRemaining() throws IOException
+ {
+ return randomAccessRead.available() > 0;
+ }
+
+ /**
+ * Returns the current position.
+ * @return current position
+ */
+ @Override
+ public int getPosition() throws IOException
+ {
+ return (int) randomAccessRead.getPosition();
+ }
+
+ /**
+ * Sets the current position to the given value.
+ *
+ * @param position the given position
+ * @throws IOException if the new position ist out of range
+ */
+ @Override
+ public void setPosition(int position) throws IOException
+ {
+ if (position < 0)
+ {
+ throw new IOException("position is negative");
+ }
+ if (position >= randomAccessRead.length())
+ {
+ throw new IOException("New position is out of range " + position + " >= "
+ + randomAccessRead.length());
+ }
+ randomAccessRead.seek(position);
+ }
+
+ /**
+ * Read one single byte from the buffer.
+ * @return the byte
+ * @throws IOException if an error occurs during reading
+ */
+ @Override
+ public byte readByte() throws IOException
+ {
+ if (!hasRemaining())
+ {
+ throw new IOException("End off buffer reached");
+ }
+ return (byte) randomAccessRead.read();
+ }
+
+ /**
+ * Read one single unsigned byte from the buffer.
+ * @return the unsigned byte as int
+ * @throws IOException if an error occurs during reading
+ */
+ @Override
+ public int readUnsignedByte() throws IOException
+ {
+ if (!hasRemaining())
+ {
+ throw new IOException("End off buffer reached");
+ }
+ return randomAccessRead.read();
+ }
+
+ /**
+ * Peeks one single unsigned byte from the buffer.
+ *
+ * @param offset offset to the byte to be peeked
+ * @return the unsigned byte as int
+ * @throws IOException if an error occurs during reading
+ */
+ @Override
+ public int peekUnsignedByte(int offset) throws IOException
+ {
+ if (offset < 0)
+ {
+ throw new IOException("offset is negative");
+ }
+ if (offset == 0)
+ {
+ return randomAccessRead.peek();
+ }
+ long currentPosition = randomAccessRead.getPosition();
+ if (currentPosition + offset >= randomAccessRead.length())
+ {
+ throw new IOException("Offset position is out of range " + (currentPosition + offset)
+ + " >= " + randomAccessRead.length());
+ }
+ randomAccessRead.seek(currentPosition + offset);
+ int peekValue = randomAccessRead.read();
+ randomAccessRead.seek(currentPosition);
+ return peekValue;
+ }
+
+ /**
+ * Read a number of single byte values from the buffer.
+ * @param length the number of bytes to be read
+ * @return an array with containing the bytes from the buffer
+ * @throws IOException if an error occurs during reading
+ */
+ @Override
+ public byte[] readBytes(int length) throws IOException
+ {
+ if (length < 0)
+ {
+ throw new IOException("length is negative");
+ }
+ if (randomAccessRead.length() - randomAccessRead.getPosition() < length)
+ {
+ throw new IOException("Premature end of buffer reached");
+ }
+ byte[] bytes = new byte[length];
+ for (int i = 0; i < length; i++)
+ bytes[i] = readByte();
+ return bytes;
+ }
+
+ @Override
+ public int length() throws IOException
+ {
+ return (int) randomAccessRead.length();
+ }
+
+}
\ No newline at end of file
Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/DataInputRandomAccessRead.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharStringParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharStringParser.java?rev=1900888&r1=1900887&r2=1900888&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharStringParser.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharStringParser.java Sat May 14 16:21:06 2022
@@ -76,7 +76,7 @@ public class Type1CharStringParser
private List<Object> parse(byte[] bytes, List<byte[]> subrs, List<Object> sequence)
throws IOException
{
- DataInput input = new DataInput(bytes);
+ DataInput input = new DataInputByteArray(bytes);
while (input.hasRemaining())
{
int b0 = input.readUnsignedByte();
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharStringParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharStringParser.java?rev=1900888&r1=1900887&r2=1900888&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharStringParser.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharStringParser.java Sat May 14 16:21:06 2022
@@ -74,7 +74,7 @@ public class Type2CharStringParser
private List<Object> parseSequence(byte[] bytes, byte[][] globalSubrIndex,
byte[][] localSubrIndex) throws IOException
{
- DataInput input = new DataInput(bytes);
+ DataInput input = new DataInputByteArray(bytes);
boolean localSubroutineIndexProvided = localSubrIndex != null && localSubrIndex.length > 0;
boolean globalSubroutineIndexProvided = globalSubrIndex != null && globalSubrIndex.length > 0;
Modified: pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/CFFParserTest.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/CFFParserTest.java?rev=1900888&r1=1900887&r2=1900888&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/CFFParserTest.java (original)
+++ pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/CFFParserTest.java Sat May 14 16:21:06 2022
@@ -20,14 +20,12 @@ import static org.junit.jupiter.api.Asse
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import org.apache.fontbox.util.BoundingBox;
+import org.apache.pdfbox.io.RandomAccessReadBufferedFile;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -205,10 +203,9 @@ class CFFParserTest
private static List<CFFFont> readFont(String filename) throws IOException
{
- ByteArrayOutputStream content = new ByteArrayOutputStream();
- Files.copy(Paths.get(filename), content);
+ RandomAccessReadBufferedFile randomAccessRead = new RandomAccessReadBufferedFile(filename);
CFFParser parser = new CFFParser();
- return parser.parse(content.toByteArray());
+ return parser.parse(randomAccessRead);
}
private void assertNumberList(String message, int[] expected, List<Number> found)
Added: pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/DataInputRandomAccessTest.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/DataInputRandomAccessTest.java?rev=1900888&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/DataInputRandomAccessTest.java (added)
+++ pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/DataInputRandomAccessTest.java Sat May 14 16:21:06 2022
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2017 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.fontbox.cff;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.pdfbox.io.RandomAccessReadBuffer;
+import org.junit.jupiter.api.Test;
+
+class DataInputRandomAccessTest
+{
+ @Test
+ void testReadBytes() throws IOException
+ {
+ byte[] data = new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9 };
+ DataInput dataInput = new DataInputRandomAccessRead(new RandomAccessReadBuffer(data));
+ assertThrows(IOException.class, () -> dataInput.readBytes(20));
+ assertArrayEquals(new byte[] { 0 }, dataInput.readBytes(1));
+ assertArrayEquals(new byte[] { -1, 2, -3 }, dataInput.readBytes(3));
+ dataInput.setPosition(6);
+ assertArrayEquals(new byte[] { 6, -7, 8 }, dataInput.readBytes(3));
+ assertThrows(IOException.class, () -> dataInput.readBytes(-1));
+ assertThrows(IOException.class, () -> dataInput.readBytes(5));
+ }
+
+ @Test
+ void testReadByte() throws IOException
+ {
+ byte[] data = new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9 };
+ DataInput dataInput = new DataInputRandomAccessRead(new RandomAccessReadBuffer(data));
+ assertEquals(0, dataInput.readByte());
+ assertEquals(-1, dataInput.readByte());
+ dataInput.setPosition(6);
+ assertEquals(6, dataInput.readByte());
+ assertEquals(-7, dataInput.readByte());
+ dataInput.setPosition(dataInput.length() - 1);
+ assertEquals(-9, dataInput.readByte());
+ assertThrows(IOException.class, () -> dataInput.readByte());
+ }
+
+ @Test
+ void testReadUnsignedByte() throws IOException
+ {
+ byte[] data = new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9 };
+ DataInput dataInput = new DataInputRandomAccessRead(new RandomAccessReadBuffer(data));
+ assertEquals(0, dataInput.readUnsignedByte());
+ assertEquals(255, dataInput.readUnsignedByte());
+ dataInput.setPosition(6);
+ assertEquals(6, dataInput.readUnsignedByte());
+ assertEquals(249, dataInput.readUnsignedByte());
+ dataInput.setPosition(dataInput.length() - 1);
+ assertEquals(247, dataInput.readUnsignedByte());
+ assertThrows(IOException.class, () -> dataInput.readUnsignedByte());
+ }
+
+ @Test
+ void testBasics() throws IOException
+ {
+ byte[] data = new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9 };
+ DataInput dataInput = new DataInputRandomAccessRead(new RandomAccessReadBuffer(data));
+ assertEquals(10, dataInput.length());
+ assertTrue(dataInput.hasRemaining());
+ assertThrows(IOException.class, () -> dataInput.setPosition(-1));
+ assertThrows(IOException.class, () -> dataInput.setPosition(dataInput.length()));
+ }
+
+ @Test
+ void testPeek() throws IOException
+ {
+ byte[] data = new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9 };
+ DataInput dataInput = new DataInputRandomAccessRead(new RandomAccessReadBuffer(data));
+ assertEquals(0, dataInput.peekUnsignedByte(0));
+ assertEquals(251, dataInput.peekUnsignedByte(5));
+ assertThrows(IOException.class, () -> dataInput.peekUnsignedByte(-1));
+ assertThrows(IOException.class, () -> dataInput.peekUnsignedByte(dataInput.length()));
+ }
+
+ @Test
+ void testReadShort() throws IOException
+ {
+ byte[] data = new byte[] { 0x00, 0x0F, (byte) 0xAA, 0, (byte) 0xFE, (byte) 0xFF };
+ DataInput dataInput = new DataInputRandomAccessRead(new RandomAccessReadBuffer(data));
+ assertEquals((short) 0x000F, dataInput.readShort());
+ assertEquals((short) 0xAA00, dataInput.readShort());
+ assertEquals((short) 0xFEFF, dataInput.readShort());
+ assertThrows(IOException.class, () -> dataInput.readShort());
+ }
+
+ @Test
+ void testReadUnsignedShort() throws IOException
+ {
+ byte[] data = new byte[] { 0x00, 0x0F, (byte) 0xAA, 0, (byte) 0xFE, (byte) 0xFF };
+ DataInput dataInput = new DataInputRandomAccessRead(new RandomAccessReadBuffer(data));
+ assertEquals(0x000F, dataInput.readUnsignedShort());
+ assertEquals(0xAA00, dataInput.readUnsignedShort());
+ assertEquals(0xFEFF, dataInput.readUnsignedShort());
+ assertThrows(IOException.class, () -> dataInput.readUnsignedShort());
+
+ byte[] data2 = new byte[] { 0x00 };
+ DataInput dataInput2 = new DataInputRandomAccessRead(new RandomAccessReadBuffer(data2));
+ assertThrows(IOException.class, () -> dataInput2.readUnsignedShort());
+ }
+
+ @Test
+ void testReadInt() throws IOException
+ {
+ byte[] data = new byte[] { 0x00, 0x0F, (byte) 0xAA, 0, (byte) 0xFE, (byte) 0xFF, 0x30,
+ 0x50 };
+ DataInput dataInput = new DataInputRandomAccessRead(new RandomAccessReadBuffer(data));
+ assertEquals(0x000FAA00, dataInput.readInt());
+ assertEquals(0xFEFF3050, dataInput.readInt());
+ assertThrows(IOException.class, () -> dataInput.readInt());
+
+ byte[] data2 = new byte[] { 0x00, 0x0F, (byte) 0xAA };
+ DataInput dataInput2 = new DataInputRandomAccessRead(new RandomAccessReadBuffer(data2));
+ assertThrows(IOException.class, () -> dataInput2.readInt());
+
+ }
+}
Propchange: pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/DataInputRandomAccessTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/DataInputTest.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/DataInputTest.java?rev=1900888&r1=1900887&r2=1900888&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/DataInputTest.java (original)
+++ pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/DataInputTest.java Sat May 14 16:21:06 2022
@@ -30,7 +30,7 @@ class DataInputTest
void testReadBytes() throws IOException
{
byte[] data = new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9 };
- DataInput dataInput = new DataInput(data);
+ DataInput dataInput = new DataInputByteArray(data);
assertThrows(IOException.class, () -> dataInput.readBytes(20));
assertArrayEquals(new byte[] { 0 }, dataInput.readBytes(1));
assertArrayEquals(new byte[] { -1, 2, -3 }, dataInput.readBytes(3));
@@ -44,7 +44,7 @@ class DataInputTest
void testReadByte() throws IOException
{
byte[] data = new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9 };
- DataInput dataInput = new DataInput(data);
+ DataInput dataInput = new DataInputByteArray(data);
assertEquals(0, dataInput.readByte());
assertEquals(-1, dataInput.readByte());
dataInput.setPosition(6);
@@ -59,7 +59,7 @@ class DataInputTest
void testReadUnsignedByte() throws IOException
{
byte[] data = new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9 };
- DataInput dataInput = new DataInput(data);
+ DataInput dataInput = new DataInputByteArray(data);
assertEquals(0, dataInput.readUnsignedByte());
assertEquals(255, dataInput.readUnsignedByte());
dataInput.setPosition(6);
@@ -74,7 +74,7 @@ class DataInputTest
void testBasics() throws IOException
{
byte[] data = new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9 };
- DataInput dataInput = new DataInput(data);
+ DataInput dataInput = new DataInputByteArray(data);
assertEquals(10, dataInput.length());
assertTrue(dataInput.hasRemaining());
assertThrows(IOException.class, () -> dataInput.setPosition(-1));
@@ -85,7 +85,7 @@ class DataInputTest
void testPeek() throws IOException
{
byte[] data = new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9 };
- DataInput dataInput = new DataInput(data);
+ DataInput dataInput = new DataInputByteArray(data);
assertEquals(0, dataInput.peekUnsignedByte(0));
assertEquals(251, dataInput.peekUnsignedByte(5));
assertThrows(IOException.class, () -> dataInput.peekUnsignedByte(-1));
@@ -96,7 +96,7 @@ class DataInputTest
void testReadShort() throws IOException
{
byte[] data = new byte[] { 0x00, 0x0F, (byte) 0xAA, 0, (byte) 0xFE, (byte) 0xFF };
- DataInput dataInput = new DataInput(data);
+ DataInput dataInput = new DataInputByteArray(data);
assertEquals((short) 0x000F, dataInput.readShort());
assertEquals((short) 0xAA00, dataInput.readShort());
assertEquals((short) 0xFEFF, dataInput.readShort());
@@ -107,14 +107,14 @@ class DataInputTest
void testReadUnsignedShort() throws IOException
{
byte[] data = new byte[] { 0x00, 0x0F, (byte) 0xAA, 0, (byte) 0xFE, (byte) 0xFF };
- DataInput dataInput = new DataInput(data);
+ DataInput dataInput = new DataInputByteArray(data);
assertEquals(0x000F, dataInput.readUnsignedShort());
assertEquals(0xAA00, dataInput.readUnsignedShort());
assertEquals(0xFEFF, dataInput.readUnsignedShort());
assertThrows(IOException.class, () -> dataInput.readUnsignedShort());
byte[] data2 = new byte[] { 0x00 };
- DataInput dataInput2 = new DataInput(data2);
+ DataInput dataInput2 = new DataInputByteArray(data2);
assertThrows(IOException.class, () -> dataInput2.readUnsignedShort());
}
@@ -123,13 +123,13 @@ class DataInputTest
{
byte[] data = new byte[] { 0x00, 0x0F, (byte) 0xAA, 0, (byte) 0xFE, (byte) 0xFF, 0x30,
0x50 };
- DataInput dataInput = new DataInput(data);
+ DataInput dataInput = new DataInputByteArray(data);
assertEquals(0x000FAA00, dataInput.readInt());
assertEquals(0xFEFF3050, dataInput.readInt());
assertThrows(IOException.class, () -> dataInput.readInt());
byte[] data2 = new byte[] { 0x00, 0x0F, (byte) 0xAA };
- DataInput dataInput2 = new DataInput(data2);
+ DataInput dataInput2 = new DataInputByteArray(data2);
assertThrows(IOException.class, () -> dataInput2.readInt());
}
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java?rev=1900888&r1=1900887&r2=1900888&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java Sat May 14 16:21:06 2022
@@ -33,6 +33,7 @@ import org.apache.fontbox.cff.CFFType1Fo
import org.apache.fontbox.cff.Type2CharString;
import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.io.RandomAccessRead;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.util.Matrix;
@@ -73,30 +74,33 @@ public class PDCIDFontType0 extends PDCI
super(fontDictionary, parent);
PDFontDescriptor fd = getFontDescriptor();
- byte[] bytes = null;
+ RandomAccessRead randomAccessRead = null;
if (fd != null)
{
PDStream ff3Stream = fd.getFontFile3();
if (ff3Stream != null)
{
- bytes = ff3Stream.toByteArray();
+ randomAccessRead = ff3Stream.getCOSObject().createView();
}
}
boolean fontIsDamaged = false;
CFFFont cffFont = null;
- if (bytes != null && bytes.length > 0 && (bytes[0] & 0xff) == '%')
+ if (randomAccessRead != null && randomAccessRead.length() > 0
+ && randomAccessRead.peek() == '%')
{
// PDFBOX-2642 contains a corrupt PFB font instead of a CFF
LOG.warn("Found PFB but expected embedded CFF font " + fd.getFontName());
fontIsDamaged = true;
+ randomAccessRead.close();
}
- else if (bytes != null)
+ else if (randomAccessRead != null)
{
CFFParser cffParser = new CFFParser();
try
{
- cffFont = cffParser.parse(bytes, new FF3ByteSource()).get(0);
+ cffFont = cffParser.parse(randomAccessRead).get(0);
+ randomAccessRead.close();
}
catch (IOException e)
{
@@ -470,12 +474,4 @@ public class PDCIDFontType0 extends PDCI
return 500;
}
- private class FF3ByteSource implements CFFParser.ByteSource
- {
- @Override
- public byte[] getBytes() throws IOException
- {
- return getFontDescriptor().getFontFile3().toByteArray();
- }
- }
}
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java?rev=1900888&r1=1900887&r2=1900888&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java Sat May 14 16:21:06 2022
@@ -35,6 +35,7 @@ import org.apache.fontbox.cff.CFFType1Fo
import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.io.RandomAccessRead;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.font.encoding.Encoding;
@@ -76,17 +77,18 @@ public class PDType1CFont extends PDSimp
super(fontDictionary);
PDFontDescriptor fd = getFontDescriptor();
- byte[] bytes = null;
+ RandomAccessRead randomAccessRead = null;
if (fd != null)
{
PDStream ff3Stream = fd.getFontFile3();
if (ff3Stream != null)
{
- bytes = ff3Stream.toByteArray();
- if (bytes.length == 0)
+ randomAccessRead = fd.getFontFile3().getCOSObject().createView();
+ if (randomAccessRead.length() == 0)
{
LOG.error("Invalid data for embedded Type1C font " + getName());
- bytes = null;
+ randomAccessRead.close();
+ randomAccessRead = null;
}
}
}
@@ -95,11 +97,11 @@ public class PDType1CFont extends PDSimp
CFFType1Font cffEmbedded = null;
try
{
- if (bytes != null)
+ if (randomAccessRead != null)
{
// note: this could be an OpenType file, fortunately CFFParser can handle that
CFFParser cffParser = new CFFParser();
- CFFFont parsedCffFont = cffParser.parse(bytes, new FF3ByteSource()).get(0);
+ CFFFont parsedCffFont = cffParser.parse(randomAccessRead).get(0);
if (parsedCffFont instanceof CFFType1Font)
{
cffEmbedded = (CFFType1Font) parsedCffFont;
@@ -109,6 +111,7 @@ public class PDType1CFont extends PDSimp
LOG.error("Expected CFFType1Font, got " + parsedCffFont.getClass().getSimpleName());
fontIsDamaged = true;
}
+ randomAccessRead.close();
}
}
catch (IOException e)
@@ -482,12 +485,4 @@ public class PDType1CFont extends PDSimp
return ".notdef";
}
- private class FF3ByteSource implements CFFParser.ByteSource
- {
- @Override
- public byte[] getBytes() throws IOException
- {
- return getFontDescriptor().getFontFile3().toByteArray();
- }
- }
}