You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2011/08/10 21:16:05 UTC
[lucy-commits] svn commit: r1156321 - in /incubator/lucy/trunk:
core/Lucy/Test/Util/TestJson.c core/Lucy/Util/Json.cfh perl/lib/Lucy.pm
Author: marvin
Date: Wed Aug 10 19:16:05 2011
New Revision: 1156321
URL: http://svn.apache.org/viewvc?rev=1156321&view=rev
Log:
Change to_json() and from_json() to set Err_error and return NULL on failure.
Add tests for invalid JSON.
Modified:
incubator/lucy/trunk/core/Lucy/Test/Util/TestJson.c
incubator/lucy/trunk/core/Lucy/Util/Json.cfh
incubator/lucy/trunk/perl/lib/Lucy.pm
Modified: incubator/lucy/trunk/core/Lucy/Test/Util/TestJson.c
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/core/Lucy/Test/Util/TestJson.c?rev=1156321&r1=1156320&r2=1156321&view=diff
==============================================================================
--- incubator/lucy/trunk/core/Lucy/Test/Util/TestJson.c (original)
+++ incubator/lucy/trunk/core/Lucy/Test/Util/TestJson.c Wed Aug 10 19:16:05 2011
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <string.h>
#include "Lucy/Util/ToolSet.h"
#include "Lucy/Test.h"
@@ -32,6 +33,17 @@ S_make_dump() {
return (Obj*)dump;
}
+static void
+test_tolerance(TestBatch *batch) {
+ CharBuf *foo = CB_newf("foo");
+ CharBuf *not_json = Json_to_json((Obj*)foo);
+ TEST_TRUE(batch, not_json == NULL,
+ "to_json returns NULL when fed invalid data type");
+ TEST_TRUE(batch, Err_get_error() != NULL,
+ "to_json sets Err_error when fed invalid data type");
+ DECREF(foo);
+}
+
// Test escapes for control characters ASCII 0-31.
static char* control_escapes[] = {
"\\u0000",
@@ -226,20 +238,59 @@ test_spew_and_slurp(TestBatch *batch) {
DECREF(folder);
}
+static void
+S_verify_bad_syntax(TestBatch *batch, const char *bad, const char *mess) {
+ ZombieCharBuf *has_errors = ZCB_WRAP_STR(bad, strlen(bad));
+ Err_set_error(NULL);
+ Obj *not_json = Json_from_json((CharBuf*)has_errors);
+ TEST_TRUE(batch, not_json == NULL, "from_json returns NULL: %s", mess);
+ TEST_TRUE(batch, Err_get_error() != NULL, "from_json sets Err_error: %s",
+ mess);
+}
+
+static void
+test_syntax_errors(TestBatch *batch) {
+ S_verify_bad_syntax(batch, "[", "unclosed left bracket");
+ S_verify_bad_syntax(batch, "]", "unopened right bracket");
+ S_verify_bad_syntax(batch, "{", "unclosed left curly");
+ S_verify_bad_syntax(batch, "}", "unopened right curly");
+ S_verify_bad_syntax(batch, "{}[]", "two top-level objects");
+ S_verify_bad_syntax(batch, "[1 \"foo\"]", "missing comma in array");
+ S_verify_bad_syntax(batch, "[1, \"foo\",]", "extra comma in array");
+ S_verify_bad_syntax(batch, "{\"1\":1 \"2\":2}", "missing comma in hash");
+ S_verify_bad_syntax(batch, "{\"1\":1,\"2\":2,}", "extra comma in hash");
+ S_verify_bad_syntax(batch, "\"1", "unterminated string");
+ // Tolerated by strtod().
+ // S_verify_bad_syntax(batch, "1. ", "float missing fraction");
+ // S_verify_bad_syntax(batch, "-.3 ", "Number missing integral part");
+ S_verify_bad_syntax(batch, "-. ", "Number missing any digits");
+ S_verify_bad_syntax(batch, "+1.0 ", "float with prepended plus");
+ S_verify_bad_syntax(batch, "\"\\g\"", "invalid char escape");
+ S_verify_bad_syntax(batch, "\"\\uAAAZ\"", "invalid \\u escape");
+}
+
void
TestJson_run_tests() {
- TestBatch *batch = TestBatch_new(92);
+ int num_tests = 94;
+#ifndef LUCY_VALGRIND
+ num_tests += 28; // FIXME: syntax errors leak memory.
+#endif
+ TestBatch *batch = TestBatch_new(num_tests);
+ TestBatch_Plan(batch);
- // Liberalize for testing.
+ // Test tolerance, then liberalize for testing.
+ test_tolerance(batch);
Json_set_tolerant(true);
- TestBatch_Plan(batch);
test_to_and_from(batch);
test_escapes(batch);
test_numbers(batch);
test_spew_and_slurp(batch);
+#ifndef LUCY_VALGRIND
+ test_syntax_errors(batch);
+#endif
+
DECREF(batch);
}
-
Modified: incubator/lucy/trunk/core/Lucy/Util/Json.cfh
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/core/Lucy/Util/Json.cfh?rev=1156321&r1=1156320&r2=1156321&view=diff
==============================================================================
--- incubator/lucy/trunk/core/Lucy/Util/Json.cfh (original)
+++ incubator/lucy/trunk/core/Lucy/Util/Json.cfh Wed Aug 10 19:16:05 2011
@@ -22,15 +22,17 @@ parcel Lucy;
*/
class Lucy::Util::Json inherits Lucy::Object::Obj {
- /** Encode <code>dump</code> as JSON.
+ /** Encode <code>dump</code> as JSON. Returns NULL and sets Err_error on
+ * failure.
*/
- inert incremented CharBuf*
+ inert incremented nullable CharBuf*
to_json(Obj *dump);
/** Decode the supplied JSON and return a data structure made
- * of Hashes, VArrays, and CharBufs.
+ * of Hashes, VArrays, and CharBufs. Returns NULL and sets Err_error on
+ * failure.
*/
- inert incremented Obj*
+ inert incremented nullable Obj*
from_json(CharBuf *json);
/** Encode <code>dump</code> as JSON and attempt to write to the indicated
Modified: incubator/lucy/trunk/perl/lib/Lucy.pm
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/perl/lib/Lucy.pm?rev=1156321&r1=1156320&r2=1156321&view=diff
==============================================================================
--- incubator/lucy/trunk/perl/lib/Lucy.pm (original)
+++ incubator/lucy/trunk/perl/lib/Lucy.pm Wed Aug 10 19:16:05 2011
@@ -577,11 +577,23 @@ sub error {$Lucy::Object::Err::error}
sub to_json {
my ( undef, $dump ) = @_;
- return $json_encoder->encode($dump);
+ my $json = eval { $json_encoder->encode($dump) };
+ if ($@) {
+ my $error = Lucy::Object::Err->new($@);
+ Lucy::Object::Err->set_error($error);
+ return;
+ }
+ return $json;
}
sub from_json {
- return to_clownfish( $json_encoder->decode( $_[1] ) );
+ my $dump = eval { to_clownfish( $json_encoder->decode( $_[1] ) ) };
+ if ($@) {
+ my $error = Lucy::Object::Err->new($@);
+ Lucy::Object::Err->set_error($error);
+ return;
+ }
+ return $dump;
}
sub set_tolerant { $json_encoder->allow_nonref( $_[1] ) }