cid#1640468 Dereference after null check
[LibreOffice.git] / package / qa / cppunit / test_package.cxx
blob989ae31044d5644bff30ef6386f61c712c7be349
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <comphelper/processfactory.hxx>
11 #include <unotest/filters-test.hxx>
12 #include <unotest/bootstrapfixturebase.hxx>
13 #include <comphelper/threadpool.hxx>
14 #include <com/sun/star/packages/zip/ZipFileAccess.hpp>
15 #include <com/sun/star/beans/NamedValue.hpp>
17 #include <iterator>
19 using namespace ::com::sun::star;
21 namespace
23 class PackageTest
24 : public test::FiltersTest
25 , public test::BootstrapFixtureBase
27 public:
28 PackageTest() {}
30 virtual void setUp() override;
32 virtual bool load(const OUString &,
33 const OUString &rURL, const OUString &,
34 SfxFilterFlags, SotClipboardFormatId, unsigned int) override;
36 void test();
37 void testThreadedStreams();
38 void testBufferedThreadedStreams();
39 void testZip64();
41 CPPUNIT_TEST_SUITE(PackageTest);
42 CPPUNIT_TEST(test);
43 CPPUNIT_TEST(testThreadedStreams);
44 CPPUNIT_TEST(testBufferedThreadedStreams);
45 CPPUNIT_TEST(testZip64);
46 CPPUNIT_TEST_SUITE_END();
48 private:
49 uno::Reference<container::XNameAccess> mxNA;
50 void verifyStreams( std::vector<std::vector<char>> &aBuffers );
53 void PackageTest::setUp()
55 BootstrapFixtureBase::setUp();
56 OUString aURL = m_directories.getURLFromSrc(u"/package/qa/cppunit/data/a2z.zip");
58 uno::Sequence<beans::NamedValue> aNVs{ { u"URL"_ustr, uno::Any(aURL) } };
59 uno::Sequence<uno::Any> aArgs{ uno::Any(aNVs) };
61 uno::Reference<uno::XComponentContext> xCxt = comphelper::getProcessComponentContext();
62 uno::Reference<lang::XMultiComponentFactory> xSvcMgr = xCxt->getServiceManager();
64 uno::Reference<packages::zip::XZipFileAccess2> xZip(
65 xSvcMgr->createInstanceWithArgumentsAndContext(
66 u"com.sun.star.packages.zip.ZipFileAccess"_ustr, aArgs, xCxt),
67 uno::UNO_QUERY);
69 CPPUNIT_ASSERT(xZip.is());
71 mxNA = xZip;
72 CPPUNIT_ASSERT(mxNA.is());
75 bool PackageTest::load(const OUString &,
76 const OUString &rURL, const OUString &,
77 SfxFilterFlags, SotClipboardFormatId, unsigned int)
79 try
81 uno::Reference<css::packages::zip::XZipFileAccess2> xZip(
82 css::packages::zip::ZipFileAccess::createWithURL(comphelper::getProcessComponentContext(), rURL));
83 return xZip.is();
85 catch(...)
87 return false;
91 void PackageTest::test()
93 testDir(OUString(),
94 m_directories.getURLFromSrc(u"/package/qa/cppunit/data/"));
97 void PackageTest::verifyStreams( std::vector<std::vector<char>> &aBuffers )
99 CPPUNIT_ASSERT_EQUAL(size_t(26), aBuffers.size());
100 auto itBuf = aBuffers.begin();
102 for (char c = 'a'; c <= 'z'; ++c, ++itBuf)
104 const std::vector<char>& rBuf = *itBuf;
105 CPPUNIT_ASSERT_EQUAL(size_t(1048576), rBuf.size()); // 1 MB each.
106 for (char check : rBuf)
107 if (c != check)
108 CPPUNIT_ASSERT_MESSAGE("stream does not contain expected data", false);
112 // TODO : This test currently doesn't fail even when you set
113 // UseBufferedStream to false. Look into this and replace it with a better
114 // test that actually fails when the aforementioned flag is set to false.
115 void PackageTest::testThreadedStreams()
117 class Worker : public comphelper::ThreadTask
119 uno::Reference<io::XInputStream> mxStrm;
120 std::vector<char>& mrBuf;
122 public:
123 Worker(
124 const std::shared_ptr<comphelper::ThreadTaskTag>& pTag,
125 const uno::Reference<io::XInputStream>& xStrm,
126 std::vector<char>& rBuf ) :
127 comphelper::ThreadTask(pTag), mxStrm(xStrm), mrBuf(rBuf) {}
129 virtual void doWork() override
131 sal_Int32 nSize = mxStrm->available();
133 uno::Sequence<sal_Int8> aBytes;
134 while (nSize > 0)
136 sal_Int32 nBytesRead = mxStrm->readBytes(aBytes, 4096);
137 const sal_Int8* p = aBytes.getArray();
138 const sal_Int8* pEnd = p + nBytesRead;
139 std::copy(p, pEnd, std::back_inserter(mrBuf));
140 nSize -= nBytesRead;
146 comphelper::ThreadPool aPool(4);
147 std::shared_ptr<comphelper::ThreadTaskTag> pTag = comphelper::ThreadPool::createThreadTaskTag();
149 std::vector<std::vector<char>> aTestBuffers(26);
150 auto itBuf = aTestBuffers.begin();
152 for (char c = 'a'; c <= 'z'; ++c, ++itBuf)
154 OUString aName = OUStringChar(c) + ".txt";
156 uno::Reference<io::XInputStream> xStrm;
157 mxNA->getByName(aName) >>= xStrm;
159 CPPUNIT_ASSERT(xStrm.is());
160 aPool.pushTask(std::make_unique<Worker>(pTag, xStrm, *itBuf));
163 aPool.waitUntilDone(pTag);
164 verifyStreams( aTestBuffers );
168 void PackageTest::testBufferedThreadedStreams()
170 std::vector<std::vector<char>> aTestBuffers(26);
171 auto itBuf = aTestBuffers.begin();
172 sal_Int32 nReadSize = 0;
174 for (char c = 'a'; c <= 'z'; ++c, ++itBuf)
176 itBuf->reserve(1024*1024);
177 OUString aName = OUStringChar(c) + ".txt";
179 uno::Reference<io::XInputStream> xStrm;
180 //Size of each stream is 1mb (>10000) => XBufferedThreadedStream
181 mxNA->getByName(aName) >>= xStrm;
183 CPPUNIT_ASSERT(xStrm.is());
184 sal_Int32 nSize = xStrm->available();
186 uno::Sequence<sal_Int8> aBytes;
187 //Read chunks of increasing size
188 nReadSize += 1024;
190 while (nSize > 0)
192 sal_Int32 nBytesRead = xStrm->readBytes(aBytes, nReadSize);
193 const sal_Int8* p = aBytes.getArray();
194 const sal_Int8* pEnd = p + nBytesRead;
195 std::copy(p, pEnd, std::back_inserter(*itBuf));
196 nSize -= nBytesRead;
200 verifyStreams( aTestBuffers );
203 void PackageTest::testZip64()
205 // This small zip file have 2 files (content.xml, styles.xml) that have
206 // Zip64 Extended Information Extra Field in both
207 // "Local file header" and "Central directory file header",
208 // and have ZIP64 format "Data descriptor".
209 OUString aURL2 = m_directories.getURLFromSrc(u"/package/qa/cppunit/data/export64.zip");
211 uno::Sequence<beans::NamedValue> aNVs2{ { u"URL"_ustr, uno::Any(aURL2) } };
212 uno::Sequence<uno::Any> aArgs2{ uno::Any(aNVs2) };
214 uno::Reference<uno::XComponentContext> xCxt = comphelper::getProcessComponentContext();
215 uno::Reference<lang::XMultiComponentFactory> xSvcMgr = xCxt->getServiceManager();
217 // Without Zip64 support, it would crash here
218 uno::Reference<packages::zip::XZipFileAccess2> xZip2(
219 xSvcMgr->createInstanceWithArgumentsAndContext(
220 u"com.sun.star.packages.zip.ZipFileAccess"_ustr, aArgs2, xCxt),
221 uno::UNO_QUERY);
223 CPPUNIT_ASSERT(xZip2.is());
225 uno::Reference<container::XNameAccess> xNA;
226 xNA = xZip2;
227 CPPUNIT_ASSERT(xNA.is());
229 // Check if the styles.xml seems to be right
230 uno::Reference<io::XInputStream> xStrm;
231 xNA->getByName(u"styles.xml"_ustr) >>= xStrm;
232 CPPUNIT_ASSERT(xStrm.is());
233 // Filesize check
234 sal_Int32 nSize = xStrm->available();
235 CPPUNIT_ASSERT_EQUAL(sal_Int32(1112), nSize);
237 uno::Sequence<sal_Int8> aBytes;
238 sal_Int32 nBytesRead = xStrm->readBytes(aBytes, nSize);
239 const sal_Int8* p = aBytes.getArray();
240 CPPUNIT_ASSERT_EQUAL(sal_Int32(1112), nBytesRead);
242 // Check the uncompressed styles.xml file content.
243 OString aFile(static_cast<const char*>(static_cast<const void*>(p)), nSize);
244 CPPUNIT_ASSERT(aFile.startsWith(
245 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<office:document-styles"));
246 CPPUNIT_ASSERT(aFile.endsWith(
247 "</number:time-style>\r\n </office:styles>\r\n</office:document-styles>\r\n"));
250 CPPUNIT_TEST_SUITE_REGISTRATION(PackageTest);
253 CPPUNIT_PLUGIN_IMPLEMENT();
255 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */