Author: sbanacho
Date: Fri Oct 30 02:42:31 2009
New Revision: 831187

URL: http://svn.apache.org/viewvc?rev=831187&view=rev
Log:
AVRO-176. Safeguard against bad istreams before reading.

Modified:
    hadoop/avro/trunk/CHANGES.txt
    hadoop/avro/trunk/src/c++/api/Compiler.hh
    hadoop/avro/trunk/src/c++/api/Exception.hh
    hadoop/avro/trunk/src/c++/api/Schema.hh
    hadoop/avro/trunk/src/c++/impl/Compiler.cc
    hadoop/avro/trunk/src/c++/test/testgen.cc
    hadoop/avro/trunk/src/c++/test/unittest.cc

Modified: hadoop/avro/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/hadoop/avro/trunk/CHANGES.txt?rev=831187&r1=831186&r2=831187&view=diff
==============================================================================
--- hadoop/avro/trunk/CHANGES.txt (original)
+++ hadoop/avro/trunk/CHANGES.txt Fri Oct 30 02:42:31 2009
@@ -10,7 +10,7 @@
 
   IMPROVEMENTS
 
-    AVRO-157. Changes from code review comments for C++.  (sbanacho)
+    AVRO-157. Changes from code review comments for C++. (sbanacho)
 
     AVRO-168. Correct shared library versioning for C implementation (massie)
 
@@ -42,6 +42,8 @@
 
   BUG FIXES
  
+    AVRO-176. Safeguard against bad istreams before reading. (sbanacho)
+
     AVRO-141.  Fix a NullPointerException in ReflectData#isRecord().
     (Isabel Drost via cutting)
 

Modified: hadoop/avro/trunk/src/c++/api/Compiler.hh
URL: 
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c%2B%2B/api/Compiler.hh?rev=831187&r1=831186&r2=831187&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c++/api/Compiler.hh (original)
+++ hadoop/avro/trunk/src/c++/api/Compiler.hh Fri Oct 30 02:42:31 2009
@@ -92,7 +92,18 @@
 
 class ValidSchema;
 
-int compileJsonSchema(std::istream &is, ValidSchema &schema);
+/// Given a stream comtaining a JSON schema, compiles the schema to a
+/// ValidSchema object.  Throws if the schema cannot be compiled to a valid
+/// schema
+
+void compileJsonSchema(std::istream &is, ValidSchema &schema);
+
+/// Non-throwing version of compileJsonSchema.  
+///
+/// /return True if no error, false if error (with the error string set)
+///
+
+bool compileJsonSchema(std::istream &is, ValidSchema &schema, std::string 
&error);
 
 } // namespace avro
 

Modified: hadoop/avro/trunk/src/c++/api/Exception.hh
URL: 
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c%2B%2B/api/Exception.hh?rev=831187&r1=831186&r2=831187&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c++/api/Exception.hh (original)
+++ hadoop/avro/trunk/src/c++/api/Exception.hh Fri Oct 30 02:42:31 2009
@@ -27,7 +27,7 @@
 /// Wrapper for std::runtime_error that provides convenience constructor
 /// for boost::format objects
 
-class Exception : public std::runtime_error
+class Exception : public virtual std::runtime_error
 {
   public:
 

Modified: hadoop/avro/trunk/src/c++/api/Schema.hh
URL: 
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c%2B%2B/api/Schema.hh?rev=831187&r1=831186&r2=831187&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c++/api/Schema.hh (original)
+++ hadoop/avro/trunk/src/c++/api/Schema.hh Fri Oct 30 02:42:31 2009
@@ -54,7 +54,7 @@
 
   protected:
 
-    friend int compileJsonSchema(std::istream &is, ValidSchema &schema);
+    friend void compileJsonSchema(std::istream &is, ValidSchema &schema);
 
     Schema();
     explicit Schema(const NodePtr &node);

Modified: hadoop/avro/trunk/src/c++/impl/Compiler.cc
URL: 
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c%2B%2B/impl/Compiler.cc?rev=831187&r1=831186&r2=831187&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c++/impl/Compiler.cc (original)
+++ hadoop/avro/trunk/src/c++/impl/Compiler.cc Fri Oct 30 02:42:31 2009
@@ -28,17 +28,38 @@
 
 // #define DEBUG_VERBOSE
 
-int
+void
 compileJsonSchema(std::istream &is, ValidSchema &schema)
 {
-     CompilerContext myctx(is);
-     yyparse(&myctx);
+    if(!is.good()) {
+        throw Exception("Input stream is not good");
+    }
 
-     Schema s(myctx.getRoot());
+    CompilerContext myctx(is);
+    yyparse(&myctx);
 
-     schema.setSchema(s);
+    Schema s(myctx.getRoot());
+    schema.setSchema(s);
+}
+
+bool
+compileJsonSchema(std::istream &is, ValidSchema &schema, std::string &error)
+{
+    bool success = false;
+    if(!is.good()) {
+        error = "Input stream is not good";
+        return false;
+    }
+
+    try {
+        compileJsonSchema(is, schema);
+        success = true;
+    }
+    catch (Exception &e) {
+        error = e.what();
+    }
 
-     return 1;
+    return success;
 }
 
 void 

Modified: hadoop/avro/trunk/src/c++/test/testgen.cc
URL: 
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c%2B%2B/test/testgen.cc?rev=831187&r1=831186&r2=831187&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c++/test/testgen.cc (original)
+++ hadoop/avro/trunk/src/c++/test/testgen.cc Fri Oct 30 02:42:31 2009
@@ -111,7 +111,6 @@
         BOOST_CHECK_EQUAL(rec1.myfixed.value[i], rec2.myfixed.value[i]);
     }
     BOOST_CHECK_EQUAL(rec1.anotherint, rec1.anotherint);
-
 }
 
 void testParser(const avrouser::RootRecord &myRecord)
@@ -192,6 +191,8 @@
     myRecord.bytes.push_back(20);
 
     runTests(myRecord);
+
+    std::cout << "Finished code generation tests\n";
 }
 
 boost::unit_test::test_suite*

Modified: hadoop/avro/trunk/src/c++/test/unittest.cc
URL: 
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c%2B%2B/test/unittest.cc?rev=831187&r1=831186&r2=831187&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c++/test/unittest.cc (original)
+++ hadoop/avro/trunk/src/c++/test/unittest.cc Fri Oct 30 02:42:31 2009
@@ -29,6 +29,7 @@
 #include "Serializer.hh"
 #include "Parser.hh"
 #include "SymbolMap.hh"
+#include "Compiler.hh"
 
 #include "AvroSerialize.hh"
 
@@ -509,6 +510,49 @@
     }
 };
 
+struct TestBadStuff
+{
+    void testBadFile() 
+    {
+        std::cout << "TestBadStuff\n";
+
+        avro::ValidSchema schema;
+        std::ifstream in("agjoewejefkjs");
+        std::string error;
+        bool result = avro::compileJsonSchema(in, schema, error);
+        BOOST_CHECK_EQUAL(result, false);
+        std::cout << "(intentional) error: " << error << '\n';
+    }
+
+    void testBadSchema()
+    {
+        std::cout << "TestBadSchema\n";
+
+        std::string str ("{ \"type\" : \"wrong\" }");
+        std::istringstream in(str);
+
+        avro::ValidSchema schema;
+        std::string error;
+        bool result = avro::compileJsonSchema(in, schema, error);
+        BOOST_CHECK_EQUAL(result, false);
+        std::cout << "(intentional) error: " << error << '\n';
+    }
+
+    void test() 
+    {
+        std::cout << "TestBadStuff\n";
+        testBadFile();
+        testBadSchema();
+    }
+};
+
+
+template<typename T>
+void addTestCase(boost::unit_test::test_suite &test) 
+{
+    boost::shared_ptr<T> newtest( new T );
+    test.add( BOOST_CLASS_TEST_CASE( &T::test, newtest ));
+}
 
 boost::unit_test::test_suite*
 init_unit_test_suite( int argc, char* argv[] ) 
@@ -517,20 +561,12 @@
 
     test_suite* test= BOOST_TEST_SUITE( "Avro C++ unit test suite" );
 
-    boost::shared_ptr<TestEncoding> encodingTester( new TestEncoding );
-    test->add( BOOST_CLASS_TEST_CASE( &TestEncoding::test, encodingTester ));
-
-    boost::shared_ptr<TestSchema> schemaTester( new TestSchema );
-    test->add( BOOST_CLASS_TEST_CASE( &TestSchema::test, schemaTester ));
-
-    boost::shared_ptr<TestSymbolMap> symbolMapTester( new TestSymbolMap );
-    test->add( BOOST_CLASS_TEST_CASE( &TestSymbolMap::test, symbolMapTester ));
-
-    boost::shared_ptr<TestNested> nestedTester( new TestNested );
-    test->add( BOOST_CLASS_TEST_CASE( &TestNested::test, nestedTester ));
-
-    boost::shared_ptr<TestGenerated> generatedTester( new TestGenerated );
-    test->add( BOOST_CLASS_TEST_CASE( &TestGenerated::test, generatedTester ));
+    addTestCase<TestEncoding>(*test);
+    addTestCase<TestSchema>(*test);
+    addTestCase<TestSymbolMap>(*test);
+    addTestCase<TestNested>(*test);
+    addTestCase<TestGenerated>(*test);
+    addTestCase<TestBadStuff>(*test);
 
     return test;
 }


Reply via email to