// fNextToken initially should point to // a string after the initial open paren ("(") // After this call, fNextToken points to the // first character after the matching close // paren. Only call AdvanceToNextToken() to get the NEXT // token after the one returned in fNextToken. void nsIMAPGenericParser::skip_to_close_paren() { int numberOfCloseParensNeeded = 1; while (ContinueParse()) { // go through fNextToken, account for nested parens const char *loc; for (loc = fNextToken; loc && *loc; loc++) { if (*loc == '(') numberOfCloseParensNeeded++; else if (*loc == ')') { numberOfCloseParensNeeded--; if (numberOfCloseParensNeeded == 0) { fNextToken = loc + 1; if (!fNextToken || !*fNextToken) AdvanceToNextToken(); return; } } else if (*loc == '{' || *loc == '"') { // quoted or literal fNextToken = loc; char *a = CreateString(); PR_FREEIF(a); break; // move to next token } } if (ContinueParse()) AdvanceToNextToken(); } }
// This function leaves us off with fCurrentTokenPlaceHolder immediately after // the end of the literal string. Call AdvanceToNextToken() to get the token // after the literal string. // RFC3501: literal = "{" number "}" CRLF *CHAR8 // ; Number represents the number of CHAR8s // CHAR8 = %x01-ff // ; any OCTET except NUL, %x00 char *nsIMAPGenericParser::CreateLiteral() { int32 numberOfCharsInMessage = atoi(fNextToken + 1); uint32 numBytes = numberOfCharsInMessage + 1; NS_ASSERTION(numBytes, "overflow!"); if (!numBytes) return nsnull; char *returnString = (char *)PR_Malloc(numBytes); if (!returnString) { HandleMemoryFailure(); return nsnull; } int32 currentLineLength = 0; int32 charsReadSoFar = 0; int32 bytesToCopy = 0; while (charsReadSoFar < numberOfCharsInMessage) { AdvanceToNextLine(); if (!ContinueParse()) break; currentLineLength = strlen(fCurrentLine); bytesToCopy = (currentLineLength > numberOfCharsInMessage - charsReadSoFar ? numberOfCharsInMessage - charsReadSoFar : currentLineLength); NS_ASSERTION(bytesToCopy, "zero-length line?"); memcpy(returnString + charsReadSoFar, fCurrentLine, bytesToCopy); charsReadSoFar += bytesToCopy; } if (ContinueParse()) { if (currentLineLength == bytesToCopy) { // We have consumed the entire line. // Consider the input "{4}\r\n" "L1\r\n" " A2\r\n" which is read // line-by-line. Reading an Astring, this should result in "L1\r\n". // Note that the second line is "L1\r\n", where the "\r\n" is part of // the literal. Hence, we now read the next line to ensure that the // next call to AdvanceToNextToken() leads to fNextToken=="A2" in our // example. AdvanceToNextLine(); } else AdvanceTokenizerStartingPoint(bytesToCopy); } returnString[charsReadSoFar] = 0; return returnString; }
void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates, const CFX_Matrix* pParentMatrix, CPDF_Type3Char* pType3Char, int level) { StartParse(pGraphicStates, pParentMatrix, pType3Char, level); ContinueParse(nullptr); }
void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates, CFX_Matrix* pParentMatrix, CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level) { StartParse(pGraphicStates, pParentMatrix, pType3Char, pOptions, level); ContinueParse(NULL); }
void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates, const CFX_Matrix* pParentMatrix, CPDF_Type3Char* pType3Char, std::set<const uint8_t*>* parsedSet) { if (GetParseState() == ParseState::kParsed) return; if (GetParseState() == ParseState::kNotParsed) { if (!parsedSet) { if (!m_ParsedSet) m_ParsedSet = pdfium::MakeUnique<std::set<const uint8_t*>>(); parsedSet = m_ParsedSet.get(); } StartParse(pdfium::MakeUnique<CPDF_ContentParser>( this, pGraphicStates, pParentMatrix, pType3Char, parsedSet)); } ASSERT(GetParseState() == ParseState::kParsing); ContinueParse(nullptr); }
// Call this to create a buffer containing all characters within // a given set of parentheses. // Call this with fNextToken[0]=='(', that is, the open paren // of the group. // It will allocate and return all characters up to and including the corresponding // closing paren, and leave the parser in the right place afterwards. char *nsIMAPGenericParser::CreateParenGroup() { NS_ASSERTION(fNextToken[0] == '(', "we don't have a paren group!"); int numOpenParens = 0; AdvanceTokenizerStartingPoint(fNextToken - fLineOfTokens); // Build up a buffer containing the paren group. nsCString returnString; char *parenGroupStart = fCurrentTokenPlaceHolder; NS_ASSERTION(parenGroupStart[0] == '(', "we don't have a paren group (2)!"); while (*fCurrentTokenPlaceHolder) { if (*fCurrentTokenPlaceHolder == '{') // literal { // Ensure it is a properly formatted literal. NS_ASSERTION(!strcmp("}\r\n", fCurrentTokenPlaceHolder + strlen(fCurrentTokenPlaceHolder) - 3), "not a literal"); // Append previous characters and the "{xx}\r\n" to buffer. returnString.Append(parenGroupStart); // Append literal itself. AdvanceToNextToken(); if (!ContinueParse()) break; char *lit = CreateLiteral(); NS_ASSERTION(lit, "syntax error or out of memory"); if (!lit) break; returnString.Append(lit); PR_Free(lit); if (!ContinueParse()) break; parenGroupStart = fCurrentTokenPlaceHolder; } else if (*fCurrentTokenPlaceHolder == '"') // quoted { // Append the _escaped_ version of the quoted string: // just skip it (because the quoted string must be on the same line). AdvanceToNextToken(); if (!ContinueParse()) break; char *q = CreateQuoted(); if (!q) break; PR_Free(q); if (!ContinueParse()) break; } else { // Append this character to the buffer. char c = *fCurrentTokenPlaceHolder++; if (c == '(') numOpenParens++; else if (c == ')') { numOpenParens--; if (numOpenParens == 0) break; } } } if (numOpenParens != 0 || !ContinueParse()) { SetSyntaxError(true, "closing ')' not found in paren group"); return nsnull; } returnString.Append(parenGroupStart, fCurrentTokenPlaceHolder - parenGroupStart); AdvanceToNextToken(); return ToNewCString(returnString); }
void CPDF_Page::ParseContent(CPDF_ParseOptions* pOptions, FX_BOOL bReParse) { StartParse(pOptions, bReParse); ContinueParse(NULL); }
void CPDF_Page::ParseContent(CPDF_ParseOptions* pOptions) { StartParse(pOptions); ContinueParse(nullptr); }
void CPDF_Page::ParseContent() { StartParse(); ContinueParse(nullptr); }