From 154e18f9a862975abecebe77b8f5fb418418d14c Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Thu, 12 Apr 2018 18:33:55 +0000 Subject: Return pdfium::span from WideString::GetBuffer(). Adds bounds checking "for free", but beware of span outliving a ReleaseBuffer() call. Scoping as such avoids the possibility of using an invalid span (and it is flagged as a lifetime issue). Change-Id: Ica63f4b1429823d0254ec6951aeaeb08160cb93c Reviewed-on: https://pdfium-review.googlesource.com/30310 Reviewed-by: dsinclair Commit-Queue: Tom Sepez --- fxjs/cfxjse_resolveprocessor.cpp | 107 ++++++++++++++++++++------------------- fxjs/xfa/cjx_hostpseudomodel.cpp | 20 ++++---- 2 files changed, 66 insertions(+), 61 deletions(-) (limited to 'fxjs') diff --git a/fxjs/cfxjse_resolveprocessor.cpp b/fxjs/cfxjse_resolveprocessor.cpp index 2ca0838a7f..46163b55fc 100644 --- a/fxjs/cfxjse_resolveprocessor.cpp +++ b/fxjs/cfxjse_resolveprocessor.cpp @@ -499,66 +499,69 @@ int32_t CFXJSE_ResolveProcessor::GetFilter(const WideStringView& wsExpression, WideString& wsName = rnd.m_wsName; WideString& wsCondition = rnd.m_wsCondition; - wchar_t* pNameBuf = wsName.GetBuffer(iLength - nStart); - wchar_t* pConditionBuf = wsCondition.GetBuffer(iLength - nStart); int32_t nNameCount = 0; int32_t nConditionCount = 0; - std::vector stack; - int32_t nType = -1; - const wchar_t* pSrc = wsExpression.unterminated_c_str(); - wchar_t wPrev = 0; - wchar_t wCur; - bool bIsCondition = false; - while (nStart < iLength) { - wCur = pSrc[nStart++]; - if (wCur == '.') { - if (wPrev == '\\') { - pNameBuf[nNameCount - 1] = wPrev = '.'; - continue; + { + // Span's lifetime must end before ReleaseBuffer() below. + pdfium::span pNameBuf = wsName.GetBuffer(iLength - nStart); + pdfium::span pConditionBuf = + wsCondition.GetBuffer(iLength - nStart); + std::vector stack; + int32_t nType = -1; + const wchar_t* pSrc = wsExpression.unterminated_c_str(); + wchar_t wPrev = 0; + wchar_t wCur; + bool bIsCondition = false; + while (nStart < iLength) { + wCur = pSrc[nStart++]; + if (wCur == '.') { + if (wPrev == '\\') { + pNameBuf[nNameCount - 1] = wPrev = '.'; + continue; + } + if (nNameCount == 0) { + rnd.m_dwStyles |= XFA_RESOLVENODE_AnyChild; + continue; + } + + wchar_t wLookahead = nStart < iLength ? pSrc[nStart] : 0; + if (wLookahead != '[' && wLookahead != '(' && nType < 0) + break; } - if (nNameCount == 0) { - rnd.m_dwStyles |= XFA_RESOLVENODE_AnyChild; - continue; + if (wCur == '[' || wCur == '(') { + bIsCondition = true; + } else if (wCur == '.' && nStart < iLength && + (pSrc[nStart] == '[' || pSrc[nStart] == '(')) { + bIsCondition = true; } - - wchar_t wLookahead = nStart < iLength ? pSrc[nStart] : 0; - if (wLookahead != '[' && wLookahead != '(' && nType < 0) - break; - } - if (wCur == '[' || wCur == '(') { - bIsCondition = true; - } else if (wCur == '.' && nStart < iLength && - (pSrc[nStart] == '[' || pSrc[nStart] == '(')) { - bIsCondition = true; - } - if (bIsCondition) - pConditionBuf[nConditionCount++] = wCur; - else - pNameBuf[nNameCount++] = wCur; - - if ((nType == 0 && wCur == ']') || (nType == 1 && wCur == ')') || - (nType == 2 && wCur == '"')) { - nType = stack.empty() ? -1 : stack.back(); - if (!stack.empty()) - stack.pop_back(); - } else if (wCur == '[') { - stack.push_back(nType); - nType = 0; - } else if (wCur == '(') { - stack.push_back(nType); - nType = 1; - } else if (wCur == '"') { - stack.push_back(nType); - nType = 2; + if (bIsCondition) + pConditionBuf[nConditionCount++] = wCur; + else + pNameBuf[nNameCount++] = wCur; + + if ((nType == 0 && wCur == ']') || (nType == 1 && wCur == ')') || + (nType == 2 && wCur == '"')) { + nType = stack.empty() ? -1 : stack.back(); + if (!stack.empty()) + stack.pop_back(); + } else if (wCur == '[') { + stack.push_back(nType); + nType = 0; + } else if (wCur == '(') { + stack.push_back(nType); + nType = 1; + } else if (wCur == '"') { + stack.push_back(nType); + nType = 2; + } + wPrev = wCur; } - wPrev = wCur; + if (!stack.empty()) + return -1; } - if (!stack.empty()) - return -1; - wsName.ReleaseBuffer(nNameCount); - wsName.Trim(); wsCondition.ReleaseBuffer(nConditionCount); + wsName.Trim(); wsCondition.Trim(); rnd.m_uHashName = static_cast(FX_HashCode_GetW(wsName.AsStringView(), false)); diff --git a/fxjs/xfa/cjx_hostpseudomodel.cpp b/fxjs/xfa/cjx_hostpseudomodel.cpp index 6ca431e78d..fe26d3161d 100644 --- a/fxjs/xfa/cjx_hostpseudomodel.cpp +++ b/fxjs/xfa/cjx_hostpseudomodel.cpp @@ -29,16 +29,18 @@ int32_t FilterName(const WideStringView& wsExpression, if (nStart >= iLength) return iLength; - wchar_t* pBuf = wsFilter.GetBuffer(iLength - nStart); int32_t nCount = 0; - const wchar_t* pSrc = wsExpression.unterminated_c_str(); - wchar_t wCur; - while (nStart < iLength) { - wCur = pSrc[nStart++]; - if (wCur == ',') - break; - - pBuf[nCount++] = wCur; + { + // Span's lifetime must end before ReleaseBuffer() below. + pdfium::span pBuf = wsFilter.GetBuffer(iLength - nStart); + const wchar_t* pSrc = wsExpression.unterminated_c_str(); + while (nStart < iLength) { + wchar_t wCur = pSrc[nStart++]; + if (wCur == ',') + break; + + pBuf[nCount++] = wCur; + } } wsFilter.ReleaseBuffer(nCount); wsFilter.Trim(); -- cgit v1.2.3