WideString CFX_V8::ToWideString(v8::Local<v8::Value> pValue) { if (pValue.IsEmpty()) return WideString(); v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext(); v8::MaybeLocal<v8::String> maybe_string = pValue->ToString(context); if (maybe_string.IsEmpty()) return WideString(); v8::String::Utf8Value s(GetIsolate(), maybe_string.ToLocalChecked()); return WideString::FromUTF8(ByteStringView(*s, s.length())); }
TEST(fxstring, FX_UTF8Decode) { EXPECT_EQ(L"", FX_UTF8Decode(ByteStringView())); EXPECT_EQ( L"x" L"\u0080" L"\u00ff" L"\uff2c" L"y", FX_UTF8Decode("x" "\xc2\x80" "\xc3\xbf" "\xef\xbc\xac" "y")); EXPECT_EQ(L"a(A) b() c() d() e().", FX_UTF8Decode("a(\xc2\x41) " // Invalid continuation. "b(\xc2\xc2) " // Invalid continuation. "c(\xc2\xff\x80) " // Invalid continuation. "d(\x80\x80) " // Invalid leading. "e(\xff\x80\x80)" // Invalid leading. ".")); }
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_TransFormWithClip(FPDF_PAGE page, const FS_MATRIX* matrix, const FS_RECTF* clipRect) { if (!matrix && !clipRect) return false; CPDF_Page* pPage = CPDFPageFromFPDFPage(page); if (!pPage) return false; std::ostringstream textBuf; textBuf << "q "; if (clipRect) { CFX_FloatRect rect = CFXFloatRectFromFSRECTF(*clipRect); rect.Normalize(); textBuf << ByteString::Format("%f %f %f %f re W* n ", rect.left, rect.bottom, rect.Width(), rect.Height()); } if (matrix) { textBuf << ByteString::Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f); } CPDF_Dictionary* pPageDict = pPage->GetDict(); CPDF_Object* pContentObj = GetPageContent(pPageDict); if (!pContentObj) return false; CPDF_Document* pDoc = pPage->GetDocument(); if (!pDoc) return false; CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>()); pStream->SetDataFromStringstream(&textBuf); CPDF_Stream* pEndStream = pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>()); pEndStream->SetData(ByteStringView(" Q").span()); if (CPDF_Array* pContentArray = ToArray(pContentObj)) { pContentArray->InsertAt(0, pStream->MakeReference(pDoc)); pContentArray->Add(pEndStream->MakeReference(pDoc)); } else if (pContentObj->IsStream() && !pContentObj->IsInline()) { pContentArray = pDoc->NewIndirect<CPDF_Array>(); pContentArray->Add(pStream->MakeReference(pDoc)); pContentArray->Add(pContentObj->MakeReference(pDoc)); pContentArray->Add(pEndStream->MakeReference(pDoc)); pPageDict->SetFor(pdfium::page_object::kContents, pContentArray->MakeReference(pDoc)); } // Need to transform the patterns as well. CPDF_Dictionary* pRes = pPageDict->GetDictFor(pdfium::page_object::kResources); if (!pRes) return true; CPDF_Dictionary* pPatternDict = pRes->GetDictFor("Pattern"); if (!pPatternDict) return true; CPDF_DictionaryLocker locker(pPatternDict); for (const auto& it : locker) { CPDF_Object* pObj = it.second.get(); if (pObj->IsReference()) pObj = pObj->GetDirect(); CPDF_Dictionary* pDict = nullptr; if (pObj->IsDictionary()) pDict = pObj->AsDictionary(); else if (CPDF_Stream* pObjStream = pObj->AsStream()) pDict = pObjStream->GetDict(); else continue; if (matrix) { CFX_Matrix m = CFXMatrixFromFSMatrix(*matrix); pDict->SetMatrixFor("Matrix", pDict->GetMatrixFor("Matrix") * m); } } return true; }
std::unique_ptr<CPDF_Object> CPDF_StreamParser::ReadNextObject( bool bAllowNestedArray, bool bInArray, uint32_t dwRecursionLevel) { bool bIsNumber; // Must get the next word before returning to avoid infinite loops. GetNextWord(bIsNumber); if (!m_WordSize || dwRecursionLevel > kMaxNestedParsingLevel) return nullptr; if (bIsNumber) { m_WordBuffer[m_WordSize] = 0; return pdfium::MakeUnique<CPDF_Number>( ByteStringView(m_WordBuffer, m_WordSize)); } int first_char = m_WordBuffer[0]; if (first_char == '/') { ByteString name = PDF_NameDecode(ByteStringView(m_WordBuffer + 1, m_WordSize - 1)); return pdfium::MakeUnique<CPDF_Name>(m_pPool, name); } if (first_char == '(') { ByteString str = ReadString(); return pdfium::MakeUnique<CPDF_String>(m_pPool, str, false); } if (first_char == '<') { if (m_WordSize == 1) return pdfium::MakeUnique<CPDF_String>(m_pPool, ReadHexString(), true); auto pDict = pdfium::MakeUnique<CPDF_Dictionary>(m_pPool); while (1) { GetNextWord(bIsNumber); if (m_WordSize == 2 && m_WordBuffer[0] == '>') break; if (!m_WordSize || m_WordBuffer[0] != '/') return nullptr; ByteString key = PDF_NameDecode(ByteStringView(m_WordBuffer + 1, m_WordSize - 1)); std::unique_ptr<CPDF_Object> pObj = ReadNextObject(true, bInArray, dwRecursionLevel + 1); if (!pObj) return nullptr; if (!key.IsEmpty()) pDict->SetFor(key, std::move(pObj)); } return std::move(pDict); } if (first_char == '[') { if ((!bAllowNestedArray && bInArray)) return nullptr; auto pArray = pdfium::MakeUnique<CPDF_Array>(); while (1) { std::unique_ptr<CPDF_Object> pObj = ReadNextObject(bAllowNestedArray, true, dwRecursionLevel + 1); if (pObj) { pArray->Add(std::move(pObj)); continue; } if (!m_WordSize || m_WordBuffer[0] == ']') break; } return std::move(pArray); } if (m_WordSize == 5 && !memcmp(m_WordBuffer, "false", 5)) return pdfium::MakeUnique<CPDF_Boolean>(false); if (m_WordSize == 4) { if (memcmp(m_WordBuffer, "true", 4) == 0) return pdfium::MakeUnique<CPDF_Boolean>(true); if (memcmp(m_WordBuffer, "null", 4) == 0) return pdfium::MakeUnique<CPDF_Null>(); } return nullptr; }