Skip to content

Commit

Permalink
Galk.interpreters.limits implementation (#247)
Browse files Browse the repository at this point in the history
* securing type 2 interpreter

* type 1 interpretation corrections and revisiting earlier type 2 corrections
  • Loading branch information
galkahana authored Jan 6, 2024
1 parent 555258e commit b2ddf3f
Show file tree
Hide file tree
Showing 13 changed files with 838 additions and 564 deletions.
233 changes: 140 additions & 93 deletions PDFWriter/CharStringType1Interpreter.cpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions PDFWriter/CharStringType1Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class CharStringType1Interpreter
IType1InterpreterImplementation* mImplementationHelper;
bool mGotEndChar;
LongList mPostScriptOperandStack;
unsigned short mSubrsNesting;

PDFHummus::EStatusCode ProcessCharString(InputCharStringDecodeStream* inCharStringToIntepret);
bool IsOperator(Byte inBuffer);
Expand Down
3 changes: 1 addition & 2 deletions PDFWriter/CharStringType1Tracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ CharStringType1Tracer::~CharStringType1Tracer(void)
{
}

/*
EStatusCode CharStringType1Tracer::TraceGlyphProgram(Byte inGlyphIndex, Type1Input* inType1Input, IByteWriter* inWriter)
{
CharStringType1Interpreter interpreter;
Expand All @@ -51,7 +50,7 @@ EStatusCode CharStringType1Tracer::TraceGlyphProgram(Byte inGlyphIndex, Type1Inp
}

return interpreter.Intepret(*charString,this);
}*/
}

EStatusCode CharStringType1Tracer::TraceGlyphProgram(const std::string& inGlyphName, Type1Input* inType1Input, IByteWriter* inWriter)
{
Expand Down
103 changes: 54 additions & 49 deletions PDFWriter/CharStringType2Flattener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ EStatusCode CharStringType2Flattener::WriteFlattenedGlyphProgram(unsigned short

do
{
if(status != PDFHummus::eSuccess)
if(status != eSuccess)
{
TRACE_LOG("CharStringType2Flattener::Trace, Exception, cannot prepare for glyph interpretation");
break;
Expand Down Expand Up @@ -91,7 +91,7 @@ EStatusCode CharStringType2Flattener::ReadCharString(LongFilePositionType inChar
EStatusCode CharStringType2Flattener::Type2InterpretNumber(const CharStringOperand& inOperand)
{
mOperandsToWrite.push_back(inOperand);
return PDFHummus::eSuccess;
return eSuccess;
}

EStatusCode CharStringType2Flattener::Type2Hstem(const CharStringOperandList& inOperandList)
Expand All @@ -104,11 +104,11 @@ EStatusCode CharStringType2Flattener::Type2Hstem(const CharStringOperandList& in
EStatusCode CharStringType2Flattener::WriteRegularOperator(unsigned short inOperatorCode)
{
CharStringOperandList::iterator it = mOperandsToWrite.begin();
EStatusCode status = PDFHummus::eSuccess;
EStatusCode status = eSuccess;

for(; it != mOperandsToWrite.end() && PDFHummus::eSuccess == status;++it)
for(; it != mOperandsToWrite.end() && eSuccess == status;++it)
status = WriteCharStringOperand(*it);
if(status != PDFHummus::eFailure)
if(status != eFailure)
status = WriteCharStringOperator(inOperatorCode);

mOperandsToWrite.clear();
Expand All @@ -134,11 +134,11 @@ EStatusCode CharStringType2Flattener::WriteCharStringOperand(const CharStringOpe
byte0 = ((value >> 8) & 0xff) + 247;
byte1 = value & 0xff;

if(WriteByte(byte0) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(byte0) != eSuccess)
return eFailure;

if(WriteByte(byte1) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(byte1) != eSuccess)
return eFailure;
}
else if(-1131 <= value && value <= -108)
{
Expand All @@ -149,11 +149,11 @@ EStatusCode CharStringType2Flattener::WriteCharStringOperand(const CharStringOpe
byte0 = ((value >> 8) & 0xff) + 251;
byte1 = value & 0xff;

if(WriteByte(byte0) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(byte0) != eSuccess)
return eFailure;

if(WriteByte(byte1) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(byte1) != eSuccess)
return eFailure;
}
else if(-32768 <= value && value<= 32767)
{
Expand All @@ -162,17 +162,17 @@ EStatusCode CharStringType2Flattener::WriteCharStringOperand(const CharStringOpe
byte1 = (value >> 8) & 0xff;
byte2 = value & 0xff;

if(WriteByte(28) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(28) != eSuccess)
return eFailure;

if(WriteByte(byte1) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(byte1) != eSuccess)
return eFailure;

if(WriteByte(byte2) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(byte2) != eSuccess)
return eFailure;
}
else
return PDFHummus::eFailure;
return eFailure;
}
else
{
Expand All @@ -185,35 +185,35 @@ EStatusCode CharStringType2Flattener::WriteCharStringOperand(const CharStringOpe
if(sign)
integerPart = -integerPart;

if(WriteByte(Byte(0xff)) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(Byte((integerPart>>8) & 0xff)) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(Byte(integerPart & 0xff)) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(Byte(0xff)) != eSuccess)
return eFailure;
if(WriteByte(Byte((integerPart>>8) & 0xff)) != eSuccess)
return eFailure;
if(WriteByte(Byte(integerPart & 0xff)) != eSuccess)
return eFailure;

if(WriteByte(Byte((realPart>>8) & 0xff)) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(Byte(realPart & 0xff)) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(Byte((realPart>>8) & 0xff)) != eSuccess)
return eFailure;
if(WriteByte(Byte(realPart & 0xff)) != eSuccess)
return eFailure;

}
return PDFHummus::eSuccess;
return eSuccess;
}

EStatusCode CharStringType2Flattener::WriteCharStringOperator(unsigned short inOperatorCode)
{
if((inOperatorCode & 0xff00) == 0x0c00)
{
if(WriteByte(0x0c) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteByte(0x0c) != eSuccess)
return eFailure;
}
return WriteByte(Byte(inOperatorCode & 0xff));
}

EStatusCode CharStringType2Flattener::WriteByte(Byte inValue)
{
return (mWriter->Write(&inValue,1) == 1 ? PDFHummus::eSuccess : PDFHummus::eFailure);
return (mWriter->Write(&inValue,1) == 1 ? eSuccess : eFailure);
}

EStatusCode CharStringType2Flattener::Type2Vstem(const CharStringOperandList& inOperandList)
Expand Down Expand Up @@ -251,7 +251,7 @@ EStatusCode CharStringType2Flattener::Type2RRCurveto(const CharStringOperandList
EStatusCode CharStringType2Flattener::Type2Return(const CharStringOperandList& inOperandList)
{
// ignore returns
return PDFHummus::eSuccess;
return eSuccess;
}

EStatusCode CharStringType2Flattener::Type2Endchar(const CharStringOperandList& inOperandList)
Expand All @@ -266,31 +266,36 @@ EStatusCode CharStringType2Flattener::Type2Hstemhm(const CharStringOperandList&
return WriteRegularOperator(18);
}

EStatusCode CharStringType2Flattener::Type2Hintmask(const CharStringOperandList& inOperandList,Byte* inProgramCounter)
EStatusCode CharStringType2Flattener::Type2Hintmask(const CharStringOperandList& inOperandList,Byte* inProgramCounter,LongFilePositionType inReadLimit)
{
mStemsCount+= (unsigned short)(inOperandList.size() / 2);

if(WriteRegularOperator(19) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteRegularOperator(19) != eSuccess)
return eFailure;

return WriteStemMask(inProgramCounter);
return WriteStemMask(inProgramCounter, inReadLimit);
}

EStatusCode CharStringType2Flattener::WriteStemMask(Byte* inProgramCounter)
EStatusCode CharStringType2Flattener::WriteStemMask(Byte* inProgramCounter,LongFilePositionType inReadLimit)
{
unsigned short maskSize = mStemsCount/8 + (mStemsCount % 8 != 0 ? 1:0);

return mWriter->Write(inProgramCounter,maskSize) != maskSize ? PDFHummus::eFailure : PDFHummus::eSuccess;
if(maskSize > inReadLimit) {
TRACE_LOG2("CharStringType2Flattener::WriteStemMask, stem mask size is %d but can only read %ld, aborting", maskSize, inReadLimit);
return eFailure;
}

return mWriter->Write(inProgramCounter,maskSize) != maskSize ? eFailure : eSuccess;
}

EStatusCode CharStringType2Flattener::Type2Cntrmask(const CharStringOperandList& inOperandList,Byte* inProgramCounter)
EStatusCode CharStringType2Flattener::Type2Cntrmask(const CharStringOperandList& inOperandList,Byte* inProgramCounter,LongFilePositionType inReadLimit)
{
mStemsCount+= (unsigned short)(inOperandList.size() / 2);

if(WriteRegularOperator(20) != PDFHummus::eSuccess)
return PDFHummus::eFailure;
if(WriteRegularOperator(20) != eSuccess)
return eFailure;

return WriteStemMask(inProgramCounter);
return WriteStemMask(inProgramCounter, inReadLimit);
}

EStatusCode CharStringType2Flattener::Type2Rmoveto(const CharStringOperandList& inOperandList)
Expand Down Expand Up @@ -462,7 +467,7 @@ EStatusCode CharStringType2Flattener::Type2Roll(const CharStringOperandList& inO

CharString* CharStringType2Flattener::GetLocalSubr(long inSubrIndex)
{
if(WriteSubrOperator(10) != PDFHummus::eSuccess)
if(WriteSubrOperator(10) != eSuccess)
return NULL;

return mHelper->GetLocalSubr(inSubrIndex);
Expand All @@ -472,13 +477,13 @@ EStatusCode CharStringType2Flattener::WriteSubrOperator(unsigned short inOperato
{
if(mOperandsToWrite.size() > 0)
{
EStatusCode status = PDFHummus::eSuccess;
EStatusCode status = eSuccess;
mOperandsToWrite.pop_back(); // pop back parameter, which is the subr index

// now continue writing all operands
CharStringOperandList::iterator it = mOperandsToWrite.begin();

for(; it != mOperandsToWrite.end() && PDFHummus::eSuccess == status;++it)
for(; it != mOperandsToWrite.end() && eSuccess == status;++it)
status = WriteCharStringOperand(*it);

mOperandsToWrite.clear();
Expand All @@ -491,7 +496,7 @@ EStatusCode CharStringType2Flattener::WriteSubrOperator(unsigned short inOperato

CharString* CharStringType2Flattener::GetGlobalSubr(long inSubrIndex)
{
if(WriteSubrOperator(29) != PDFHummus::eSuccess)
if(WriteSubrOperator(29) != eSuccess)
return NULL;

return mHelper->GetGlobalSubr(inSubrIndex);
Expand Down
6 changes: 3 additions & 3 deletions PDFWriter/CharStringType2Flattener.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ class CharStringType2Flattener : public IType2InterpreterImplementation
virtual PDFHummus::EStatusCode Type2Return(const CharStringOperandList& inOperandList) ;
virtual PDFHummus::EStatusCode Type2Endchar(const CharStringOperandList& inOperandList);
virtual PDFHummus::EStatusCode Type2Hstemhm(const CharStringOperandList& inOperandList);
virtual PDFHummus::EStatusCode Type2Hintmask(const CharStringOperandList& inOperandList,Byte* inProgramCounter);
virtual PDFHummus::EStatusCode Type2Cntrmask(const CharStringOperandList& inOperandList,Byte* inProgramCounter);
virtual PDFHummus::EStatusCode Type2Hintmask(const CharStringOperandList& inOperandList,Byte* inProgramCounter,LongFilePositionType inReadLimit);
virtual PDFHummus::EStatusCode Type2Cntrmask(const CharStringOperandList& inOperandList,Byte* inProgramCounter,LongFilePositionType inReadLimit);
virtual PDFHummus::EStatusCode Type2Rmoveto(const CharStringOperandList& inOperandList);
virtual PDFHummus::EStatusCode Type2Hmoveto(const CharStringOperandList& inOperandList);
virtual PDFHummus::EStatusCode Type2Vstemhm(const CharStringOperandList& inOperandList);
Expand Down Expand Up @@ -96,7 +96,7 @@ class CharStringType2Flattener : public IType2InterpreterImplementation
CharStringOperandList mOperandsToWrite;

PDFHummus::EStatusCode WriteRegularOperator(unsigned short inOperatorCode);
PDFHummus::EStatusCode WriteStemMask(Byte* inProgramCounter);
PDFHummus::EStatusCode WriteStemMask(Byte* inProgramCounter,LongFilePositionType inReadLimit);
PDFHummus::EStatusCode WriteCharStringOperand(const CharStringOperand& inOperand);
PDFHummus::EStatusCode WriteCharStringOperator(unsigned short inOperatorCode);
PDFHummus::EStatusCode WriteByte(Byte inValue);
Expand Down
Loading

0 comments on commit b2ddf3f

Please sign in to comment.