[open-ils-commits] r12297 - trunk/Open-ILS/src/c-apps (scottmk)

svn at svn.open-ils.org svn at svn.open-ils.org
Wed Feb 25 11:00:06 EST 2009


Author: scottmk
Date: 2009-02-25 11:00:05 -0500 (Wed, 25 Feb 2009)
New Revision: 12297

Modified:
   trunk/Open-ILS/src/c-apps/oils_cstore.c
Log:
In SELECT(): Enhanced the validation of JSON queries:

1. If the FROM clause is the wrong sort of jsonObject, issue
a helpful message before bailing out.

2. If a class in the SELECT clause is not defined in the IDL,
issue a message and bail out (instead of silently ignoring it).

3. If a selected item is represented by anything but a 
JSON_STRING or JSON_HASH, issue a message and bail out
(instead of creating a query that bombs out later due to an
extra comma).


Modified: trunk/Open-ILS/src/c-apps/oils_cstore.c
===================================================================
--- trunk/Open-ILS/src/c-apps/oils_cstore.c	2009-02-25 13:36:27 UTC (rev 12296)
+++ trunk/Open-ILS/src/c-apps/oils_cstore.c	2009-02-25 16:00:05 UTC (rev 12297)
@@ -75,6 +75,7 @@
 static char* getSourceDefinition( osrfHash* );
 static int str_is_true( const char* str );
 static int obj_is_true( const jsonObject* obj );
+static const char* json_type( int code );
 
 #ifdef PCRUD
 static jsonObject* verifyUserPCRUD( osrfMethodContext* );
@@ -2480,8 +2481,24 @@
 		core_class = jsonObjectToSimpleString( join_hash );
 		join_hash = NULL;
 	}
-	else
+	else {
+		osrfLogError(
+			OSRF_LOG_MARK,
+			"%s: FROM clause is unexpected JSON type: %s",
+			MODULENAME,
+			json_type( join_hash->type )
+		);
+		if( ctx )
+			osrfAppSessionStatus(
+				ctx->session,
+				OSRF_STATUS_INTERNALSERVERERROR,
+				"osrfMethodException",
+				ctx->request,
+				"Ill-formed FROM clause in JSON query"
+			);
+		free( core_class );
 		return NULL;
+	}
 
 	if (!from_function) {
 		// Get the IDL class definition for the core class
@@ -2532,33 +2549,11 @@
 		selhash = defaultselhash = jsonNewObjectType(JSON_HASH);
 		jsonObjectSetKey( selhash, core_class, jsonNewObjectType(JSON_ARRAY) );
 	} else if( selhash->type != JSON_HASH ) {
-		const char* json_type;
-		switch ( selhash->type )
-		{
-			case 1 :
-				json_type = "JSON_ARRAY";
-				break;
-			case 2 :
-				json_type = "JSON_STRING";
-				break;
-			case 3 :
-				json_type = "JSON_NUMBER";
-				break;
-			case 4 :
-				json_type = "JSON_NULL";
-				break;
-			case 5 :
-				json_type = "JSON_BOOL";
-				break;
-			default :
-				json_type = "(unrecognized)";
-				break;
-		}
 		osrfLogError(
 			OSRF_LOG_MARK,
 			"%s: Expected JSON_HASH for SELECT clause; found %s",
 			MODULENAME,
-			json_type
+			json_type( selhash->type )
 		);
 
 		if (ctx)
@@ -2619,13 +2614,36 @@
 	    jsonIterator* selclass_itr = jsonNewIterator( selhash );
 	    while ( (selclass = jsonIteratorNext( selclass_itr )) ) {    // For each class
 
-		    // round trip through the idl, just to be safe
+		    // Make sure the class is defined in the IDL
 			const char* cname = selclass_itr->key;
 			osrfHash* idlClass = osrfHashGet( oilsIDL(), cname );
-		    if (!idlClass)
-				// No such class.  Skip it.
-				continue;
+		    if (!idlClass) {
+				osrfLogError(
+					OSRF_LOG_MARK,
+					"%s: Selected class \"%s\" not defined in IDL",
+					MODULENAME,
+					cname
+				);
 
+				if (ctx)
+					osrfAppSessionStatus(
+						ctx->session,
+						OSRF_STATUS_INTERNALSERVERERROR,
+						"osrfMethodException",
+						ctx->request,
+						"Selected class is not defined"
+					);
+				jsonIteratorFree( selclass_itr );
+				jsonObjectFree( is_agg );
+				buffer_free( sql_buf );
+				buffer_free( select_buf );
+				buffer_free( order_buf );
+				buffer_free( group_buf );
+				buffer_free( having_buf );
+				free( core_class );
+				return NULL;
+			}
+
 		    // Make sure the target relation is in the join tree.
 			
 			// At this point join_hash is a step down from the join_hash we
@@ -2694,8 +2712,8 @@
 			// Look up some attributes of the current class, so that we 
 			// don't have to look them up again for each field
 			osrfHash* class_field_set = osrfHashGet( idlClass, "fields" );
-			char* class_pkey = osrfHashGet( idlClass, "primarykey" );
-			char* class_tname = osrfHashGet( idlClass, "tablename" );
+			const char* class_pkey = osrfHashGet( idlClass, "primarykey" );
+			const char* class_tname = osrfHashGet( idlClass, "tablename" );
 			
 		    // stitch together the column list ...
 		    jsonIterator* select_itr = jsonNewIterator( selclass );
@@ -2735,7 +2753,7 @@
                     }
 					
 				// ... but it could be an object, in which case we check for a Field Transform
-				} else {
+				} else if (selfield->type == JSON_HASH) {
 
 					char* col_name = jsonObjectToSimpleString( jsonObjectGetKeyConst( selfield, "column" ) );
 
@@ -2780,6 +2798,32 @@
 					    free(_alias);
 					free( col_name );
 			    }
+				else {
+					osrfLogError(
+						OSRF_LOG_MARK,
+						"%s: Selected item is unexpected JSON type: %s",
+						MODULENAME,
+						json_type( selfield->type )
+					);
+					if( ctx )
+						osrfAppSessionStatus(
+							ctx->session,
+							OSRF_STATUS_INTERNALSERVERERROR,
+							"osrfMethodException",
+							ctx->request,
+							"Ill-formed SELECT item in JSON query"
+						);
+					jsonIteratorFree( select_itr );
+					jsonIteratorFree( selclass_itr );
+					jsonObjectFree( is_agg );
+					buffer_free( sql_buf );
+					buffer_free( select_buf );
+					buffer_free( order_buf );
+					buffer_free( group_buf );
+					buffer_free( having_buf );
+					free( core_class );
+					return NULL;
+				}
 
 			    if (is_agg->size || (flags & SELECT_DISTINCT)) {
 
@@ -4240,3 +4284,25 @@
 			return 0;
 	}
 }
+
+// Translate a numeric code into a text string identifying a type of
+// jsonObject.  To be used for building error messages.
+static const char* json_type( int code ) {
+	switch ( code )
+	{
+		case 0 :
+			return "JSON_HASH";
+		case 1 :
+			return "JSON_ARRAY";
+		case 2 :
+			return "JSON_STRING";
+		case 3 :
+			return "JSON_NUMBER";
+		case 4 :
+			return "JSON_NULL";
+		case 5 :
+			return "JSON_BOOL";
+		default :
+			return "(unrecognized)";
+	}
+}



More information about the open-ils-commits mailing list