From 8daab317ff959905e926b861a7d2aa876fd10429 Mon Sep 17 00:00:00 2001 From: Bo Xu Date: Mon, 14 Jul 2014 12:13:53 -0700 Subject: Fix an out-of-boundary issue for wide string BUG=381521 R=palmer@chromium.org Review URL: https://codereview.chromium.org/383563002 --- core/include/fxcrt/fx_string.h | 6 ++-- core/src/fxcrt/fx_basic_util.cpp | 2 +- core/src/fxcrt/fx_basic_wstring.cpp | 28 +++++++-------- core/src/fxge/win32/fx_win32_device.cpp | 4 ++- fpdfsdk/src/fpdfdoc.cpp | 3 +- fpdfsdk/src/fpdftext.cpp | 5 +-- fpdfsdk/src/javascript/Document.cpp | 62 ++++++++++++++++----------------- fpdfsdk/src/javascript/app.cpp | 22 ++++++------ fpdfsdk/src/jsapi/fxjs_v8.cpp | 2 +- 9 files changed, 69 insertions(+), 65 deletions(-) diff --git a/core/include/fxcrt/fx_string.h b/core/include/fxcrt/fx_string.h index fe56e1867e..26b04b70fa 100644 --- a/core/include/fxcrt/fx_string.h +++ b/core/include/fxcrt/fx_string.h @@ -634,9 +634,11 @@ public: static CFX_WideString FromLocal(const char* str, FX_STRSIZE len = -1); - static CFX_WideString FromUTF8(const char* str, FX_STRSIZE len = -1); + static CFX_WideString FromUTF8(const char* str, FX_STRSIZE len); - static CFX_WideString FromUTF16LE(const unsigned short* str, FX_STRSIZE len = -1); + static CFX_WideString FromUTF16LE(const unsigned short* str, FX_STRSIZE len); + + static FX_STRSIZE WStringLength(const unsigned short* str); operator FX_LPCWSTR() const { diff --git a/core/src/fxcrt/fx_basic_util.cpp b/core/src/fxcrt/fx_basic_util.cpp index 1d947d3fed..dc5eea7821 100644 --- a/core/src/fxcrt/fx_basic_util.cpp +++ b/core/src/fxcrt/fx_basic_util.cpp @@ -273,7 +273,7 @@ CFX_WideString FX_DecodeURI(const CFX_ByteString& bsURI) rURI += bsURI[i]; } } - return CFX_WideString::FromUTF8(rURI); + return CFX_WideString::FromUTF8(rURI, rURI.GetLength()); } #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ class CFindFileData : public CFX_Object diff --git a/core/src/fxcrt/fx_basic_wstring.cpp b/core/src/fxcrt/fx_basic_wstring.cpp index 192579fe54..794630b9e5 100644 --- a/core/src/fxcrt/fx_basic_wstring.cpp +++ b/core/src/fxcrt/fx_basic_wstring.cpp @@ -398,15 +398,10 @@ CFX_WideString CFX_WideString::FromLocal(const char* str, FX_STRSIZE len) } CFX_WideString CFX_WideString::FromUTF8(const char* str, FX_STRSIZE len) { - if (!str) { + if (!str || 0 == len) { return CFX_WideString(); } - if (len < 0) { - len = 0; - while (str[len]) { - len ++; - } - } + CFX_UTF8Decoder decoder; for (FX_STRSIZE i = 0; i < len; i ++) { decoder.Input(str[i]); @@ -415,15 +410,10 @@ CFX_WideString CFX_WideString::FromUTF8(const char* str, FX_STRSIZE len) } CFX_WideString CFX_WideString::FromUTF16LE(const unsigned short* wstr, FX_STRSIZE wlen) { - if (!wstr || !wlen) { + if (!wstr || 0 == wlen) { return CFX_WideString(); } - if (wlen < 0) { - wlen = 0; - while (wstr[wlen]) { - wlen ++; - } - } + CFX_WideString result; FX_WCHAR* buf = result.GetBuffer(wlen); for (int i = 0; i < wlen; i ++) { @@ -432,6 +422,16 @@ CFX_WideString CFX_WideString::FromUTF16LE(const unsigned short* wstr, FX_STRSIZ result.ReleaseBuffer(wlen); return result; } +FX_STRSIZE CFX_WideString::WStringLength(const unsigned short* str) +{ + FX_STRSIZE len = 0; + if (str) + while (str[len]) len++; + return len; +} + + + void CFX_WideString::AllocCopy(CFX_WideString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex) const { // |FX_STRSIZE| is currently typedef'd as in |int|. TODO(palmer): It diff --git a/core/src/fxge/win32/fx_win32_device.cpp b/core/src/fxge/win32/fx_win32_device.cpp index 2e2ea9a92b..9c03a30837 100644 --- a/core/src/fxge/win32/fx_win32_device.cpp +++ b/core/src/fxge/win32/fx_win32_device.cpp @@ -328,7 +328,9 @@ void* CWin32FontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitc for (int i = 0; i < iCount; ++i) { if (face == VariantNames[i].m_pFaceName) { CFX_WideString wsFace = CFX_WideString::FromLocal(facebuf); - CFX_WideString wsName = CFX_WideString::FromUTF16LE((const unsigned short*)VariantNames[i].m_pVariantName); + const unsigned short* pName = (const unsigned short*)VariantNames[i].m_pVariantName; + FX_STRSIZE len = CFX_WideString::WStringLength(pName); + CFX_WideString wsName = CFX_WideString::FromUTF16LE(pName, len); if (wsFace == wsName) { return hFont; } diff --git a/fpdfsdk/src/fpdfdoc.cpp b/fpdfsdk/src/fpdfdoc.cpp index edd61f9e51..e974ffbcf2 100644 --- a/fpdfsdk/src/fpdfdoc.cpp +++ b/fpdfsdk/src/fpdfdoc.cpp @@ -36,7 +36,8 @@ DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_Find(FPDF_DOCUMENT document, FPDF_W CPDF_Document* pDoc = (CPDF_Document*)document; CPDF_BookmarkTree tree(pDoc); - CFX_WideString wstr = CFX_WideString::FromUTF16LE(title); + FX_STRSIZE len = CFX_WideString::WStringLength(title); + CFX_WideString wstr = CFX_WideString::FromUTF16LE(title, len); return FindBookmark(tree, NULL, wstr); } diff --git a/fpdfsdk/src/fpdftext.cpp b/fpdfsdk/src/fpdftext.cpp index 1aa0542124..869ec48ba6 100644 --- a/fpdfsdk/src/fpdftext.cpp +++ b/fpdfsdk/src/fpdftext.cpp @@ -11,7 +11,7 @@ #include #endif - // jabdelmalek: commented out to build on Linux. Not used. + // jabdelmalek: commented out to build on Linux. Not used. // extern HANDLE g_hModule; DLLEXPORT FPDF_TEXTPAGE STDCALL FPDFText_LoadPage(FPDF_PAGE page) @@ -162,7 +162,8 @@ DLLEXPORT FPDF_SCHHANDLE STDCALL FPDFText_FindStart(FPDF_TEXTPAGE text_page,FPDF try { textpageFind=IPDF_TextPageFind::CreatePageFind((IPDF_TextPage*)text_page); - textpageFind->FindFirst(CFX_WideString::FromUTF16LE(findwhat),flags,start_index); + FX_STRSIZE len = CFX_WideString::WStringLength(findwhat); + textpageFind->FindFirst(CFX_WideString::FromUTF16LE(findwhat, len),flags,start_index); } catch (...) { diff --git a/fpdfsdk/src/javascript/Document.cpp b/fpdfsdk/src/javascript/Document.cpp index 2318d9b834..0c4d4f4cdf 100644 --- a/fpdfsdk/src/javascript/Document.cpp +++ b/fpdfsdk/src/javascript/Document.cpp @@ -196,7 +196,7 @@ FX_BOOL Document::numFields(OBJ_PROP_PARAMS) ASSERT(m_pDocument != NULL); - CPDFSDK_InterForm *pInterForm = m_pDocument->GetInterForm(); + CPDFSDK_InterForm *pInterForm = m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); CPDF_InterForm *pPDFForm = pInterForm->GetInterForm(); @@ -284,7 +284,7 @@ FX_BOOL Document::pageNum(OBJ_PROP_PARAMS) } } - return TRUE; + return TRUE; } FX_BOOL Document::ParserParams(JSObject* pObj,CJS_AnnotObj& annotobj) @@ -294,7 +294,7 @@ FX_BOOL Document::ParserParams(JSObject* pObj,CJS_AnnotObj& annotobj) FX_BOOL Document::addAnnot(OBJ_METHOD_PARAMS) { - return TRUE; + return TRUE; } FX_BOOL Document::addField(OBJ_METHOD_PARAMS) @@ -336,7 +336,7 @@ FX_BOOL Document::exportAsFDF(OBJ_METHOD_PARAMS) if (!bWhole) arrayFileds.Attach(params[2]); //FX_BOOL bFlags = params.size() > 3 ? (FX_BOOL)params[3] : FALSE; - CFX_WideString swFilePath = params.size() > 4 ? (FX_LPCWSTR)params[4].operator CFX_WideString() : (FX_LPCWSTR)L""; + CFX_WideString swFilePath = params.size() > 4 ? (FX_LPCWSTR)params[4].operator CFX_WideString() : (FX_LPCWSTR)L""; if (swFilePath.IsEmpty()) { @@ -349,10 +349,10 @@ FX_BOOL Document::exportAsFDF(OBJ_METHOD_PARAMS) { swFilePath = app::PDFPathToSysPath(swFilePath); } - + m_pDocument->SetFocusAnnot(NULL); - CPDFSDK_InterForm* pInterForm= (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); + CPDFSDK_InterForm* pInterForm= (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); @@ -386,7 +386,7 @@ FX_BOOL Document::exportAsFDF(OBJ_METHOD_PARAMS) for (int i=0,sz=aFields.GetSize(); iGetValue() == L"") @@ -396,10 +396,10 @@ FX_BOOL Document::exportAsFDF(OBJ_METHOD_PARAMS) if (pField->GetFieldFlags() & 0x2000) continue; - fields.Add((void*)pField); + fields.Add((void*)pField); } - return pInterForm->ExportFieldsToFDFFile(swFilePath, fields, TRUE); + return pInterForm->ExportFieldsToFDFFile(swFilePath, fields, TRUE); } //exports form fields an XFDF file to the local hard drive @@ -430,7 +430,7 @@ FX_BOOL Document::getField(OBJ_METHOD_PARAMS) CFX_WideString wideName = params[0].operator CFX_WideString(); - CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm(); + CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); @@ -505,7 +505,7 @@ FX_BOOL Document::importAnFDF(OBJ_METHOD_PARAMS) if (params.size() > 0) swPath = params[0]; - + if (swPath.IsEmpty()) { CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); @@ -526,7 +526,7 @@ FX_BOOL Document::importAnFDF(OBJ_METHOD_PARAMS) if (!pInterForm->ImportFormFromFDFFile(swPath, TRUE)) return FALSE; - m_pDocument->SetChangeMark(); + m_pDocument->SetChangeMark(); // CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); // ASSERT(pEnv != NULL); // IUndo* pUndo = IUndo::GetUndo(pEnv); @@ -605,9 +605,9 @@ FX_BOOL Document::mailForm(OBJ_METHOD_PARAMS) ASSERT(pRuntime != NULL); pRuntime->BeginBlock(); - pEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI, (FX_LPCWSTR)cTo, (FX_LPCWSTR)cSubject, (FX_LPCWSTR)cCc, (FX_LPCWSTR)cBcc, (FX_LPCWSTR)cMsg); + pEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI, (FX_LPCWSTR)cTo, (FX_LPCWSTR)cSubject, (FX_LPCWSTR)cCc, (FX_LPCWSTR)cBcc, (FX_LPCWSTR)cMsg); pRuntime->EndBlock(); - return TRUE; + return TRUE; } FX_BOOL Document::print(OBJ_METHOD_PARAMS) @@ -660,11 +660,11 @@ FX_BOOL Document::print(OBJ_METHOD_PARAMS) if(nlength >= 2) nStart = (int)params[1]; if(nlength >= 3) - nEnd = (int)params[2]; + nEnd = (int)params[2]; if(nlength >= 4) bSilent = params[3]; if(nlength >= 5) - bShrinkToFit = params[4]; + bShrinkToFit = params[4]; if(nlength >= 6) bPrintAsImage = params[5]; if(nlength >= 7) @@ -673,13 +673,13 @@ FX_BOOL Document::print(OBJ_METHOD_PARAMS) bAnnotations = params[7]; } - ASSERT(m_pDocument != NULL); + ASSERT(m_pDocument != NULL); - if (CPDFDoc_Environment* pEnv = m_pDocument->GetEnv()) - { + if (CPDFDoc_Environment* pEnv = m_pDocument->GetEnv()) + { pEnv->JS_docprint(bUI, nStart, nEnd, bSilent, bShrinkToFit, bPrintAsImage, bReverse, bAnnotations); - return TRUE; - } + return TRUE; + } return FALSE; } @@ -786,15 +786,15 @@ FX_BOOL Document::resetForm(OBJ_METHOD_PARAMS) if (aFields.GetSize() > 0) { - pPDFForm->ResetForm(aFields, TRUE, TRUE); - m_pDocument->SetChangeMark(); + pPDFForm->ResetForm(aFields, TRUE, TRUE); + m_pDocument->SetChangeMark(); } } else { - pPDFForm->ResetForm(TRUE); - m_pDocument->SetChangeMark(); + pPDFForm->ResetForm(TRUE); + m_pDocument->SetChangeMark(); } @@ -1070,7 +1070,7 @@ FX_BOOL Document::info(OBJ_PROP_PARAMS) { CFX_ByteString bsKey; CPDF_Object* pValueObj = pDictionary->GetNextElement(pos, bsKey); - CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey); + CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey, bsKey.GetLength()); if((pValueObj->GetType()==PDFOBJ_STRING) || (pValueObj->GetType()==PDFOBJ_NAME) ) JS_PutObjectString(isolate,pObj, wsKey, pValueObj->GetUnicodeText()); if(pValueObj->GetType()==PDFOBJ_NUMBER) @@ -1356,12 +1356,12 @@ FX_BOOL Document::filesize(OBJ_PROP_PARAMS) FX_BOOL Document::mouseX(OBJ_PROP_PARAMS) { - return TRUE; + return TRUE; } FX_BOOL Document::mouseY(OBJ_PROP_PARAMS) { - return TRUE; + return TRUE; } FX_BOOL Document::baseURL(OBJ_PROP_PARAMS) @@ -1493,7 +1493,7 @@ FX_BOOL Document::layout(OBJ_PROP_PARAMS) FX_BOOL Document::addLink(OBJ_METHOD_PARAMS) { - return TRUE; + return TRUE; } FX_BOOL Document::closeDoc(OBJ_METHOD_PARAMS) @@ -1509,13 +1509,13 @@ FX_BOOL Document::closeDoc(OBJ_METHOD_PARAMS) FX_BOOL Document::getPageBox(OBJ_METHOD_PARAMS) { - return TRUE; + return TRUE; } FX_BOOL Document::getAnnot(OBJ_METHOD_PARAMS) { - return TRUE; + return TRUE; } FX_BOOL Document::getAnnots(OBJ_METHOD_PARAMS) diff --git a/fpdfsdk/src/javascript/app.cpp b/fpdfsdk/src/javascript/app.cpp index a3e61c01ab..3b92a992d9 100644 --- a/fpdfsdk/src/javascript/app.cpp +++ b/fpdfsdk/src/javascript/app.cpp @@ -886,15 +886,15 @@ FX_BOOL app::browseForDoc(OBJ_METHOD_PARAMS) { JSObject pObj = (JSObject )params[0]; - v8::Handle pValue = JS_GetObjectElement(isolate,pObj,L"bSave"); - bSave = (bool)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)); - + v8::Handle pValue = JS_GetObjectElement(isolate,pObj,L"bSave"); + bSave = (bool)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)); + pValue = JS_GetObjectElement(isolate, pObj,L"cFilenameInit"); { CJS_Value t = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)); - cFilenameInit = t.operator CFX_ByteString(); + cFilenameInit = t.operator CFX_ByteString(); } - + pValue = JS_GetObjectElement(isolate,pObj,L"cFSInit"); { CJS_Value t = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)); @@ -1097,25 +1097,23 @@ FX_BOOL app::response(OBJ_METHOD_PARAMS) } CJS_Context* pContext = (CJS_Context *)cc; - ASSERT(pContext != NULL); + ASSERT(pContext != NULL); CPDFDoc_Environment* pApp = pContext->GetReaderApp(); - ASSERT(pApp != NULL); + ASSERT(pApp != NULL); int nLength = 2048; char* pBuff = new char[nLength]; nLength = pApp->JS_appResponse(swQuestion, swTitle, swDefault, swLabel, bPassWord, pBuff, nLength); if(nLength<=0) { + delete[] pBuff; vRet.SetNull(); return FALSE; } else { - nLength = nLength>2046?2046:nLength; - pBuff[nLength] = 0; - pBuff[nLength+1] = 0; - swResponse = CFX_WideString::FromUTF16LE((unsigned short*)pBuff, nLength); - vRet = swResponse; + nLength = nLength > sizeof(pBuff) ? sizeof(pBuff) : nLength; + vRet = swResponse = CFX_WideString::FromUTF16LE((unsigned short*)pBuff, nLength / 2); } delete[] pBuff; diff --git a/fpdfsdk/src/jsapi/fxjs_v8.cpp b/fpdfsdk/src/jsapi/fxjs_v8.cpp index f2336ab2fc..5eb9873f5c 100644 --- a/fpdfsdk/src/jsapi/fxjs_v8.cpp +++ b/fpdfsdk/src/jsapi/fxjs_v8.cpp @@ -734,7 +734,7 @@ CFX_WideString JS_ToString(v8::Handle pValue) { if(pValue.IsEmpty()) return L""; v8::String::Utf8Value s(pValue->ToString()); - return CFX_WideString::FromUTF8(*s); + return CFX_WideString::FromUTF8(*s, s.length()); } v8::Handle JS_ToArray(v8::Handle pValue) -- cgit v1.2.3