Ejemplo n.º 1
0
 public CosBase Parse(ParsingArguments arguments, CosObject obj, bool requiresExistingObject)
 {
     return(Parse(arguments.Reader, obj, arguments.CachingProviders.ObjectPool,
                  arguments.CrossReferenceTable, arguments.CachingProviders.BruteForceSearcher,
                  arguments.IsLenientParsing,
                  requiresExistingObject));
 }
Ejemplo n.º 2
0
        private static CosBase ParseTrailer(IRandomAccessRead reader, CrossReferenceTable crossReferenceTable,
                                            DynamicParser dynamicParser, BruteForceSearcher bruteForceSearcher, CosObjectPool pool, bool isLenientParsing)
        {
            foreach (var value in crossReferenceTable.Dictionary.Values)
            {
                if (value is CosObject temporaryObject)
                {
                    // Loads these objects into the object pool for access later.
                    dynamicParser.Parse(reader, temporaryObject, pool, crossReferenceTable, bruteForceSearcher,
                                        isLenientParsing, false);
                }
            }

            CosObject root = (CosObject)crossReferenceTable.Dictionary.GetItemOrDefault(CosName.ROOT);

            if (root == null)
            {
                throw new InvalidOperationException("Missing root object specification in trailer.");
            }

            var rootObject = dynamicParser.Parse(reader, root, pool, crossReferenceTable, bruteForceSearcher,
                                                 isLenientParsing, false);

            return(rootObject);
        }
Ejemplo n.º 3
0
        public IReadOnlyList <CosObject> Parse(PdfRawStream stream, CosObjectPool pool)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            //need to first parse the header.
            var numberOfObjects = stream.Dictionary.GetIntOrDefault(CosName.N);
            var objectNumbers   = new List <long>(numberOfObjects);

            var streamObjects = new List <CosObject>(numberOfObjects);

            var bytes = stream.Decode(filterProvider);

            var reader = new RandomAccessBuffer(bytes);

            for (int i = 0; i < numberOfObjects; i++)
            {
                long objectNumber = ObjectHelper.ReadObjectNumber(reader);
                // skip offset
                ReadHelper.ReadLong(reader);
                objectNumbers.Add(objectNumber);
            }

            CosObject obj;
            CosBase   cosObject;
            int       objectCounter = 0;

            while ((cosObject = baseParser.Parse(reader, pool)) != null)
            {
                obj = new CosObject(cosObject);
                obj.SetGenerationNumber(0);

                if (objectCounter >= objectNumbers.Count)
                {
                    log.Error("/ObjStm (object stream) has more objects than /N " + numberOfObjects);
                    break;
                }

                obj.SetObjectNumber(objectNumbers[objectCounter]);
                streamObjects.Add(obj);

                // According to the spec objects within an object stream shall not be enclosed
                // by obj/endobj tags, but there are some pdfs in the wild using those tags
                // skip endobject marker if present
                if (!reader.IsEof() && reader.Peek() == 'e')
                {
                    ReadHelper.ReadLine(reader);
                }

                objectCounter++;
            }

            return(streamObjects);
        }
Ejemplo n.º 4
0
        public CosBase Parse(IRandomAccessRead reader, CosObject obj, CosObjectPool pool,
                             CrossReferenceTable crossReferenceTable, BruteForceSearcher bruteForceSearcher, bool isLenient, bool requireExistingObject)
        {
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj));
            }

            return(Parse(reader, obj.GetObjectNumber(), obj.GetGenerationNumber(), pool,
                         crossReferenceTable, bruteForceSearcher, isLenient, requireExistingObject));
        }
Ejemplo n.º 5
0
        public static CosBase Find <T>(CosObject baseObject, IPdfObjectParser parser, IRandomAccessRead reader,
                                       bool isLenientParsing) where T : CosBase
        {
            var result = parser.Parse(baseObject.ToIndirectReference(), reader, isLenientParsing);

            if (result is T resultT)
            {
                return(resultT);
            }

            if (result is CosObject obj)
            {
                return(Find <T>(obj, parser, reader, isLenientParsing));
            }

            if (result is COSArray arr && arr.Count == 1 && arr.get(0) is CosObject arrayObject)
            {
                return(Find <T>(arrayObject, parser, reader, isLenientParsing));
            }

            throw new InvalidOperationException($"Could not find the object {baseObject.ToIndirectReference()} with type {typeof(T).Name}.");
        }
Ejemplo n.º 6
0
        private static bool TryGetFirstDescendant(PdfDictionary dictionary, out CosObject descendant)
        {
            descendant = null;

            if (!dictionary.TryGetValue(CosName.DESCENDANT_FONTS, out var value))
            {
                return(false);
            }

            if (value is CosObject obj)
            {
                descendant = obj;
                return(true);
            }

            if (value is COSArray array && array.Count > 0 && array.get(0) is CosObject objArr)
            {
                descendant = objArr;
                return(true);
            }

            return(false);
        }
Ejemplo n.º 7
0
        public CosBase Parse(IRandomAccessRead reader, CosObjectPool pool)
        {
            CosBase retval = null;

            ReadHelper.SkipSpaces(reader);
            int nextByte = reader.Peek();

            if (nextByte == -1)
            {
                return(null);
            }

            char c = (char)nextByte;

            switch (c)
            {
            case '<':
            {
                // pull off first left bracket
                int leftBracket = reader.Read();
                // check for second left bracket
                c = (char)reader.Peek();
                reader.Unread(leftBracket);
                if (c == '<')
                {
                    retval = dictionaryParser.Parse(reader, this, pool);
                    ReadHelper.SkipSpaces(reader);
                }
                else
                {
                    retval = stringParser.Parse(reader);
                }
                break;
            }

            case '[':
            {
                // array
                retval = arrayParser.Parse(reader, this, pool);
                break;
            }

            case '(':
                retval = stringParser.Parse(reader);
                break;

            case '/':
                // name
                retval = nameParser.Parse(reader);
                break;

            case 'n':
            {
                // null
                ReadHelper.ReadExpectedString(reader, "null");
                retval = CosNull.Null;
                break;
            }

            case 't':
            {
                string truestring = OtherEncodings.BytesAsLatin1String(reader.ReadFully(4));
                if (truestring.Equals("true"))
                {
                    retval = PdfBoolean.True;
                }
                else
                {
                    throw new IOException("expected true actual='" + truestring + "' " + reader +
                                          "' at offset " + reader.GetPosition());
                }
                break;
            }

            case 'f':
            {
                string falsestring = OtherEncodings.BytesAsLatin1String(reader.ReadFully(5));
                if (falsestring.Equals("false"))
                {
                    retval = PdfBoolean.False;
                }
                else
                {
                    throw new IOException("expected false actual='" + falsestring + "' " + reader +
                                          "' at offset " + reader.GetPosition());
                }
                break;
            }

            case 'R':
                reader.Read();
                retval = new CosObject(null);
                break;

            default:

                if (char.IsDigit(c) || c == '-' || c == '+' || c == '.')
                {
                    StringBuilder buf = new StringBuilder();
                    int           ic  = reader.Read();
                    c = (char)ic;
                    while (char.IsDigit(c) ||
                           c == '-' ||
                           c == '+' ||
                           c == '.' ||
                           c == 'E' ||
                           c == 'e')
                    {
                        buf.Append(c);
                        ic = reader.Read();
                        c  = (char)ic;
                    }
                    if (ic != -1)
                    {
                        reader.Unread(ic);
                    }
                    retval = CosNumberFactory.get(buf.ToString()) as CosBase;
                }
                else
                {
                    //This is not suppose to happen, but we will allow for it
                    //so we are more compatible with POS writers that don't
                    //follow the spec
                    string badstring = ReadHelper.ReadString(reader);
                    if (badstring == string.Empty)
                    {
                        int peek = reader.Peek();
                        // we can end up in an infinite loop otherwise
                        throw new IOException("Unknown dir object c='" + c +
                                              "' cInt=" + (int)c + " peek='" + (char)peek
                                              + "' peekInt=" + peek + " at offset " + reader.GetPosition());
                    }

                    // if it's an endstream/endobj, we want to put it back so the caller will see it
                    if (string.Equals("endobj", badstring) || string.Equals("endstream", badstring))
                    {
                        reader.Unread(OtherEncodings.StringAsLatin1Bytes(badstring));
                    }
                }
                break;
            }
            return(retval);
        }