@@ -187,7 +187,8 @@ static int yajl_start_array(void *ctx) {
187187 msr -> json -> current_depth ++ ;
188188 if (msr -> json -> current_depth > msr -> txcfg -> reqbody_json_depth_limit ) {
189189 msr -> json -> depth_limit_exceeded = 1 ;
190- return 0 ;
190+ msr -> json -> yajl_error = apr_psprintf (msr -> mp , "More than %d JSON nesting" , msr -> txcfg -> reqbody_json_depth_limit );
191+ return 0 ;
191192 }
192193
193194 if (msr -> txcfg -> debuglog_level >= 9 ) {
@@ -312,6 +313,16 @@ static int yajl_end_map(void *ctx)
312313 return 1 ;
313314}
314315
316+ static void * yajl_fmalloc (void * ctx , size_t sz )
317+ {
318+ assert (ctx != NULL );
319+ return apr_palloc ((apr_pool_t * )ctx , sz );
320+ }
321+ static void yajl_ffree (void * ctx , void * p )
322+ {
323+ assert (ctx != NULL );
324+ }
325+
315326/**
316327 * Initialise JSON parser.
317328 */
@@ -375,23 +386,21 @@ int json_process_chunk(modsec_rec *msr, const char *buf, unsigned int size, char
375386 assert (msr -> json != NULL );
376387 assert (error_msg != NULL );
377388 * error_msg = NULL ;
378- base_offset = buf ;
389+ // Take a copy in case libyajl decodes the buffer inline
390+ base_offset = apr_pstrmemdup (msr -> mp , buf , size );
391+ if (!base_offset ) return -1 ;
379392
380393 /* Feed our parser and catch any errors */
381- msr -> json -> status = yajl_parse (msr -> json -> handle , buf , size );
394+ msr -> json -> status = yajl_parse (msr -> json -> handle , ( unsigned char * ) base_offset , size );
382395 if (msr -> json -> status != yajl_status_ok ) {
383- if (msr -> json -> depth_limit_exceeded ) {
384- * error_msg = "JSON depth limit exceeded" ;
385- } else {
386396 if (msr -> json -> yajl_error ) * error_msg = msr -> json -> yajl_error ;
387397 else {
388- char * yajl_err = yajl_get_error (msr -> json -> handle , 0 , buf , size );
389- * error_msg = apr_pstrdup (msr -> mp , yajl_err );
390- yajl_free_error (msr -> json -> handle , yajl_err );
398+ char * yajl_err = yajl_get_error (msr -> json -> handle , 0 , base_offset , size );
399+ * error_msg = apr_pstrdup (msr -> mp , yajl_err );
400+ yajl_free_error (msr -> json -> handle , yajl_err );
391401 }
392- }
393402 return -1 ;
394- }
403+ }
395404
396405 return 1 ;
397406}
@@ -404,18 +413,19 @@ int json_complete(modsec_rec *msr, char **error_msg) {
404413 assert (msr -> json != NULL );
405414 assert (error_msg != NULL );
406415
416+ if (error_msg == NULL ) return -1 ;
407417 * error_msg = NULL ;
408418
409419 /* Wrap up the parsing process */
410420 msr -> json -> status = yajl_complete_parse (msr -> json -> handle );
411421 if (msr -> json -> status != yajl_status_ok ) {
412- if (msr -> json -> depth_limit_exceeded ) {
413- * error_msg = "JSON depth limit exceeded" ;
422+ if (msr -> json -> depth_limit_exceeded ) {
423+ * error_msg = "JSON depth limit exceeded" ;
414424 } else {
415- char * yajl_err = yajl_get_error (msr -> json -> handle , 0 , NULL , 0 );
416- * error_msg = apr_pstrdup (msr -> mp , yajl_err );
417- yajl_free_error (msr -> json -> handle , yajl_err );
418- }
425+ char * yajl_err = yajl_get_error (msr -> json -> handle , 0 , NULL , 0 );
426+ * error_msg = apr_pstrdup (msr -> mp , yajl_err );
427+ yajl_free_error (msr -> json -> handle , yajl_err );
428+ }
419429
420430 return -1 ;
421431 }
0 commit comments