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;
}