Esempio n. 1
0
        /// <inheritdoc />
        public bool TryTokenize(byte currentByte, IInputBytes inputBytes, out IToken token)
        {
            token = null;

            if (currentByte != '/')
            {
                return(false);
            }

            var builder = new StringBuilder();

            while (inputBytes.MoveNext())
            {
                if (ReadHelper.IsWhitespace(inputBytes.CurrentByte) ||
                    inputBytes.CurrentByte == '{' ||
                    inputBytes.CurrentByte == '<' ||
                    inputBytes.CurrentByte == '/' ||
                    inputBytes.CurrentByte == '[' ||
                    inputBytes.CurrentByte == '(')
                {
                    break;
                }

                builder.Append((char)inputBytes.CurrentByte);
            }

            token = NameToken.Create(builder.ToString());

            return(true);
        }
Esempio n. 2
0
 private void BfSearchForXRefTables()
 {
     if (bfSearchXRefTablesOffsets == null)
     {
         // a pdf may contain more than one xref entry
         bfSearchXRefTablesOffsets = new List <long>();
         long originOffset = source.GetPosition();
         source.Seek(MinimumSearchOffset);
         // search for xref tables
         while (!source.IsEof())
         {
             if (ReadHelper.IsString(source, "xref"))
             {
                 long newOffset = source.GetPosition();
                 source.Seek(newOffset - 1);
                 // ensure that we don't read "startxref" instead of "xref"
                 if (ReadHelper.IsWhitespace(source))
                 {
                     bfSearchXRefTablesOffsets.Add(newOffset);
                 }
                 source.Seek(newOffset + 4);
             }
             source.Read();
         }
         source.Seek(originOffset);
     }
 }
Esempio n. 3
0
        private void BruteForceSearchForTables(IInputBytes bytes)
        {
            if (bfSearchXRefTablesOffsets != null)
            {
                return;
            }

            // a pdf may contain more than one xref entry
            bfSearchXRefTablesOffsets = new List <long>();

            var startOffset = bytes.CurrentOffset;

            bytes.Seek(MinimumSearchOffset);

            // search for xref tables
            while (bytes.MoveNext() && !bytes.IsAtEnd())
            {
                if (ReadHelper.IsString(bytes, "xref"))
                {
                    var newOffset = bytes.CurrentOffset;

                    bytes.Seek(newOffset - 1);

                    // ensure that we don't read "startxref" instead of "xref"
                    if (ReadHelper.IsWhitespace(bytes.CurrentByte))
                    {
                        bfSearchXRefTablesOffsets.Add(newOffset);
                    }

                    bytes.Seek(newOffset + 4);
                }
            }

            bytes.Seek(startOffset);
        }
Esempio n. 4
0
        public bool TryTokenize(byte currentByte, IInputBytes inputBytes, out IToken token)
        {
            token = null;

            if (ReadHelper.IsWhitespace(currentByte))
            {
                return(false);
            }

            var builder = stringBuilder;

            builder.Append((char)currentByte);
            while (inputBytes.MoveNext())
            {
                if (ReadHelper.IsWhitespace(inputBytes.CurrentByte))
                {
                    break;
                }

                if (inputBytes.CurrentByte == '<' || inputBytes.CurrentByte == '[' ||
                    inputBytes.CurrentByte == '/' || inputBytes.CurrentByte == ']' ||
                    inputBytes.CurrentByte == '>' || inputBytes.CurrentByte == '(' ||
                    inputBytes.CurrentByte == ')')
                {
                    break;
                }

                builder.Append((char)inputBytes.CurrentByte);
            }

            var text = builder.ToString();

            builder.Clear();

            switch (text)
            {
            case "true":
                token = BooleanToken.True;
                break;

            case "false":
                token = BooleanToken.False;
                break;

            case "null":
                token = NullToken.Instance;
                break;

            default:
                token = OperatorToken.Create(text);
                break;
            }

            return(true);
        }
Esempio n. 5
0
        public bool TryTokenize(byte currentByte, IInputBytes inputBytes, out IToken token)
        {
            token = null;

            if (currentByte != '<')
            {
                return(false);
            }

            bool foundNextOpenBrace = false;

            while (inputBytes.MoveNext())
            {
                if (inputBytes.CurrentByte == '<')
                {
                    foundNextOpenBrace = true;
                    break;
                }

                if (!ReadHelper.IsWhitespace(inputBytes.CurrentByte))
                {
                    break;
                }
            }

            if (!foundNextOpenBrace)
            {
                return(false);
            }

            var coreScanner = new CoreTokenScanner(inputBytes, ScannerScope.Dictionary);

            var tokens = new List <IToken>();

            while (coreScanner.MoveNext())
            {
                if (coreScanner.CurrentToken is CommentToken)
                {
                    continue;
                }

                tokens.Add(coreScanner.CurrentToken);
            }

            var dictionary = ConvertToDictionary(tokens);

            token = new DictionaryToken(dictionary);

            return(true);
        }
Esempio n. 6
0
        private static bool CheckObjectKeys(IInputBytes bytes, IndirectReference objectKey, long offset)
        {
            // there can't be any object at the very beginning of a pdf
            if (offset < MinimumSearchOffset)
            {
                return(false);
            }

            var  objectNr     = objectKey.ObjectNumber;
            long objectGen    = objectKey.Generation;
            var  originOffset = bytes.CurrentOffset;

            var objectString = ObjectHelper.CreateObjectString(objectNr, objectGen);

            try
            {
                if (offset >= bytes.Length)
                {
                    bytes.Seek(originOffset);
                    return(false);
                }

                bytes.Seek(offset);

                if (ReadHelper.IsWhitespace(bytes.CurrentByte))
                {
                    bytes.MoveNext();
                }

                if (ReadHelper.IsString(bytes, objectString))
                {
                    // everything is ok, return origin object key
                    bytes.Seek(originOffset);
                    return(true);
                }
            }
            catch (Exception)
            {
                // Swallow the exception, obviously there isn't any valid object number
            }
            finally
            {
                bytes.Seek(originOffset);
            }

            // no valid object number found
            return(false);
        }
Esempio n. 7
0
        private static string ReadLine(IInputBytes input, StringBuilder stringBuilder)
        {
            stringBuilder.Clear();

            while (ReadHelper.IsWhitespace(input.CurrentByte) && input.MoveNext())
            {
            }

            stringBuilder.Append((char)input.CurrentByte);

            while (input.MoveNext() && !ReadHelper.IsEndOfLine(input.CurrentByte))
            {
                stringBuilder.Append((char)input.CurrentByte);
            }

            return(stringBuilder.ToString());
        }
Esempio n. 8
0
        private bool CheckXRefStreamOffset(IRandomAccessRead source, long startXRefOffset, bool isLenient, CosObjectPool pool)
        {
            // repair mode isn't available in non-lenient mode
            if (!isLenient || startXRefOffset == 0)
            {
                return(true);
            }
            // seek to offset-1
            source.Seek(startXRefOffset - 1);
            int nextValue = source.Read();

            // the first character has to be a whitespace, and then a digit
            if (ReadHelper.IsWhitespace(nextValue))
            {
                ReadHelper.SkipSpaces(source);
                if (ReadHelper.IsDigit(source))
                {
                    try
                    {
                        // it's a XRef stream
                        ObjectHelper.ReadObjectNumber(source);
                        ObjectHelper.ReadGenerationNumber(source);

                        ReadHelper.ReadExpectedString(source, "obj", true);

                        // check the dictionary to avoid false positives
                        PdfDictionary dict = dictionaryParser.Parse(source, baseParser, pool);
                        source.Seek(startXRefOffset);

                        if (dict.IsType(CosName.XREF))
                        {
                            return(true);
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error("Couldn't read the xref stream object.", ex);
                        // there wasn't an object of a xref stream
                        source.Seek(startXRefOffset);
                    }
                }
            }
            return(false);
        }
Esempio n. 9
0
        private static string ReadString(IInputBytes input, StringBuilder stringBuilder)
        {
            stringBuilder.Clear();

            if (input.IsAtEnd())
            {
                return(EndFontMetrics);
            }

            while (ReadHelper.IsWhitespace(input.CurrentByte) && input.MoveNext())
            {
            }

            stringBuilder.Append((char)input.CurrentByte);

            while (input.MoveNext() && !ReadHelper.IsWhitespace(input.CurrentByte))
            {
                stringBuilder.Append((char)input.CurrentByte);
            }

            return(stringBuilder.ToString());
        }
Esempio n. 10
0
        public bool TryTokenize(byte currentByte, IInputBytes inputBytes, out IToken token)
        {
            token = null;

            if (currentByte != '<')
            {
                return(false);
            }

            var characters = new List <char>();

            while (inputBytes.MoveNext())
            {
                var current = inputBytes.CurrentByte;

                if (ReadHelper.IsWhitespace(current))
                {
                    continue;
                }

                if (current == '>')
                {
                    break;
                }

                if (!IsValidHexCharacter(current))
                {
                    return(false);
                }

                characters.Add((char)current);
            }

            token = new HexToken(characters);

            return(true);
        }
Esempio n. 11
0
        /// <summary>
        /// To distinguish between binary and hex the first 4 bytes (of the ciphertext) for hex must obey these restrictions:
        /// The first byte must not be whitespace.
        /// One of the first four ciphertext bytes must not be an ASCII hex character.
        /// </summary>
        private static bool IsBinary(IReadOnlyList <byte> bytes)
        {
            if (bytes.Count < 4)
            {
                return(true);
            }

            if (ReadHelper.IsWhitespace(bytes[0]))
            {
                return(true);
            }

            for (var i = 1; i < 4; i++)
            {
                var b = bytes[i];

                if (!ReadHelper.IsHex(b))
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 12
0
        private Type1Token ReadNextToken()
        {
            previousToken = CurrentToken;
            bool skip;

            do
            {
                skip = false;
                while (bytes.MoveNext())
                {
                    var b = bytes.CurrentByte;
                    var c = (char)b;

                    switch (c)
                    {
                    case '%':
                        comments.Add(ReadComment());
                        break;

                    case '(':
                        return(ReadString());

                    case ')':
                        throw new InvalidOperationException("Encountered an end of string ')' outside of string.");

                    case '[':
                        return(new Type1Token(c, Type1Token.TokenType.StartArray));

                    case ']':
                        return(new Type1Token(c, Type1Token.TokenType.EndArray));

                    case '{':
                        return(new Type1Token(c, Type1Token.TokenType.StartProc));

                    case '}':
                        return(new Type1Token(c, Type1Token.TokenType.EndProc));

                    case '/':
                    {
                        var name = ReadLiteral();
                        return(new Type1Token(name, Type1Token.TokenType.Literal));
                    }

                    case '<':
                    {
                        var following = bytes.Peek();
                        if (following == '<')
                        {
                            bytes.MoveNext();
                            return(new Type1Token("<<", Type1Token.TokenType.StartDict));
                        }

                        return(new Type1Token(c, Type1Token.TokenType.Name));
                    }

                    case '>':
                    {
                        var following = bytes.Peek();
                        if (following == '>')
                        {
                            bytes.MoveNext();
                            return(new Type1Token(">>", Type1Token.TokenType.EndDict));
                        }

                        return(new Type1Token(c, Type1Token.TokenType.Name));
                    }

                    default:
                    {
                        if (ReadHelper.IsWhitespace(b))
                        {
                            skip = true;
                            break;
                        }

                        if (b == 0)
                        {
                            skip = true;
                            break;
                        }

                        if (TryReadNumber(c, out var number))
                        {
                            return(number);
                        }

                        var name = ReadLiteral(c);
                        if (name == null)
                        {
                            throw new InvalidOperationException($"The binary portion of the type 1 font was invalid at position {bytes.CurrentOffset}.");
                        }

                        if (name.Equals(Type1Symbols.RdProcedure, StringComparison.OrdinalIgnoreCase) || name.Equals(Type1Symbols.RdProcedureAlt))
                        {
                            if (previousToken.Type == Type1Token.TokenType.Integer)
                            {
                                return(ReadCharString(previousToken.AsInt()));
                            }

                            throw new InvalidOperationException($"Expected integer token before {name} at offset {bytes.CurrentOffset}.");
                        }

                        return(new Type1Token(name, Type1Token.TokenType.Name));
                    }
                    }
                }
            } while (skip);

            return(null);
        }