Exemplo n.º 1
0
        private void ReadEncoding()
        {
            if (lexer.PeekToken().Kind == TokenKind.NAME)
            {
                string name = lexer.NextToken().Text;

                if (name.Equals("StandardEncoding", StringComparison.Ordinal))
                {
                    font.Encoding = StandardEncoding.Instance;
                }
                else
                {
                    throw new IOException("Unknown encoding: " + name);
                }
                ReadMaybe(TokenKind.NAME, "readonly");
                Read(TokenKind.NAME, "def");
            }
            else
            {
                var intValue = Read(TokenKind.INTEGER).IntValue;
                ReadMaybe(TokenKind.NAME, "array");

                // 0 1 255 {1 index exch /.notdef put } for
                // we have to check "readonly" and "def" too
                // as some fonts don't provide any dup-values, see PDFBOX-2134
                while (!(lexer.PeekToken().Kind == TokenKind.NAME &&
                         (lexer.PeekToken().Text.Equals("dup", StringComparison.Ordinal) ||
                          lexer.PeekToken().Text.Equals("readonly", StringComparison.Ordinal) ||
                          lexer.PeekToken().Text.Equals("def", StringComparison.Ordinal))))
                {
                    lexer.NextToken();
                }

                Dictionary <int, string> codeToName = new Dictionary <int, string>();
                while (lexer.PeekToken().Kind == TokenKind.NAME &&
                       lexer.PeekToken().Text.Equals("dup", StringComparison.Ordinal))
                {
                    Read(TokenKind.NAME, "dup");
                    int    code = Read(TokenKind.INTEGER).IntValue;
                    string name = Read(TokenKind.LITERAL).Text;
                    Read(TokenKind.NAME, "put");
                    codeToName.Add(code, name);
                }
                font.Encoding = new Encoding(codeToName);
                ReadMaybe(TokenKind.NAME, "readonly");
                Read(TokenKind.NAME, "def");
            }
        }
Exemplo n.º 2
0
        /**
         * Parses the binary portion of a Type 1 font.
         */
        private void ParseBinary(byte[] bytes)
        {
            byte[] decrypted;
            // Sometimes, fonts use the hex format, so this needs to be converted before decryption
            if (IsBinary(bytes))
            {
                decrypted = Decrypt(bytes, EEXEC_KEY, 4);
            }
            else
            {
                decrypted = Decrypt(hexToBinary(bytes), EEXEC_KEY, 4);
            }
            lexer = new Type1Lexer(decrypted);

            // find /Private dict
            Token peekToken = lexer.PeekToken();

            while (peekToken != null && !peekToken.Text.Equals("Private", StringComparison.Ordinal))
            {
                // for a more thorough validation, the presence of "begin" before Private
                // determines how code before and following charstrings should look
                // it is not currently checked anyway
                lexer.NextToken();
                peekToken = lexer.PeekToken();
            }
            if (peekToken == null)
            {
                throw new IOException("/Private token not found");
            }

            // Private dict
            Read(TokenKind.LITERAL, "Private");
            int Length = Read(TokenKind.INTEGER).IntValue;

            Read(TokenKind.NAME, "dict");
            // actually could also be "/Private 10 dict def Private begin"
            // instead of the "dup"
            ReadMaybe(TokenKind.NAME, "dup");
            Read(TokenKind.NAME, "begin");

            int lenIV = 4; // number of random bytes at start of charstring

            for (int i = 0; i < Length; i++)
            {
                // premature end
                if (lexer.PeekToken() == null || lexer.PeekToken().Kind != TokenKind.LITERAL)
                {
                    break;
                }

                // key/value
                string key = Read(TokenKind.LITERAL).Text;

                switch (key)
                {
                case "Subrs":
                    ReadSubrs(lenIV);
                    break;

                case "OtherSubrs":
                    ReadOtherSubrs();
                    break;

                case "lenIV":
                    lenIV = ReadDictValue()[0].IntValue;
                    break;

                case "ND":
                    Read(TokenKind.START_PROC);
                    // the access restrictions are not mandatory
                    ReadMaybe(TokenKind.NAME, "noaccess");
                    Read(TokenKind.NAME, "def");
                    Read(TokenKind.END_PROC);
                    ReadMaybe(TokenKind.NAME, "executeonly");
                    Read(TokenKind.NAME, "def");
                    break;

                case "NP":
                    Read(TokenKind.START_PROC);
                    ReadMaybe(TokenKind.NAME, "noaccess");
                    Read(TokenKind.NAME);
                    Read(TokenKind.END_PROC);
                    ReadMaybe(TokenKind.NAME, "executeonly");
                    Read(TokenKind.NAME, "def");
                    break;

                case "RD":
                    // /RD {string currentfile exch readstring pop} bind executeonly def
                    Read(TokenKind.START_PROC);
                    ReadProc();
                    ReadMaybe(TokenKind.NAME, "bind");
                    ReadMaybe(TokenKind.NAME, "executeonly");
                    Read(TokenKind.NAME, "def");
                    break;

                default:
                    ReadPrivate(key, ReadDictValue());
                    break;
                }
            }

            // some fonts have "2 index" here, others have "end noaccess put"
            // sometimes followed by "put". Either way, we just skip until
            // the /CharStrings dict is found
            while (!(lexer.PeekToken().Kind == TokenKind.LITERAL &&
                     lexer.PeekToken().Text.Equals("CharStrings", StringComparison.Ordinal)))
            {
                lexer.NextToken();
            }

            // CharStrings dict
            Read(TokenKind.LITERAL, "CharStrings");
            ReadCharStrings(lenIV);
        }