diff options
author | Artem Strygin <art-snake@yandex-team.ru> | 2017-08-09 18:50:59 +0300 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-08-09 16:10:23 +0000 |
commit | d24b97ee1d065eff482355ea3ff82be59bb528b1 (patch) | |
tree | a736ae139525dddf6f1c62a1669d79d405782fea /core/fpdfapi/edit | |
parent | e13c4f887201e3cce33f927bfd6467e8e0263ea7 (diff) | |
download | pdfium-d24b97ee1d065eff482355ea3ff82be59bb528b1.tar.xz |
Unify of saving documents.chromium/3181
In the original code the method of writing of objects depends on a much unpredictable factors:
as:
1) Is there an updated version of the at least one object in the document.
2) The password is changed.
3) Was this object loaded earlier.
4) The Object is compressed and document have a password.
With these factors it is difficult to predict what will be the final file.
To reduce volatility use only one method that works in all cases mentioned.
This method is parse then serialize.
Change-Id: I3d7dcadd10abffbad68d1f993f2dd60b039ed989
Reviewed-on: https://pdfium-review.googlesource.com/9572
Commit-Queue: Art Snake <art-snake@yandex-team.ru>
Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'core/fpdfapi/edit')
-rw-r--r-- | core/fpdfapi/edit/cpdf_creator.cpp | 35 | ||||
-rw-r--r-- | core/fpdfapi/edit/cpdf_creator_embeddertest.cpp | 43 |
2 files changed, 51 insertions, 27 deletions
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp index b347d45dce..9735460f41 100644 --- a/core/fpdfapi/edit/cpdf_creator.cpp +++ b/core/fpdfapi/edit/cpdf_creator.cpp @@ -323,34 +323,15 @@ bool CPDF_Creator::WriteOldIndirectObject(uint32_t objnum) { m_ObjectOffsets[objnum] = m_Archive->CurrentOffset(); bool bExistInMap = !!m_pDocument->GetIndirectObject(objnum); - const CPDF_Parser::ObjectType object_type = m_pParser->GetObjectType(objnum); - if (m_pParser->IsVersionUpdated() || m_bSecurityChanged || bExistInMap || - (object_type == CPDF_Parser::ObjectType::kCompressed && m_pEncryptDict)) { - CPDF_Object* pObj = m_pDocument->GetOrParseIndirectObject(objnum); - if (!pObj) { - m_ObjectOffsets.erase(objnum); - return true; - } - if (!WriteIndirectObj(pObj->GetObjNum(), pObj)) - return false; - if (!bExistInMap) - m_pDocument->DeleteIndirectObject(objnum); - } else { - std::vector<uint8_t> buffer = m_pParser->GetIndirectBinary(objnum); - if (buffer.empty()) - return true; - if (object_type == CPDF_Parser::ObjectType::kCompressed) { - if (!m_Archive->WriteDWord(objnum) || - !m_Archive->WriteString(" 0 obj ") || - !m_Archive->WriteBlock(buffer.data(), buffer.size()) || - !m_Archive->WriteString("\r\nendobj\r\n")) { - return false; - } - } else { - if (!m_Archive->WriteBlock(buffer.data(), buffer.size())) - return false; - } + CPDF_Object* pObj = m_pDocument->GetOrParseIndirectObject(objnum); + if (!pObj) { + m_ObjectOffsets.erase(objnum); + return true; } + if (!WriteIndirectObj(pObj->GetObjNum(), pObj)) + return false; + if (!bExistInMap) + m_pDocument->DeleteIndirectObject(objnum); return true; } diff --git a/core/fpdfapi/edit/cpdf_creator_embeddertest.cpp b/core/fpdfapi/edit/cpdf_creator_embeddertest.cpp new file mode 100644 index 0000000000..def7d50a97 --- /dev/null +++ b/core/fpdfapi/edit/cpdf_creator_embeddertest.cpp @@ -0,0 +1,43 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <string> +#include <vector> + +#include "core/fxcrt/fx_system.h" +#include "public/fpdf_annot.h" +#include "public/fpdf_edit.h" +#include "public/fpdfview.h" +#include "testing/embedder_test.h" +#include "testing/gtest/include/gtest/gtest.h" + +class CPDF_CreatorEmbedderTest : public EmbedderTest {}; + +TEST_F(CPDF_CreatorEmbedderTest, SavedDocsAreEqualAfterParse) { + ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf")); + // Save without additional data reading. + EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0)); + const std::string saved_doc_1 = GetString(); + ClearString(); + + { + // Do some read only operations. + ASSERT_GE(1, FPDF_GetPageCount(document())); + FPDF_PAGE page = FPDF_LoadPage(document(), 0); + ASSERT_TRUE(page); + FPDF_BITMAP new_bitmap = + RenderPageWithFlags(page, form_handle(), FPDF_ANNOT); + FPDFBitmap_Destroy(new_bitmap); + UnloadPage(page); + } + + // Save when we have additional loaded data. + EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0)); + const std::string saved_doc_2 = GetString(); + ClearString(); + + // The sizes of saved docs should be equal. + EXPECT_EQ(saved_doc_1.size(), saved_doc_2.size()); +} |