From d5fd881c2a044474b54ddf03b6ab8be8d2b75927 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 24 Jun 2016 20:12:53 +0000 Subject: [PATCH] -handle NULL results --- src/include/gnunet_my_lib.h | 5 +++++ src/my/my.c | 42 +++++++++++++++++++++--------------- src/my/my_result_helper.c | 43 ++++++++++++++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 20 deletions(-) diff --git a/src/include/gnunet_my_lib.h b/src/include/gnunet_my_lib.h index 61fd6459f..6ecff67a0 100644 --- a/src/include/gnunet_my_lib.h +++ b/src/include/gnunet_my_lib.h @@ -246,6 +246,11 @@ struct GNUNET_MY_ResultSpec */ unsigned long mysql_bind_output_length; + /** + * Memory for MySQL to notify us about NULL values. + */ + my_bool is_null; + }; diff --git a/src/my/my.c b/src/my/my.c index ae46a2888..5ca80b63c 100644 --- a/src/my/my.c +++ b/src/my/my.c @@ -75,9 +75,11 @@ GNUNET_MY_exec_prepared (struct GNUNET_MYSQL_Context *mc, if (mysql_stmt_bind_param (stmt, qbind)) { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "my", _("`%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_bind_param", __FILE__, __LINE__, + "mysql_stmt_bind_param", + __FILE__, __LINE__, mysql_stmt_error (stmt)); GNUNET_MYSQL_statements_invalidate (mc); return GNUNET_SYSERR; @@ -85,18 +87,17 @@ GNUNET_MY_exec_prepared (struct GNUNET_MYSQL_Context *mc, if (mysql_stmt_execute (stmt)) { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "my", _("`%s' failed at %s:%d with error: %s\n"), "mysql_stmt_execute", __FILE__, __LINE__, mysql_stmt_error (stmt)); GNUNET_MYSQL_statements_invalidate (mc); return GNUNET_SYSERR; } - GNUNET_MY_cleanup_query (params, qbind); } - return GNUNET_OK; } @@ -125,7 +126,6 @@ GNUNET_MY_cleanup_query (struct GNUNET_MY_QueryParam *qp, * Extract results from a query result according to the given * specification. Always fetches the next row. * - * * @param sh statement that returned results * @param rs specification to extract for * @return @@ -145,12 +145,14 @@ GNUNET_MY_extract_result (struct GNUNET_MYSQL_StatementHandle *sh, stmt = GNUNET_MYSQL_statement_get_stmt (sh); if (NULL == stmt) { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", - ("`%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_bind_result", __FILE__, __LINE__, - mysql_stmt_error (stmt)); + GNUNET_break (0); return GNUNET_SYSERR; } + if (NULL == rs) + { + mysql_stmt_free_result (stmt); + return GNUNET_NO; + } num_fields = 0; for (i=0;NULL != rs[i].pre_conv;i++) @@ -187,25 +189,32 @@ GNUNET_MY_extract_result (struct GNUNET_MYSQL_StatementHandle *sh, } field_off += rp->num_fields; } + if (mysql_stmt_bind_result (stmt, result)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "my", - _("`%s' failed at %s:%d with error: %s\n"), - "mysql_stmt_bind_result", __FILE__, __LINE__, + _("%s failed at %s:%d with error: %s\n"), + "mysql_stmt_bind_result", + __FILE__, __LINE__, mysql_stmt_error (stmt)); return GNUNET_SYSERR; } - +#if TEST_OPTIMIZATION + (void) mysql_stmt_store_result (stmt); +#endif ret = mysql_stmt_fetch (stmt); - if (MYSQL_NO_DATA == ret) + { + mysql_stmt_free_result (stmt); return GNUNET_NO; - if ((0 != ret ) && (MYSQL_DATA_TRUNCATED != ret)) + } + if (1 == ret) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "my", - _("mysql_stmt_fetch failed at %s:%d with error: %s\n"), + _("%s failed at %s:%d with error: %s\n"), + "mysql_stmt_fetch", __FILE__, __LINE__, mysql_stmt_error (stmt)); GNUNET_MY_cleanup_result (rs); @@ -235,7 +244,6 @@ GNUNET_MY_extract_result (struct GNUNET_MYSQL_StatementHandle *sh, field_off += rp->num_fields; } } - mysql_stmt_free_result (stmt); return GNUNET_OK; } diff --git a/src/my/my_result_helper.c b/src/my/my_result_helper.c index a91a24d90..bee6e3304 100644 --- a/src/my/my_result_helper.c +++ b/src/my/my_result_helper.c @@ -46,6 +46,8 @@ pre_extract_varsize_blob (void *cls, results[0].buffer = NULL; results[0].buffer_length = 0; results[0].length = &rs->mysql_bind_output_length; + results[0].is_null = &rs->is_null; + rs->is_null = 0; return GNUNET_OK; } @@ -73,6 +75,8 @@ post_extract_varsize_blob (void *cls, void *buf; size_t size; + if (*results->is_null) + return GNUNET_SYSERR; size = (size_t) rs->mysql_bind_output_length; if (rs->mysql_bind_output_length != size) @@ -169,6 +173,8 @@ pre_extract_fixed_blob (void *cls, results[0].buffer_length = rs->dst_size; results[0].length = &rs->mysql_bind_output_length; results[0].buffer_type = MYSQL_TYPE_BLOB; + results[0].is_null = &rs->is_null; + rs->is_null = 0; return GNUNET_OK; } @@ -194,6 +200,8 @@ post_extract_fixed_blob (void *cls, unsigned int column, MYSQL_BIND *results) { + if (*results->is_null) + return GNUNET_SYSERR; if (rs->dst_size != rs->mysql_bind_output_length) return GNUNET_SYSERR; return GNUNET_OK; @@ -249,6 +257,8 @@ pre_extract_rsa_public_key (void *cls, results[0].buffer_length = 0; results[0].length = &rs->mysql_bind_output_length; results[0].buffer_type = MYSQL_TYPE_BLOB; + results[0].is_null = &rs->is_null; + rs->is_null = 0; return GNUNET_OK; } @@ -279,6 +289,8 @@ post_extract_rsa_public_key (void *cls, void *buf; size_t size; + if (*results->is_null) + return GNUNET_SYSERR; size = (size_t) rs->mysql_bind_output_length; if (rs->mysql_bind_output_length != size) @@ -379,6 +391,8 @@ pre_extract_rsa_signature (void *cls, results[0].buffer_length = 0; results[0].length = &rs->mysql_bind_output_length; results[0].buffer_type = MYSQL_TYPE_BLOB; + results[0].is_null = &rs->is_null; + rs->is_null = 0; return GNUNET_OK; } @@ -407,6 +421,8 @@ post_extract_rsa_signature (void *cls, void *buf; size_t size; + if (*results->is_null) + return GNUNET_SYSERR; size = (size_t) rs->mysql_bind_output_length; if (rs->mysql_bind_output_length != size) @@ -448,7 +464,7 @@ post_extract_rsa_signature (void *cls, */ static void clean_rsa_signature (void *cls, - struct GNUNET_MY_ResultSpec *rs) + struct GNUNET_MY_ResultSpec *rs) { struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst; @@ -505,6 +521,8 @@ pre_extract_string (void * cls, results[0].buffer_length = 0; results[0].length = &rs->mysql_bind_output_length; results[0].buffer_type = MYSQL_TYPE_BLOB; + results[0].is_null = &rs->is_null; + rs->is_null = 0; return GNUNET_OK; } @@ -534,6 +552,11 @@ post_extract_string (void * cls, if (rs->mysql_bind_output_length != size) return GNUNET_SYSERR; + if (*results->is_null) + { + rs->dst = NULL; + return GNUNET_OK; + } buf = GNUNET_malloc (size); results[0].buffer = buf; @@ -627,6 +650,8 @@ pre_extract_uint16 (void *cls, results[0].buffer_length = rs->dst_size; results[0].length = &rs->mysql_bind_output_length; results[0].buffer_type = MYSQL_TYPE_SHORT; + results[0].is_null = &rs->is_null; + rs->is_null = 0; return GNUNET_OK; } @@ -653,6 +678,8 @@ post_extract_uint16 (void *cls, { if (rs->dst_size != rs->mysql_bind_output_length) return GNUNET_SYSERR; + if (*results->is_null) + return GNUNET_SYSERR; return GNUNET_OK; } @@ -702,6 +729,8 @@ pre_extract_uint32 (void *cls, results[0].buffer_length = rs->dst_size; results[0].length = &rs->mysql_bind_output_length; results[0].buffer_type = MYSQL_TYPE_LONG; + results[0].is_null = &rs->is_null; + rs->is_null = 0; return GNUNET_OK; } @@ -728,7 +757,9 @@ post_extract_uint32 (void *cls, MYSQL_BIND *results) { if (rs->dst_size != rs->mysql_bind_output_length) - return GNUNET_SYSERR; + return GNUNET_SYSERR; + if (*results->is_null) + return GNUNET_SYSERR; return GNUNET_OK; } @@ -773,10 +804,14 @@ pre_extract_uint64 (void *cls, unsigned int column, MYSQL_BIND *results) { + if (sizeof (uint64_t) != rs->dst_size) + return GNUNET_SYSERR; results[0].buffer = rs->dst; results[0].buffer_length = rs->dst_size; results[0].length = &rs->mysql_bind_output_length; results[0].buffer_type = MYSQL_TYPE_LONGLONG; + results[0].is_null = &rs->is_null; + rs->is_null = 0; return GNUNET_OK; } @@ -801,7 +836,9 @@ post_extract_uint64 (void *cls, unsigned int column, MYSQL_BIND *results) { - if (rs->dst_size != rs->mysql_bind_output_length) + if (sizeof (uint64_t) != rs->dst_size) + return GNUNET_SYSERR; + if (*results->is_null) return GNUNET_SYSERR; return GNUNET_OK; } -- 2.25.1