treat encryption entries as optional for revisions 5+ #34

the revision 5 and 6 encryption algorithms specify the presence of additional encryption material named 'oe' and 'ue'. it turns out this is not always required so will now default to null if not present. this also adds support for those values being in hex rather than normal string format.

tidies up some commenting on the xynode class, moves public methods below constructors and adds xy to the resharper list of abbreviations for the solution.
This commit is contained in:
Eliot Jones
2019-06-23 13:52:12 +01:00
parent ff9e2ad83f
commit f86c2545bd
4 changed files with 73 additions and 29 deletions

View File

@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XY/@EntryIndexedValue">XY</s:String></wpf:ResourceDictionary>

View File

@@ -25,29 +25,6 @@ namespace UglyToad.PdfPig.DocumentLayoutAnalysis
/// </summary> /// </summary>
public XYNode[] Children { get; set; } public XYNode[] Children { get; set; }
/// <summary>
/// Recursively counts the words included in this node.
/// </summary>
public virtual int CountWords()
{
if (Children == null) return 0;
int count = 0;
RecursiveCount(Children, ref count);
return count;
}
/// <summary>
/// Recursively gets the leafs (last nodes) of this node.
/// </summary>
public virtual List<XYLeaf> GetLeafs()
{
List<XYLeaf> leafs = new List<XYLeaf>();
if (Children == null || Children.Count() == 0) return leafs;
int level = 0;
RecursiveGetLeafs(Children, ref leafs, level);
return leafs;
}
/// <summary> /// <summary>
/// Create a new <see cref="XYNode"/>. /// Create a new <see cref="XYNode"/>.
/// </summary> /// </summary>
@@ -79,6 +56,37 @@ namespace UglyToad.PdfPig.DocumentLayoutAnalysis
} }
} }
/// <summary>
/// Recursively counts the words included in this node.
/// </summary>
public virtual int CountWords()
{
if (Children == null)
{
return 0;
}
int count = 0;
RecursiveCount(Children, ref count);
return count;
}
/// <summary>
/// Recursively gets the leafs (last nodes) of this node.
/// </summary>
public virtual List<XYLeaf> GetLeafs()
{
List<XYLeaf> leafs = new List<XYLeaf>();
if (Children == null || Children.Length == 0)
{
return leafs;
}
int level = 0;
RecursiveGetLeafs(Children, ref leafs, level);
return leafs;
}
private void RecursiveCount(IEnumerable<XYNode> children, ref int count) private void RecursiveCount(IEnumerable<XYNode> children, ref int count)
{ {
if (children.Count() == 0) return; if (children.Count() == 0) return;
@@ -122,9 +130,10 @@ namespace UglyToad.PdfPig.DocumentLayoutAnalysis
} }
} }
/// <inheritdoc />
public override string ToString() public override string ToString()
{ {
return (IsLeaf ? "Leaf" : "Node"); return IsLeaf ? "Leaf" : "Node";
} }
} }
} }

View File

@@ -73,11 +73,8 @@
byte[] userEncryptionBytes = null, ownerEncryptionBytes = null; byte[] userEncryptionBytes = null, ownerEncryptionBytes = null;
if (revision >= 5) if (revision >= 5)
{ {
var oe = encryptionDictionary.Get<StringToken>(NameToken.Oe, tokenScanner); ownerEncryptionBytes = GetEncryptionBytesOrDefault(encryptionDictionary, tokenScanner, false);
var ue = encryptionDictionary.Get<StringToken>(NameToken.Ue, tokenScanner); userEncryptionBytes = GetEncryptionBytesOrDefault(encryptionDictionary, tokenScanner, true);
ownerEncryptionBytes = OtherEncodings.StringAsLatin1Bytes(oe.Data);
userEncryptionBytes = OtherEncodings.StringAsLatin1Bytes(ue.Data);
} }
encryptionDictionary.TryGetOptionalTokenDirect(NameToken.EncryptMetaData, tokenScanner, out BooleanToken encryptMetadata); encryptionDictionary.TryGetOptionalTokenDirect(NameToken.EncryptMetaData, tokenScanner, out BooleanToken encryptMetadata);
@@ -89,5 +86,21 @@
encryptionDictionary, encryptionDictionary,
encryptMetadata?.Data ?? true); encryptMetadata?.Data ?? true);
} }
private static byte[] GetEncryptionBytesOrDefault(DictionaryToken encryptionDictionary, IPdfTokenScanner tokenScanner, bool isUser)
{
var name = isUser ? NameToken.Ue : NameToken.Oe;
if (encryptionDictionary.TryGet(name, tokenScanner, out StringToken stringToken))
{
return OtherEncodings.StringAsLatin1Bytes(stringToken.Data);
}
if (encryptionDictionary.TryGet(name, tokenScanner, out HexToken hexToken))
{
return hexToken.Bytes.ToArray();
}
return null;
}
} }
} }

View File

@@ -77,6 +77,26 @@
return Data.TryGetValue(name.Data, out token); return Data.TryGetValue(name.Data, out token);
} }
/// <summary>
/// Try and get the entry with a given name and type or look-up the object if it's an indirect reference.
/// </summary>
internal bool TryGet<T>(NameToken name, IPdfTokenScanner tokenScanner, out T token) where T : IToken
{
token = default(T);
if (!TryGet(name, out var t) || !(t is T typedToken))
{
if (t is IndirectReferenceToken reference)
{
return DirectObjectFinder.TryGet(reference, tokenScanner, out token);
}
return false;
}
token = typedToken;
return true;
}
/// <summary> /// <summary>
/// Try and get the entry with a given name and a specific data type. /// Try and get the entry with a given name and a specific data type.
/// </summary> /// </summary>