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")
