mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-09-20 20:07:57 +08:00
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:
2
src/UglyToad.PdfPig.sln.DotSettings
Normal file
2
src/UglyToad.PdfPig.sln.DotSettings
Normal 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>
|
@@ -25,29 +25,6 @@ namespace UglyToad.PdfPig.DocumentLayoutAnalysis
|
||||
/// </summary>
|
||||
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>
|
||||
/// Create a new <see cref="XYNode"/>.
|
||||
/// </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)
|
||||
{
|
||||
if (children.Count() == 0) return;
|
||||
@@ -122,9 +130,10 @@ namespace UglyToad.PdfPig.DocumentLayoutAnalysis
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return (IsLeaf ? "Leaf" : "Node");
|
||||
return IsLeaf ? "Leaf" : "Node";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -73,11 +73,8 @@
|
||||
byte[] userEncryptionBytes = null, ownerEncryptionBytes = null;
|
||||
if (revision >= 5)
|
||||
{
|
||||
var oe = encryptionDictionary.Get<StringToken>(NameToken.Oe, tokenScanner);
|
||||
var ue = encryptionDictionary.Get<StringToken>(NameToken.Ue, tokenScanner);
|
||||
|
||||
ownerEncryptionBytes = OtherEncodings.StringAsLatin1Bytes(oe.Data);
|
||||
userEncryptionBytes = OtherEncodings.StringAsLatin1Bytes(ue.Data);
|
||||
ownerEncryptionBytes = GetEncryptionBytesOrDefault(encryptionDictionary, tokenScanner, false);
|
||||
userEncryptionBytes = GetEncryptionBytesOrDefault(encryptionDictionary, tokenScanner, true);
|
||||
}
|
||||
|
||||
encryptionDictionary.TryGetOptionalTokenDirect(NameToken.EncryptMetaData, tokenScanner, out BooleanToken encryptMetadata);
|
||||
@@ -89,5 +86,21 @@
|
||||
encryptionDictionary,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -77,6 +77,26 @@
|
||||
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>
|
||||
/// Try and get the entry with a given name and a specific data type.
|
||||
/// </summary>
|
||||
|
Reference in New Issue
Block a user