Fixes ruby-mysql with Ruby 1.9 and UTF-8
authorAntonio Terceiro <terceiro@debian.org>
Sun, 5 Aug 2012 18:43:30 +0000 (15:43 -0300)
committerAntonio Terceiro <terceiro@debian.org>
Sun, 5 Aug 2012 18:43:30 +0000 (15:43 -0300)
Closes: #678515

debian/changelog
debian/patches/add-basic-encoding-awareness-logic.patch [new file with mode: 0644]
debian/patches/series [new file with mode: 0644]

index 8ebad65..bc2f830 100644 (file)
@@ -1,3 +1,12 @@
+ruby-mysql (2.8.2+gem2deb-3) UNRELEASED; urgency=low
+
+  * Team upload.
+  * debian/patches/add-basic-encoding-awareness-logic.patch: convert all
+    string data to the default external encoding. This makes it possible to
+    use the mysql bindings with RUby 1.9 and UTF-8 (Closes: #678515)
+
+ -- Antonio Terceiro <terceiro@debian.org>  Sun, 05 Aug 2012 11:05:50 -0300
+
 ruby-mysql (2.8.2+gem2deb-2) unstable; urgency=low
 
   * Team upload.
diff --git a/debian/patches/add-basic-encoding-awareness-logic.patch b/debian/patches/add-basic-encoding-awareness-logic.patch
new file mode 100644 (file)
index 0000000..1ca4922
--- /dev/null
@@ -0,0 +1,280 @@
+Description: Add basic encoding aware logic
+ Convert all data to default external encoding
+ .
+ This patch has been adapted for the ruby-mysql Debian package by Antonio
+ Terceiro <terceiro@debian.org>
+Author: Loren Segal <lsegal@soen.ca>
+
+---
+
+Origin: https://github.com/lsegal/mysql-ruby/commit/b7e4613559f0a741935ad375f07f9411c2107bb7
+Bug-Debian: http://bugs.debian.org/678515
+Reviewed-By: Antonio Terceiro <terceiro@debian.org>
+Last-Update: 2012-08-05
+
+--- ruby-mysql-2.8.2+gem2deb.orig/mysql.c
++++ ruby-mysql-2.8.2+gem2deb/mysql.c
+@@ -42,6 +42,32 @@
+ #define GetMysqlRes(obj)      (Check_Type(obj, T_DATA), ((struct mysql_res*)DATA_PTR(obj))->res)
+ #define GetMysqlStmt(obj)     (Check_Type(obj, T_DATA), ((struct mysql_stmt*)DATA_PTR(obj))->stmt)
++#ifdef RUBY19
++#include <ruby/encoding.h>
++#define DEFAULT_ENCODING (rb_enc_get(rb_enc_default_external()))
++#else
++#define DEFAULT_ENCODING NULL
++#define rb_enc_str_new(ptr, len, enc) rb_str_new(ptr, len)
++#endif
++
++VALUE
++rb_mysql_enc_tainted_str_new(const char *ptr, long len)
++{
++    VALUE str = rb_enc_str_new(ptr, len, DEFAULT_ENCODING);
++
++    OBJ_TAINT(str);
++    return str;
++}
++
++VALUE
++rb_mysql_enc_tainted_str_new2(const char *ptr)
++{
++    VALUE str = rb_enc_str_new(ptr, strlen(ptr), DEFAULT_ENCODING);
++
++    OBJ_TAINT(str);
++    return str;
++}
++
+ VALUE cMysql;
+ VALUE cMysqlRes;
+ VALUE cMysqlField;
+@@ -170,7 +196,7 @@ static void mysql_raise(MYSQL* m)
+     VALUE e = rb_exc_new2(eMysql, mysql_error(m));
+     rb_iv_set(e, "errno", INT2FIX(mysql_errno(m)));
+ #if MYSQL_VERSION_ID >= 40101
+-    rb_iv_set(e, "sqlstate", rb_tainted_str_new2(mysql_sqlstate(m)));
++    rb_iv_set(e, "sqlstate", rb_mysql_enc_tainted_str_new2(mysql_sqlstate(m)));
+ #endif
+     rb_exc_raise(e);
+ }
+@@ -197,9 +223,9 @@ static VALUE make_field_obj(MYSQL_FIELD*
+     if (f == NULL)
+       return Qnil;
+     obj = rb_obj_alloc(cMysqlField);
+-    rb_iv_set(obj, "name", f->name? rb_str_freeze(rb_tainted_str_new2(f->name)): Qnil);
+-    rb_iv_set(obj, "table", f->table? rb_str_freeze(rb_tainted_str_new2(f->table)): Qnil);
+-    rb_iv_set(obj, "def", f->def? rb_str_freeze(rb_tainted_str_new2(f->def)): Qnil);
++    rb_iv_set(obj, "name", f->name? rb_str_freeze(rb_mysql_enc_tainted_str_new2(f->name)): Qnil);
++    rb_iv_set(obj, "table", f->table? rb_str_freeze(rb_mysql_enc_tainted_str_new2(f->table)): Qnil);
++    rb_iv_set(obj, "def", f->def? rb_str_freeze(rb_mysql_enc_tainted_str_new2(f->def)): Qnil);
+     rb_iv_set(obj, "type", INT2NUM(f->type));
+     rb_iv_set(obj, "length", INT2NUM(f->length));
+     rb_iv_set(obj, "max_length", INT2NUM(f->max_length));
+@@ -286,7 +312,7 @@ static VALUE escape_string(VALUE klass,
+ {
+     VALUE ret;
+     Check_Type(str, T_STRING);
+-    ret = rb_str_new(0, (RSTRING_LEN(str))*2+1);
++    ret = rb_enc_str_new(0, (RSTRING_LEN(str))*2+1, DEFAULT_ENCODING);
+     rb_str_set_len(ret, mysql_escape_string(RSTRING_PTR(ret), RSTRING_PTR(str), RSTRING_LEN(str)));
+     return ret;
+ }
+@@ -294,7 +320,7 @@ static VALUE escape_string(VALUE klass,
+ /*    client_info()   */
+ static VALUE client_info(VALUE klass)
+ {
+-    return rb_tainted_str_new2(mysql_get_client_info());
++    return rb_mysql_enc_tainted_str_new2(mysql_get_client_info());
+ }
+ #if MYSQL_VERSION_ID >= 32332
+@@ -430,7 +456,7 @@ static VALUE real_escape_string(VALUE ob
+     MYSQL* m = GetHandler(obj);
+     VALUE ret;
+     Check_Type(str, T_STRING);
+-    ret = rb_str_new(0, (RSTRING_LEN(str))*2+1);
++    ret = rb_enc_str_new(0, (RSTRING_LEN(str))*2+1, DEFAULT_ENCODING);
+     rb_str_set_len(ret, mysql_real_escape_string(m, RSTRING_PTR(ret), RSTRING_PTR(str), RSTRING_LEN(str)));
+     return ret;
+ }
+@@ -469,7 +495,7 @@ static VALUE change_user(int argc, VALUE
+ /*    character_set_name()    */
+ static VALUE character_set_name(VALUE obj)
+ {
+-    return rb_tainted_str_new2(mysql_character_set_name(GetHandler(obj)));
++    return rb_mysql_enc_tainted_str_new2(mysql_character_set_name(GetHandler(obj)));
+ }
+ #endif
+@@ -534,7 +560,7 @@ static VALUE field_count(VALUE obj)
+ /*    host_info()     */
+ static VALUE host_info(VALUE obj)
+ {
+-    return rb_tainted_str_new2(mysql_get_host_info(GetHandler(obj)));
++    return rb_mysql_enc_tainted_str_new2(mysql_get_host_info(GetHandler(obj)));
+ }
+ /*    proto_info()    */
+@@ -546,14 +572,14 @@ static VALUE proto_info(VALUE obj)
+ /*    server_info()   */
+ static VALUE server_info(VALUE obj)
+ {
+-    return rb_tainted_str_new2(mysql_get_server_info(GetHandler(obj)));
++    return rb_mysql_enc_tainted_str_new2(mysql_get_server_info(GetHandler(obj)));
+ }
+ /*    info()          */
+ static VALUE info(VALUE obj)
+ {
+     const char* p = mysql_info(GetHandler(obj));
+-    return p? rb_tainted_str_new2(p): Qnil;
++    return p? rb_mysql_enc_tainted_str_new2(p): Qnil;
+ }
+ /*    insert_id()     */
+@@ -588,7 +614,7 @@ static VALUE list_dbs(int argc, VALUE* a
+     n = mysql_num_rows(res);
+     ret = rb_ary_new2(n);
+     for (i=0; i<n; i++)
+-      rb_ary_store(ret, i, rb_tainted_str_new2(mysql_fetch_row(res)[0]));
++      rb_ary_store(ret, i, rb_mysql_enc_tainted_str_new2(mysql_fetch_row(res)[0]));
+     mysql_free_result(res);
+     return ret;
+ }
+@@ -633,7 +659,7 @@ static VALUE list_tables(int argc, VALUE
+     n = mysql_num_rows(res);
+     ret = rb_ary_new2(n);
+     for (i=0; i<n; i++)
+-      rb_ary_store(ret, i, rb_tainted_str_new2(mysql_fetch_row(res)[0]));
++      rb_ary_store(ret, i, rb_mysql_enc_tainted_str_new2(mysql_fetch_row(res)[0]));
+     mysql_free_result(res);
+     return ret;
+ }
+@@ -697,7 +723,7 @@ static VALUE my_stat(VALUE obj)
+     const char* s = mysql_stat(m);
+     if (s == NULL)
+       mysql_raise(m);
+-    return rb_tainted_str_new2(s);
++    return rb_mysql_enc_tainted_str_new2(s);
+ }
+ /*    store_result()  */
+@@ -864,7 +890,7 @@ static VALUE set_server_option(VALUE obj
+ static VALUE sqlstate(VALUE obj)
+ {
+     MYSQL *m = GetHandler(obj);
+-    return rb_tainted_str_new2(mysql_sqlstate(m));
++    return rb_mysql_enc_tainted_str_new2(mysql_sqlstate(m));
+ }
+ #endif
+@@ -1029,7 +1055,7 @@ static VALUE fetch_row(VALUE obj)
+       return Qnil;
+     ary = rb_ary_new2(n);
+     for (i=0; i<n; i++)
+-      rb_ary_store(ary, i, row[i]? rb_tainted_str_new(row[i], lengths[i]): Qnil);
++      rb_ary_store(ary, i, row[i]? rb_mysql_enc_tainted_str_new(row[i], lengths[i]): Qnil);
+     return ary;
+ }
+@@ -1053,7 +1079,7 @@ static VALUE fetch_hash2(VALUE obj, VALU
+         if (colname == Qnil) {
+             colname = rb_ary_new2(n);
+             for (i=0; i<n; i++) {
+-                VALUE s = rb_tainted_str_new2(fields[i].name);
++                VALUE s = rb_mysql_enc_tainted_str_new2(fields[i].name);
+                 rb_obj_freeze(s);
+                 rb_ary_store(colname, i, s);
+             }
+@@ -1066,7 +1092,7 @@ static VALUE fetch_hash2(VALUE obj, VALU
+             colname = rb_ary_new2(n);
+             for (i=0; i<n; i++) {
+                 int len = strlen(fields[i].table)+strlen(fields[i].name)+1;
+-                VALUE s = rb_tainted_str_new(NULL, len);
++                VALUE s = rb_mysql_enc_tainted_str_new(NULL, len);
+                 snprintf(RSTRING_PTR(s), len+1, "%s.%s", fields[i].table, fields[i].name);
+                 rb_obj_freeze(s);
+                 rb_ary_store(colname, i, s);
+@@ -1076,7 +1102,7 @@ static VALUE fetch_hash2(VALUE obj, VALU
+         }
+     }
+     for (i=0; i<n; i++) {
+-        rb_hash_aset(hash, rb_ary_entry(colname, i), row[i]? rb_tainted_str_new(row[i], lengths[i]): Qnil);
++        rb_hash_aset(hash, rb_ary_entry(colname, i), row[i]? rb_mysql_enc_tainted_str_new(row[i], lengths[i]): Qnil);
+     }
+     return hash;
+ }
+@@ -1198,7 +1224,7 @@ static VALUE field_hash(VALUE obj)
+ static VALUE field_inspect(VALUE obj)
+ {
+     VALUE n = rb_iv_get(obj, "name");
+-    VALUE s = rb_str_new(0, RSTRING_LEN(n) + 16);
++    VALUE s = rb_enc_str_new(0, RSTRING_LEN(n) + 16, DEFAULT_ENCODING);
+     sprintf(RSTRING_PTR(s), "#<Mysql::Field:%s>", RSTRING_PTR(n));
+     return s;
+ }
+@@ -1257,7 +1283,7 @@ static void mysql_stmt_raise(MYSQL_STMT*
+ {
+     VALUE e = rb_exc_new2(eMysql, mysql_stmt_error(s));
+     rb_iv_set(e, "errno", INT2FIX(mysql_stmt_errno(s)));
+-    rb_iv_set(e, "sqlstate", rb_tainted_str_new2(mysql_stmt_sqlstate(s)));
++    rb_iv_set(e, "sqlstate", rb_mysql_enc_tainted_str_new2(mysql_stmt_sqlstate(s)));
+     rb_exc_raise(e);
+ }
+@@ -1573,7 +1599,7 @@ static VALUE stmt_fetch(VALUE obj)
+             case MYSQL_TYPE_NEWDECIMAL:
+             case MYSQL_TYPE_BIT:
+ #endif
+-                v = rb_tainted_str_new(s->result.bind[i].buffer, s->result.length[i]);
++                v = rb_mysql_enc_tainted_str_new(s->result.bind[i].buffer, s->result.length[i]);
+                 break;
+             default:
+                 rb_raise(rb_eTypeError, "unknown buffer_type: %d", s->result.bind[i].buffer_type);
+@@ -1762,7 +1788,7 @@ static VALUE stmt_send_long_data(VALUE o
+ static VALUE stmt_sqlstate(VALUE obj)
+ {
+     struct mysql_stmt* s = DATA_PTR(obj);
+-    return rb_tainted_str_new2(mysql_stmt_sqlstate(s->stmt));
++    return rb_mysql_enc_tainted_str_new2(mysql_stmt_sqlstate(s->stmt));
+ }
+ /*-------------------------------
+--- ruby-mysql-2.8.2+gem2deb.orig/test.rb
++++ ruby-mysql-2.8.2+gem2deb/test.rb
+@@ -2,7 +2,7 @@
+ # $Id: test.rb 250 2010-02-11 10:42:54Z tommy $
+ require "test/unit"
+-require "./mysql.o"
++require "mysql"
+ class TC_Mysql < Test::Unit::TestCase
+   def setup()
+@@ -1196,7 +1196,9 @@ class TC_MysqlStmt2 < Test::Unit::TestCa
+       @s.execute
+       assert_equal([nil], @s.fetch)
+       assert_equal([""], @s.fetch)
+-      assert_equal(["abc"], @s.fetch)
++      row = @s.fetch
++      assert_equal(Encoding.default_external, row[0].encoding) if RUBY_VERSION =~ /1.9/
++      assert_equal(["abc"], row)
+       assert_equal(["def"], @s.fetch)
+       assert_equal(["abc"], @s.fetch)
+       assert_equal(["def"], @s.fetch)
+@@ -1233,6 +1235,7 @@ class TC_MysqlStmt2 < Test::Unit::TestCa
+         case c
+         when 0
+           assert_equal([1,"abc",Mysql::Time.new(1970,12,24,23,59,05)], a)
++          assert_equal(Encoding.default_external, a[1].encoding) if RUBY_VERSION =~ /1.9/
+         when 1
+           assert_equal([2,"def",Mysql::Time.new(2112,9,3,12,34,56)], a)
+         when 2
+--- ruby-mysql-2.8.2+gem2deb.orig/extconf.rb
++++ ruby-mysql-2.8.2+gem2deb/extconf.rb
+@@ -68,4 +68,6 @@ File.open('error_const.h', 'w') do |f|
+   end
+ end
++$CPPFLAGS += " -DRUBY19" if RUBY_VERSION =~ /1.9/
++
+ create_makefile("mysql")
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644 (file)
index 0000000..0340c09
--- /dev/null
@@ -0,0 +1 @@
+add-basic-encoding-awareness-logic.patch