]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-sql: Implemented sql_escape_blob()
authorTimo Sirainen <tss@iki.fi>
Wed, 2 Sep 2015 16:43:26 +0000 (19:43 +0300)
committerTimo Sirainen <tss@iki.fi>
Wed, 2 Sep 2015 16:43:26 +0000 (19:43 +0300)
src/lib-sql/driver-cassandra.c
src/lib-sql/driver-mysql.c
src/lib-sql/driver-pgsql.c
src/lib-sql/driver-sqlite.c
src/lib-sql/driver-sqlpool.c
src/lib-sql/sql-api-private.h
src/lib-sql/sql-api.c
src/lib-sql/sql-api.h

index 91287c226109db4632e9016289073fc1b3b9ac93..41a9032134706a033f1bbfbdefd5e64822628941 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "array.h"
+#include "hex-binary.h"
 #include "str.h"
 #include "ioloop.h"
 #include "write-full.h"
@@ -957,6 +958,17 @@ driver_cassandra_update(struct sql_transaction_context *_ctx, const char *query,
        sql_transaction_add_query(_ctx, ctx->query_pool, query, affected_rows);
 }
 
+static const char *
+driver_cassandra_escape_blob(struct sql_db *_db ATTR_UNUSED,
+                            const unsigned char *data, size_t size)
+{
+       string_t *str = t_str_new(128);
+
+       str_append(str, "0x");
+       binary_to_hex_append(str, data, size);
+       return str_c(str);
+}
+
 const struct sql_db driver_cassandra_db = {
        .name = "cassandra",
        .flags = SQL_DB_FLAG_POOLED,
@@ -976,7 +988,9 @@ const struct sql_db driver_cassandra_db = {
                driver_cassandra_transaction_commit_s,
                driver_cassandra_transaction_rollback,
 
-               driver_cassandra_update
+               driver_cassandra_update,
+
+               driver_cassandra_escape_blob
        }
 };
 
index 1285367bb64890433e7085367215d1ef4fbff31d..da1f0f01a009402c4e12006c7138628110e7df21 100644 (file)
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "ioloop.h"
 #include "array.h"
+#include "hex-binary.h"
 #include "str.h"
 #include "net.h"
 #include "sql-api-private.h"
@@ -619,6 +620,18 @@ driver_mysql_update(struct sql_transaction_context *_ctx, const char *query,
                                  query, affected_rows);
 }
 
+static const char *
+driver_mysql_escape_blob(struct sql_db *_db ATTR_UNUSED,
+                        const unsigned char *data, size_t size)
+{
+       string_t *str = t_str_new(128);
+
+       str_append(str, "HEX('");
+       binary_to_hex_append(str, data, size);
+       str_append_c(str, ')');
+       return str_c(str);
+}
+
 const struct sql_db driver_mysql_db = {
        .name = "mysql",
        .flags = SQL_DB_FLAG_BLOCKING | SQL_DB_FLAG_POOLED,
@@ -638,7 +651,9 @@ const struct sql_db driver_mysql_db = {
                driver_mysql_transaction_commit_s,
                driver_mysql_transaction_rollback,
 
-               driver_mysql_update
+               driver_mysql_update,
+
+               driver_mysql_escape_blob
        }
 };
 
index bbe066459ef109b13e05c8f4a392a95227f86fcf..efa184916234deb18a6db20b81339b8b92a3e4a8 100644 (file)
@@ -3,6 +3,8 @@
 #include "lib.h"
 #include "array.h"
 #include "ioloop.h"
+#include "hex-binary.h"
+#include "str.h"
 #include "time-util.h"
 #include "sql-api-private.h"
 
@@ -1066,6 +1068,18 @@ driver_pgsql_update(struct sql_transaction_context *_ctx, const char *query,
        sql_transaction_add_query(_ctx, ctx->query_pool, query, affected_rows);
 }
 
+static const char *
+driver_pgsql_escape_blob(struct sql_db *_db ATTR_UNUSED,
+                        const unsigned char *data, size_t size)
+{
+       string_t *str = t_str_new(128);
+
+       str_append(str, "E'\\x");
+       binary_to_hex_append(str, data, size);
+       str_append_c(str, '\'');
+       return str_c(str);
+}
+
 const struct sql_db driver_pgsql_db = {
        .name = "pgsql",
        .flags = SQL_DB_FLAG_POOLED,
@@ -1085,7 +1099,9 @@ const struct sql_db driver_pgsql_db = {
                driver_pgsql_transaction_commit_s,
                driver_pgsql_transaction_rollback,
 
-               driver_pgsql_update
+               driver_pgsql_update,
+
+               driver_pgsql_escape_blob
        }
 };
 
index 3b92f0fb92c63f8fb6ae0cac631c34f45dd7ffa8..a3b5d85efd5de39aabb06354310007932f32cbbe 100644 (file)
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "array.h"
 #include "str.h"
+#include "hex-binary.h"
 #include "sql-api-private.h"
 
 #ifdef BUILD_SQLITE
@@ -392,6 +393,18 @@ driver_sqlite_update(struct sql_transaction_context *_ctx, const char *query,
                *affected_rows = sqlite3_changes(db->sqlite);
 }
 
+static const char *
+driver_sqlite_escape_blob(struct sql_db *_db ATTR_UNUSED,
+                         const unsigned char *data, size_t size)
+{
+       string_t *str = t_str_new(128);
+
+       str_append(str, "x'");
+       binary_to_hex_append(str, data, size);
+       str_append_c(str, '\'');
+       return str_c(str);
+}
+
 const struct sql_db driver_sqlite_db = {
        .name = "sqlite",
        .flags = SQL_DB_FLAG_BLOCKING,
@@ -410,7 +423,9 @@ const struct sql_db driver_sqlite_db = {
                driver_sqlite_transaction_commit,
                driver_sqlite_transaction_commit_s,
                driver_sqlite_transaction_rollback,
-               driver_sqlite_update
+               driver_sqlite_update,
+
+               driver_sqlite_escape_blob
        }
 };
 
index 626760dea8f7cdf8dc77d04e544dec793ec4c2f7..b86d3fd2154237bc7cf0c824915b01cce9911d52 100644 (file)
@@ -790,6 +790,25 @@ driver_sqlpool_update(struct sql_transaction_context *_ctx, const char *query,
                                  query, affected_rows);
 }
 
+static const char *
+driver_sqlpool_escape_blob(struct sql_db *_db,
+                          const unsigned char *data, size_t size)
+{
+       struct sqlpool_db *db = (struct sqlpool_db *)_db;
+       const struct sqlpool_connection *conns;
+       unsigned int i, count;
+
+       /* use the first ready connection */
+       conns = array_get(&db->all_connections, &count);
+       for (i = 0; i < count; i++) {
+               if (SQL_DB_IS_READY(conns[i].db))
+                       return sql_escape_blob(conns[i].db, data, size);
+       }
+       /* no ready connections. just use the first one (we're guaranteed
+          to always have one) */
+       return sql_escape_blob(conns[0].db, data, size);
+}
+
 struct sql_db driver_sqlpool_db = {
        "",
 
@@ -808,6 +827,8 @@ struct sql_db driver_sqlpool_db = {
                driver_sqlpool_transaction_commit_s,
                driver_sqlpool_transaction_rollback,
 
-               driver_sqlpool_update
+               driver_sqlpool_update,
+
+               driver_sqlpool_escape_blob
        }
 };
index f59d47cfda94a9ff7fa11f182431ec9eba225dda..ea47f5cba4176b4b9c42db811f72a35ab344b6f0 100644 (file)
@@ -76,6 +76,8 @@ struct sql_db_vfuncs {
 
        void (*update)(struct sql_transaction_context *ctx, const char *query,
                       unsigned int *affected_rows);
+       const char *(*escape_blob)(struct sql_db *db,
+                                  const unsigned char *data, size_t size);
 };
 
 struct sql_db {
index 12743f819b2ba02dd338245d5c5e52b18107612f..98d208b0972363f187f1220e95326edf0cbbf1cf 100644 (file)
@@ -126,6 +126,12 @@ const char *sql_escape_string(struct sql_db *db, const char *string)
        return db->v.escape_string(db, string);
 }
 
+const char *sql_escape_blob(struct sql_db *db,
+                           const unsigned char *data, size_t size)
+{
+       return db->v.escape_blob(db, data, size);
+}
+
 void sql_exec(struct sql_db *db, const char *query)
 {
        db->v.exec(db, query);
index 436d1d543a98a1cd3e59bc803ac268fc3040f5ca..773d3132e6a45ea433d6666a67d91dd5ed7ed701 100644 (file)
@@ -70,6 +70,9 @@ void sql_disconnect(struct sql_db *db);
 
 /* Escape the given string if needed and return it. */
 const char *sql_escape_string(struct sql_db *db, const char *string);
+/* Escape the given data as a string. */
+const char *sql_escape_blob(struct sql_db *db,
+                           const unsigned char *data, size_t size);
 
 /* Execute SQL query without waiting for results. */
 void sql_exec(struct sql_db *db, const char *query);