Skip to content

Commit

Permalink
-使用探查器分析内容流遇到异常内容将导致程序崩溃的问题(#241
Browse files Browse the repository at this point in the history
  • Loading branch information
wmjordan committed Oct 18, 2024
1 parent 5aa4f77 commit 7c3f48b
Show file tree
Hide file tree
Showing 9 changed files with 350 additions and 282 deletions.
2 changes: 1 addition & 1 deletion App/Functions/DocumentInspectorControl.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions App/Functions/DocumentInspectorControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void OnLoad() {
d.ImageKey = ic;
}
else {
d.ImageKey = __OpNameIcons["Null"];
d.ImageKey = __OpNameIcons["?"];
}
}
return d.ImageKey;
Expand Down Expand Up @@ -445,7 +445,8 @@ Dictionary<string, int> InitOpNameIcons() {
"Do",
"W*", "W", "c", "v", "y", "l", "re",
"m", "h", "n", "w", "J", "j", "M", "d", "i",
"pdf:number", "pdf:string", "pdf:name", "pdf:dictionary", "pdf:array", "pdf:boolean" };
"pdf:number", "pdf:string", "pdf:name", "pdf:dictionary", "pdf:array", "pdf:boolean",
"?" };
var ico = new string[] {
"op_q", "op_tm", "op_cm", "op_gs", "op_gs", "op_gs", "op_gs",
"op_sc", "op_sc", "op_sc", "op_sc", "op_sc", "op_sc", "op_sc", "op_sc",
Expand All @@ -458,7 +459,8 @@ Dictionary<string, int> InitOpNameIcons() {
"Resources",
"op_W*", "op_W*", "op_c", "op_c", "op_c", "op_l", "op_re",
"op_m", "op_h", "op_h", "op_w", "op_l", "op_l", "op_M_", "op_d", "op_gs",
"Number", "String", "Name", "Dictionary", "Array", "Bool" };
"Number", "String", "Name", "Dictionary", "Array", "Bool",
"Error" };
var d = new Dictionary<string, int>(n.Length + p.Length);
foreach (var i in p) {
d.Add(i, _ObjectTypeIcons.Images.IndexOfKey(i));
Expand Down
497 changes: 252 additions & 245 deletions App/Functions/DocumentInspectorControl.resx

Large diffs are not rendered by default.

16 changes: 15 additions & 1 deletion App/Model/DocumentObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,9 @@ private void PopulateChildrenForSpecialObject() {
foreach (var item in cp.Commands) {
PopulatePageCommand(item);
}
if (cp.LastError != null) {
Description = cp.LastError;
}
break;
}
case PdfObjectType.PageCommand:
Expand Down Expand Up @@ -409,7 +412,7 @@ private void PopulatePageCommand(PdfPageCommand item) {
fn = "未知操作符";
}
var o = new DocumentObject(OwnerDocument, this, fn, null, PdfObjectType.PageCommand) {
FriendlyName = $"{fn}({op})",
FriendlyName = fn + "(" + op + ")",
ExtensiveObject = op
};
if (item.Type == PdfPageCommandType.Text) {
Expand Down Expand Up @@ -464,6 +467,17 @@ private void PopulatePageCommand(PdfPageCommand item) {
o._Children.Add(new DocumentObject(OwnerDocument, o, PdfHelper.DecodeKeyName(ii.Key), ii.Value));
}
}
else if (item.Type == PdfPageCommandType.Invalid) {
o.Description = ((InvalidCommand)item).Error;
o.ExtensiveObject = "?";
if (item.Operands.HasContent()) {
var i = 0;
CreateChildrenList(ref o._Children);
foreach (var t in item.Operands) {
o._Children.Add(new DocumentObject(OwnerDocument, o, (++i).ToText(), t));
}
}
}
else {
o.FriendlyValue = item.GetOperandsText();
}
Expand Down
10 changes: 10 additions & 0 deletions App/Model/PdfModelHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ internal static T Locate<T>(this PdfArray source, bool resolveRef, int index) wh
internal static T CastAs<T>(this PdfIndirectReference pdfRef) where T : PdfObject {
return PdfReader.GetPdfObject(pdfRef) as T;
}
internal static float ValueAsFloat(this PdfObject obj) {
return obj is PdfNumber n
? n.FloatValue
: 0;
}
internal static float ValueAsInt(this PdfObject obj) {
return obj is PdfNumber n
? n.IntValue
: 0;
}

internal static bool ValueIs(this PdfNumber obj, double value) {
return obj != null && obj.DoubleValue == value;
Expand Down
14 changes: 13 additions & 1 deletion App/Model/PdfPageCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ enum PdfPageCommandType
Enclosure,
Matrix,
Font,
InlineImage
InlineImage,
Invalid
}
interface IPdfPageCommandContainer
{
Expand Down Expand Up @@ -325,4 +326,15 @@ internal override void WriteToPdf(Stream target) {
WriteOperator(__EI, target);
}
}

sealed class InvalidCommand(PdfLiteral oper, List<PdfObject> operands) : PdfPageCommand(oper, operands)
{
public override PdfPageCommandType Type => PdfPageCommandType.Invalid;
public override bool HasOutput => false;
public string Error { get; set; }

internal override void WriteToPdf(Stream target) {
// do nothing
}
}
}
54 changes: 31 additions & 23 deletions App/Processor/PdfContentStreamParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,22 @@ public void ProcessContent(byte[] contentBytes, PdfDictionary resources) {
var ps = new PdfContentParser(tokenizer);
var operands = new List<PdfObject>();
while (ps.Parse(operands).Count > 0) {
var oper = (PdfLiteral)operands[operands.Count - 1];
if ("BI".Equals(oper.ToString())) {
var oper = operands[operands.Count - 1] as PdfLiteral;
if (oper is null) {
break;
}
if ("BI".Equals(oper)) {
var img = InlineImageUtils.ParseInlineImage(ps, resources.GetAsDict(PdfName.COLORSPACE));
InvokeOperator(oper, new List<PdfObject> { img, oper });
// this.renderListener.RenderImage (renderInfo);
}
else {
InvokeOperator(oper, operands);
try {
InvokeOperator(oper, operands);
}
catch (Exception) {
continue;
}
}
}
tokenizer.Close();
Expand Down Expand Up @@ -273,18 +281,18 @@ public void HandleXObject(PdfContentStreamProcessor processor, PdfStream stream,
var resources = stream.GetAsDict(PdfName.RESOURCES);
var contentBytes = ContentByteUtils.GetContentBytesFromContentObject(stream);
var matrix = stream.GetAsArray(PdfName.MATRIX);
new PdfContentStreamProcessor.PushGraphicsState().Invoke(processor, null, null);
new PushGraphicsState().Invoke(processor, null, null);
if (matrix != null) {
float a = matrix.GetAsNumber(0).FloatValue;
float b = matrix.GetAsNumber(1).FloatValue;
float c = matrix.GetAsNumber(2).FloatValue;
float d = matrix.GetAsNumber(3).FloatValue;
float e = matrix.GetAsNumber(4).FloatValue;
float f = matrix.GetAsNumber(5).FloatValue;
float a = matrix[0].ValueAsFloat();
float b = matrix[1].ValueAsFloat();
float c = matrix[2].ValueAsFloat();
float d = matrix[3].ValueAsFloat();
float e = matrix[4].ValueAsFloat();
float f = matrix[5].ValueAsFloat();
processor.CurrentGraphicState.TransMatrix = new Matrix(a, b, c, d, e, f).Multiply(processor.CurrentGraphicState.TransMatrix);
}
processor.ProcessContent(contentBytes, resources);
new PdfContentStreamProcessor.PopGraphicsState().Invoke(processor, null, null);
new PopGraphicsState().Invoke(processor, null, null);
}
}

Expand Down Expand Up @@ -315,12 +323,12 @@ protected sealed class ModifyCurrentTransformationMatrix : IContentOperator
{
public bool HasOutput => false;
public void Invoke(PdfContentStreamProcessor processor, PdfLiteral oper, List<PdfObject> operands) {
float a = ((PdfNumber)operands[0]).FloatValue;
float b = ((PdfNumber)operands[1]).FloatValue;
float c = ((PdfNumber)operands[2]).FloatValue;
float d = ((PdfNumber)operands[3]).FloatValue;
float e = ((PdfNumber)operands[4]).FloatValue;
float f = ((PdfNumber)operands[5]).FloatValue;
float a = operands[0].ValueAsFloat();
float b = operands[1].ValueAsFloat();
float c = operands[2].ValueAsFloat();
float d = operands[3].ValueAsFloat();
float e = operands[4].ValueAsFloat();
float f = operands[5].ValueAsFloat();
var gs = processor.gsStack.Peek();
gs.TransMatrix = new Matrix(a, b, c, d, e, f).Multiply(gs.TransMatrix);
}
Expand Down Expand Up @@ -608,12 +616,12 @@ protected sealed class TextSetTextMatrix : IContentOperator
{
public bool HasOutput => false;
public void Invoke(PdfContentStreamProcessor processor, PdfLiteral oper, List<PdfObject> operands) {
float a = ((PdfNumber)operands[0]).FloatValue;
float b = ((PdfNumber)operands[1]).FloatValue;
float c = ((PdfNumber)operands[2]).FloatValue;
float d = ((PdfNumber)operands[3]).FloatValue;
float e = ((PdfNumber)operands[4]).FloatValue;
float f = ((PdfNumber)operands[5]).FloatValue;
float a = operands[0].ValueAsFloat();
float b = operands[1].ValueAsFloat();
float c = operands[2].ValueAsFloat();
float d = operands[3].ValueAsFloat();
float e = operands[4].ValueAsFloat();
float f = operands[5].ValueAsFloat();
processor._TextLineMatrix = new Matrix(a, b, c, d, e, f);
processor._TextMatrix = processor._TextLineMatrix;
}
Expand Down
29 changes: 21 additions & 8 deletions App/Processor/PdfPageCommandProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@ namespace PDFPatcher.Processor
{
sealed class PdfPageCommandProcessor : PdfContentStreamProcessor, IPdfPageCommandContainer
{
readonly Stack<EnclosingCommand> _commandStack = new Stack<EnclosingCommand>();
EnclosingCommand _currentCommand;
float _textWidth;

public bool HasCommand => Commands.Count > 0;
/// <summary>
/// 分析内容后得到的 PDF 命令操作符及操作数列表。
/// </summary>
public IList<PdfPageCommand> Commands { get; }
readonly Stack<EnclosingCommand> _commandStack;
EnclosingCommand _currentCommand;
float _textWidth;
public IList<PdfPageCommand> Commands { get; } = new List<PdfPageCommand>();
public string LastError { get; private set; }

public PdfPageCommandProcessor() {
PopulateOperators();
RegisterContentOperator("TJ", new AccumulatedShowTextArray());
Commands = new List<PdfPageCommand>();
_commandStack = new Stack<EnclosingCommand>();
}

public PdfPageCommandProcessor(PRStream form)
Expand All @@ -48,8 +47,20 @@ protected override void DisplayPdfString(PdfString str) {
}

protected override void InvokeOperator(PdfLiteral oper, List<PdfObject> operands) {
base.InvokeOperator(oper, operands);
PdfPageCommand cmd;
try {
base.InvokeOperator(oper, operands);
}
catch (Exception ex) {
cmd = new InvalidCommand(oper, operands) {
Error = LastError = oper + " " + (ex is IndexOutOfRangeException ? "指令参数不足"
: ex is ArgumentOutOfRangeException ? "指令参数不足"
: ex is InvalidCastException ? "指令参数类型不匹配"
: ex.Message)
};
goto ADD_COMMAND;
}

switch (oper.ToString()) {
case "TJ":
cmd = new PaceAndTextCommand(oper, operands, GetTextInfo(new PdfString()), CurrentGraphicState.Font);
Expand Down Expand Up @@ -97,6 +108,8 @@ protected override void InvokeOperator(PdfLiteral oper, List<PdfObject> operands
}
else {
_currentCommand = null;
cmd = new InvalidCommand(oper, operands) { Error = "嵌套指令不配对" };
goto ADD_COMMAND;
}
return;
case "BI":
Expand All @@ -106,7 +119,7 @@ protected override void InvokeOperator(PdfLiteral oper, List<PdfObject> operands
cmd = new AdjustCommand(oper, operands);
break;
}

ADD_COMMAND:
if (_currentCommand != null) {
_currentCommand.Commands.Add(cmd);
}
Expand Down
2 changes: 2 additions & 0 deletions 更新历史.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
1.1.0.4544 2024年10月7日
修改功能:
新的 MuPDF 库。
修复问题:
使用探查器分析内容流遇到异常内容将导致程序崩溃。

1.0.4.4512 2024年9月30日
新增功能:
Expand Down

0 comments on commit 7c3f48b

Please sign in to comment.