]> git.saurik.com Git - wxWidgets.git/commitdiff
Forward port test case that corrupts archives to see if they can crash an input stream.
authorMichael Wetherell <mike.wetherell@ntlworld.com>
Sun, 24 Sep 2006 11:52:53 +0000 (11:52 +0000)
committerMichael Wetherell <mike.wetherell@ntlworld.com>
Sun, 24 Sep 2006 11:52:53 +0000 (11:52 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41411 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

tests/archive/archivetest.cpp
tests/archive/archivetest.h

index 4550f7b9afe5b18139652df5f82d7819a342bf48..dc75506136916635f41091192d40c87d2a11fb06 100644 (file)
@@ -216,6 +216,8 @@ void TestInputStream::Rewind()
         m_wbacksize = 0;
         m_wbackcur = 0;
     }
+
+    Reset();
 }
 
 void TestInputStream::SetData(TestOutputStream& out)
@@ -224,7 +226,6 @@ void TestInputStream::SetData(TestOutputStream& out)
     m_options = out.GetOptions();
     out.GetData(m_data, m_size);
     Rewind();
-    Reset();
 }
 
 wxFileOffset TestInputStream::OnSysSeek(wxFileOffset pos, wxSeekMode mode)
@@ -1168,6 +1169,90 @@ void ArchiveTestCase<ClassFactoryT>::OnSetNotifier(EntryT& entry)
 }
 
 
+///////////////////////////////////////////////////////////////////////////////
+// An additional case to check that reading corrupt archives doesn't crash
+
+class CorruptionTestCase : public CppUnit::TestCase
+{
+public:
+    CorruptionTestCase(std::string name,
+                       wxArchiveClassFactory *factory,
+                       int options)
+      : CppUnit::TestCase(TestId::MakeId() + name),
+        m_factory(factory),
+        m_options(options)
+    { }
+
+protected:
+    // the entry point for the test
+    void runTest();
+
+    void CreateArchive(wxOutputStream& out);
+    void ExtractArchive(wxInputStream& in);
+
+    auto_ptr<wxArchiveClassFactory> m_factory;  // factory to make classes
+    int m_options;                              // test options
+};
+
+void CorruptionTestCase::runTest()
+{
+    TestOutputStream out(m_options);
+    CreateArchive(out);
+    TestInputStream in(out, 0);
+    wxFileOffset len = in.GetLength();
+
+    // try flipping one byte in the archive
+    for (int pos = 0; pos < len; pos++) {
+        char n = in[pos];
+        in[pos] = ~n;
+        ExtractArchive(in);
+        in.Rewind();
+        in[pos] = n;
+    }
+
+    // try zeroing one byte in the archive
+    for (int pos = 0; pos < len; pos++) {
+        char n = in[pos];
+        in[pos] = 0;
+        ExtractArchive(in);
+        in.Rewind();
+        in[pos] = n;
+    }
+
+    // try chopping the archive off
+    for (int size = 1; size <= len; size++) {
+        in.Chop(size);
+        ExtractArchive(in);
+        in.Rewind();
+    }
+}
+
+void CorruptionTestCase::CreateArchive(wxOutputStream& out)
+{
+    auto_ptr<wxArchiveOutputStream> arc(m_factory->NewStream(out));
+
+    arc->PutNextDirEntry(_T("dir"));
+    arc->PutNextEntry(_T("file"));
+    arc->Write(_T("foo"), 3);
+}
+
+void CorruptionTestCase::ExtractArchive(wxInputStream& in)
+{
+    auto_ptr<wxArchiveInputStream> arc(m_factory->NewStream(in));
+    auto_ptr<wxArchiveEntry> entry(arc->GetNextEntry());
+        
+    while (entry.get() != NULL) {
+        wxString name = entry->GetName();
+        char buf[1024];
+        
+        while (arc->IsOk())
+            arc->Read(buf, sizeof(buf));
+
+        entry = auto_ptr<wxArchiveEntry>(arc->GetNextEntry());
+    }
+}
+
+
 ///////////////////////////////////////////////////////////////////////////////
 // Make the ids
 
@@ -1177,7 +1262,7 @@ int TestId::m_seed = 6219;
 string TestId::MakeId()
 {
     m_seed = (m_seed * 171) % 30269;
-    return (const char *)wxString::Format(_T("%-6d"), m_seed).mb_str();
+    return string(wxString::Format(_T("%-6d"), m_seed).mb_str());
 }
 
 
@@ -1240,6 +1325,23 @@ ArchiveTestSuite *ArchiveTestSuite::makeSuite()
                         addTest(test);
                 }
 
+    for (int options = 0; options <= PipeIn; options += PipeIn) 
+    {
+        wxObject *pObj = wxCreateDynamicObject(m_name + _T("ClassFactory"));
+        wxArchiveClassFactory *factory;
+        factory = wxDynamicCast(pObj, wxArchiveClassFactory);
+
+        if (factory) {
+            string descr(m_name.mb_str());
+            descr = "CorruptionTestCase (" + descr + ")";
+
+            if (options)
+                descr += " (PipeIn)";
+
+            addTest(new CorruptionTestCase(descr, factory, options));
+        }
+    }
+
     return this;
 }
 
@@ -1290,7 +1392,7 @@ string ArchiveTestSuite::Description(const wxString& type,
 
     descr << optstr;
 
-    return (const char*)descr.mb_str();
+    return string(descr.mb_str());
 }
 
 
index 69dbd9520fee89285ce5bb93a8da5ad0766191e9..0d24a105f645d27ca1cfb8cdd8f3ec5da7f8e00f 100644 (file)
@@ -79,6 +79,9 @@ public:
     bool IsSeekable() const { return (m_options & PipeIn) == 0; }
     void SetData(TestOutputStream& out);
 
+    void Chop(size_t size) { m_size = size; }
+    char& operator [](size_t pos) { return m_data[pos]; }
+
 private:
     wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
     wxFileOffset OnSysTell() const;