From d3a3cc24a034654b0825e4822446ddfc6a22c045 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Tue, 16 May 2017 10:48:51 -0700 Subject: Handle when XFA parser error handlers cannot format error messages. Limit the length of error messages to avoid string formatting failure. Simplify some CXFA_FMParse error handling code too. BUG=chromium:708428 Change-Id: I2f5fdb61349a90b3ba681dcc04a26ce0d7f2bdda Reviewed-on: https://pdfium-review.googlesource.com/5331 Commit-Queue: Lei Zhang Reviewed-by: dsinclair --- xfa/fxfa/fm2js/xfa_error.cpp | 8 +-- xfa/fxfa/fm2js/xfa_fm2jscontext.cpp | 9 ++-- xfa/fxfa/fm2js/xfa_fmparse.cpp | 98 +++++++++++++------------------------ xfa/fxfa/fm2js/xfa_fmparse.h | 2 +- xfa/fxfa/fm2js/xfa_lexer.cpp | 1 + xfa/fxfa/parser/cxfa_object.cpp | 3 +- 6 files changed, 47 insertions(+), 74 deletions(-) diff --git a/xfa/fxfa/fm2js/xfa_error.cpp b/xfa/fxfa/fm2js/xfa_error.cpp index ea0511a89a..5a76d614d1 100644 --- a/xfa/fxfa/fm2js/xfa_error.cpp +++ b/xfa/fxfa/fm2js/xfa_error.cpp @@ -9,10 +9,10 @@ const wchar_t kFMErrUnsupportedChar[] = L"unsupported char '%c'"; const wchar_t kFMErrBadSuffixNumber[] = L"bad suffix on number"; const wchar_t kFMErrExpectedIdentifier[] = - L"expected identifier instead of '%s'"; -const wchar_t kFMErrExpectedToken[] = L"expected '%s' instead of '%s'"; -const wchar_t kFMErrExpectedEndIf[] = L"expected 'endif' instead of '%s'"; -const wchar_t kFMErrUnexpectedExpression[] = L"unexpected expression '%s'"; + L"expected identifier instead of '%.16s'"; +const wchar_t kFMErrExpectedToken[] = L"expected '%.16s' instead of '%.16s'"; +const wchar_t kFMErrExpectedEndIf[] = L"expected 'endif' instead of '%.16s'"; +const wchar_t kFMErrUnexpectedExpression[] = L"unexpected expression '%.16s'"; const wchar_t kFMErrExpectedNonEmptyExpression[] = L"expected non-empty expression"; const wchar_t kFMErrLongAssignmentChain[] = diff --git a/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp b/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp index d0a111fa0d..7deab862f1 100644 --- a/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp +++ b/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp @@ -6144,7 +6144,7 @@ void CXFA_FM2JSContext::GlobalPropertyGetter(CFXJSE_Value* pValue) { void CXFA_FM2JSContext::ThrowNoDefaultPropertyException( const CFX_ByteStringC& name) const { - ThrowException(L"%s doesn't have a default property.", name.c_str()); + ThrowException(L"%.16s doesn't have a default property.", name.c_str()); } void CXFA_FM2JSContext::ThrowCompilerErrorException() const { @@ -6163,14 +6163,14 @@ void CXFA_FM2JSContext::ThrowPropertyNotInObjectException( const CFX_WideString& name, const CFX_WideString& exp) const { ThrowException( - L"An attempt was made to reference property '%s' of a non-object " - L"in SOM expression %s.", + L"An attempt was made to reference property '%.16s' of a non-object " + L"in SOM expression %.16s.", name.c_str(), exp.c_str()); } void CXFA_FM2JSContext::ThrowParamCountMismatchException( const CFX_WideString& method) const { - ThrowException(L"Incorrect number of parameters calling method '%s'.", + ThrowException(L"Incorrect number of parameters calling method '%.16s'.", method.c_str()); } @@ -6184,5 +6184,6 @@ void CXFA_FM2JSContext::ThrowException(const wchar_t* str, ...) const { va_start(arg_ptr, str); wsMessage.FormatV(str, arg_ptr); va_end(arg_ptr); + ASSERT(!wsMessage.IsEmpty()); FXJSE_ThrowMessage(wsMessage.UTF8Encode().AsStringC()); } diff --git a/xfa/fxfa/fm2js/xfa_fmparse.cpp b/xfa/fxfa/fm2js/xfa_fmparse.cpp index ad3a92abc3..4f6f6bac58 100644 --- a/xfa/fxfa/fm2js/xfa_fmparse.cpp +++ b/xfa/fxfa/fm2js/xfa_fmparse.cpp @@ -38,19 +38,19 @@ void CXFA_FMParse::NextToken() { void CXFA_FMParse::Check(XFA_FM_TOKEN op) { if (m_pToken->m_type != op) { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedToken, XFA_FM_KeywordToString(op), - ws_TempString.c_str()); + Error(kFMErrExpectedToken, XFA_FM_KeywordToString(op), + m_pToken->m_wstring.c_str()); } NextToken(); } -void CXFA_FMParse::Error(uint32_t lineNum, const wchar_t* msg, ...) { - m_pErrorInfo->linenum = lineNum; +void CXFA_FMParse::Error(const wchar_t* msg, ...) { + m_pErrorInfo->linenum = m_pToken->m_uLinenum; va_list ap; va_start(ap, msg); m_pErrorInfo->message.FormatV(msg, ap); va_end(ap); + ASSERT(!m_pErrorInfo->message.IsEmpty()); } std::vector> @@ -79,9 +79,7 @@ std::unique_ptr CXFA_FMParse::ParseFunction() { uint32_t line = m_pToken->m_uLinenum; NextToken(); if (m_pToken->m_type != TOKidentifier) { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier, - ws_TempString.c_str()); + Error(kFMErrExpectedIdentifier, m_pToken->m_wstring.c_str()); } else { ident = m_pToken->m_wstring; NextToken(); @@ -103,9 +101,7 @@ std::unique_ptr CXFA_FMParse::ParseFunction() { else Check(TOKrparen); } else { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier, - ws_TempString.c_str()); + Error(kFMErrExpectedIdentifier, m_pToken->m_wstring.c_str()); NextToken(); } break; @@ -166,9 +162,7 @@ std::unique_ptr CXFA_FMParse::ParseExpression() { NextToken(); break; default: - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrUnexpectedExpression, - ws_TempString.c_str()); + Error(kFMErrUnexpectedExpression, m_pToken->m_wstring.c_str()); NextToken(); break; } @@ -180,9 +174,7 @@ std::unique_ptr CXFA_FMParse::ParseVarExpression() { uint32_t line = m_pToken->m_uLinenum; NextToken(); if (m_pToken->m_type != TOKidentifier) { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier, - ws_TempString.c_str()); + Error(kFMErrExpectedIdentifier, m_pToken->m_wstring.c_str()); } else { ident = m_pToken->m_wstring; NextToken(); @@ -206,7 +198,7 @@ std::unique_ptr CXFA_FMParse::ParseSimpleExpression() { NextToken(); std::unique_ptr pExp2 = ParseLogicalOrExpression(); if (level++ == kMaxAssignmentChainLength) - Error(m_pToken->m_uLinenum, kFMErrLongAssignmentChain); + Error(kFMErrLongAssignmentChain); if (m_pErrorInfo->message.IsEmpty()) { pExp1 = pdfium::MakeUnique( line, TOKassign, std::move(pExp1), std::move(pExp2)); @@ -524,9 +516,7 @@ CXFA_FMParse::ParsePrimaryExpression() { expr = ParseParenExpression(); break; default: - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrUnexpectedExpression, - ws_TempString.c_str()); + Error(kFMErrUnexpectedExpression, m_pToken->m_wstring.c_str()); NextToken(); break; } @@ -557,9 +547,8 @@ std::unique_ptr CXFA_FMParse::ParsePostExpression( } } if (m_pToken->m_type != TOKrparen) { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedToken, - XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str()); + Error(kFMErrExpectedToken, XFA_FM_KeywordToString(TOKrparen), + m_pToken->m_wstring.c_str()); } } if (m_pErrorInfo->message.IsEmpty()) { @@ -604,9 +593,8 @@ std::unique_ptr CXFA_FMParse::ParsePostExpression( } } if (m_pToken->m_type != TOKrparen) { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedToken, - XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str()); + Error(kFMErrExpectedToken, XFA_FM_KeywordToString(TOKrparen), + m_pToken->m_wstring.c_str()); } } if (m_pErrorInfo->message.IsEmpty()) { @@ -648,9 +636,7 @@ std::unique_ptr CXFA_FMParse::ParsePostExpression( continue; } } else { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier, - ws_TempString.c_str()); + Error(kFMErrExpectedIdentifier, m_pToken->m_wstring.c_str()); return expr; } break; @@ -676,18 +662,14 @@ std::unique_ptr CXFA_FMParse::ParsePostExpression( continue; } } else { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier, - ws_TempString.c_str()); + Error(kFMErrExpectedIdentifier, m_pToken->m_wstring.c_str()); return expr; } break; case TOKdotscream: { NextToken(); if (m_pToken->m_type != TOKidentifier) { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedIdentifier, - ws_TempString.c_str()); + Error(kFMErrExpectedIdentifier, m_pToken->m_wstring.c_str()); return expr; } CFX_WideStringC tempStr = m_pToken->m_wstring; @@ -736,9 +718,8 @@ std::unique_ptr CXFA_FMParse::ParseIndexExpression() { std::move(s), true); NextToken(); if (m_pToken->m_type != TOKrbracket) { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedToken, - XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str()); + Error(kFMErrExpectedToken, XFA_FM_KeywordToString(TOKrparen), + m_pToken->m_wstring.c_str()); pExp.reset(); } return pExp; @@ -752,9 +733,8 @@ std::unique_ptr CXFA_FMParse::ParseIndexExpression() { } s = ParseSimpleExpression(); if (m_pToken->m_type != TOKrbracket) { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedToken, - XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str()); + Error(kFMErrExpectedToken, XFA_FM_KeywordToString(TOKrparen), + m_pToken->m_wstring.c_str()); } else { pExp = pdfium::MakeUnique(line, accessorIndex, std::move(s), false); @@ -766,7 +746,7 @@ std::unique_ptr CXFA_FMParse::ParseParenExpression() { Check(TOKlparen); if (m_pToken->m_type == TOKrparen) { - Error(m_pToken->m_uLinenum, kFMErrExpectedNonEmptyExpression); + Error(kFMErrExpectedNonEmptyExpression); NextToken(); return nullptr; } @@ -779,7 +759,7 @@ std::unique_ptr CXFA_FMParse::ParseParenExpression() { NextToken(); std::unique_ptr pExp2 = ParseLogicalOrExpression(); if (level++ == kMaxAssignmentChainLength) - Error(m_pToken->m_uLinenum, kFMErrLongAssignmentChain); + Error(kFMErrLongAssignmentChain); if (m_pErrorInfo->message.IsEmpty()) { pExp1 = pdfium::MakeUnique( line, TOKassign, std::move(pExp1), std::move(pExp2)); @@ -875,8 +855,7 @@ std::unique_ptr CXFA_FMParse::ParseIfExpression() { Check(TOKendif); break; default: - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedEndIf, ws_TempString.c_str()); + Error(kFMErrExpectedEndIf, m_pToken->m_wstring.c_str()); NextToken(); break; } @@ -912,9 +891,7 @@ CXFA_FMParse::ParseSubassignmentInForExpression() { expr = ParseSimpleExpression(); break; default: - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrUnexpectedExpression, - ws_TempString.c_str()); + Error(kFMErrUnexpectedExpression, m_pToken->m_wstring.c_str()); NextToken(); break; } @@ -926,9 +903,8 @@ std::unique_ptr CXFA_FMParse::ParseForExpression() { uint32_t line = m_pToken->m_uLinenum; NextToken(); if (m_pToken->m_type != TOKidentifier) { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedToken, - XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str()); + Error(kFMErrExpectedToken, XFA_FM_KeywordToString(m_pToken->m_type), + m_pToken->m_wstring.c_str()); } wsVariant = m_pToken->m_wstring; NextToken(); @@ -937,9 +913,8 @@ std::unique_ptr CXFA_FMParse::ParseForExpression() { NextToken(); pAssignment = ParseSimpleExpression(); } else { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedToken, - XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str()); + Error(kFMErrExpectedToken, XFA_FM_KeywordToString(m_pToken->m_type), + m_pToken->m_wstring.c_str()); } int32_t iDirection = 0; if (m_pToken->m_type == TOKupto) { @@ -947,9 +922,7 @@ std::unique_ptr CXFA_FMParse::ParseForExpression() { } else if (m_pToken->m_type == TOKdownto) { iDirection = -1; } else { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedToken, L"upto or downto", - ws_TempString.c_str()); + Error(kFMErrExpectedToken, L"upto or downto", m_pToken->m_wstring.c_str()); } NextToken(); std::unique_ptr pAccessor = ParseSimpleExpression(); @@ -978,18 +951,15 @@ std::unique_ptr CXFA_FMParse::ParseForeachExpression() { uint32_t line = m_pToken->m_uLinenum; NextToken(); if (m_pToken->m_type != TOKidentifier) { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrExpectedToken, - XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str()); + Error(kFMErrExpectedToken, XFA_FM_KeywordToString(m_pToken->m_type), + m_pToken->m_wstring.c_str()); } wsIdentifier = m_pToken->m_wstring; NextToken(); Check(TOKin); Check(TOKlparen); if (m_pToken->m_type == TOKrparen) { - CFX_WideString ws_TempString(m_pToken->m_wstring); - Error(m_pToken->m_uLinenum, kFMErrUnexpectedExpression, - ws_TempString.c_str()); + Error(kFMErrUnexpectedExpression, m_pToken->m_wstring.c_str()); NextToken(); } else { while (m_pToken->m_type != TOKrparen) { diff --git a/xfa/fxfa/fm2js/xfa_fmparse.h b/xfa/fxfa/fm2js/xfa_fmparse.h index 8cf6b955ed..e49fbf2f72 100644 --- a/xfa/fxfa/fm2js/xfa_fmparse.h +++ b/xfa/fxfa/fm2js/xfa_fmparse.h @@ -23,7 +23,7 @@ class CXFA_FMParse { private: void Check(XFA_FM_TOKEN op); - void Error(uint32_t lineNum, const wchar_t* msg, ...); + void Error(const wchar_t* msg, ...); bool HasError() const; std::unique_ptr ParseFunction(); std::unique_ptr ParseExpression(); diff --git a/xfa/fxfa/fm2js/xfa_lexer.cpp b/xfa/fxfa/fm2js/xfa_lexer.cpp index bdffa7e998..be3bb290b9 100644 --- a/xfa/fxfa/fm2js/xfa_lexer.cpp +++ b/xfa/fxfa/fm2js/xfa_lexer.cpp @@ -493,6 +493,7 @@ void CXFA_FMLexer::Error(const wchar_t* msg, ...) { va_start(ap, msg); m_pErrorInfo->message.FormatV(msg, ap); va_end(ap); + ASSERT(!m_pErrorInfo->message.IsEmpty()); } bool CXFA_FMLexer::HasError() const { diff --git a/xfa/fxfa/parser/cxfa_object.cpp b/xfa/fxfa/parser/cxfa_object.cpp index 30aae88307..bd7daec83a 100644 --- a/xfa/fxfa/parser/cxfa_object.cpp +++ b/xfa/fxfa/parser/cxfa_object.cpp @@ -45,7 +45,7 @@ void CXFA_Object::ThrowIndexOutOfBoundsException() const { void CXFA_Object::ThrowParamCountMismatchException( const CFX_WideString& method) const { - ThrowException(L"Incorrect number of parameters calling method '%s'.", + ThrowException(L"Incorrect number of parameters calling method '%.16s'.", method.c_str()); } @@ -59,6 +59,7 @@ void CXFA_Object::ThrowException(const wchar_t* str, ...) const { va_start(arg_ptr, str); wsMessage.FormatV(str, arg_ptr); va_end(arg_ptr); + ASSERT(!wsMessage.IsEmpty()); FXJSE_ThrowMessage(wsMessage.UTF8Encode().AsStringC()); } -- cgit v1.2.3