/// <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); }
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); } }
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); }
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); }
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); }
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); }
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()); }
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); }
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()); }
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); }
/// <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); }
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); }