On 02/23/2016 07:36 PM, E.Pasma wrote:
> 22 feb 2016, Dan Kennedy:
>
>> On 02/23/2016 01:33 AM, E.Pasma wrote:
>>>
>>> I reproduced the memory leak and added a test in the sql script.
>>> An alternative fix, instead of adding the missing break, is:
>>>
>>>       case SQLITE_TEXT:
>>>       case SQLITE_BLOB:
>>>         pval->n=sqlite3_value_bytes(arg);
>>>         if (!pval->n) {
>>>           pval->z="";
>>>         } else {
>>>           pval->z=sqlite3_malloc(pval->n);
>>>           assert (pval->z); /* TODO: SQLITE_NOMEM*/
>>> memcpy(pval->z,sqlite3_value_blob(arg),pval->n);
>>>         }
>>>         break;
>>>
>>> Thus sqlite3_value_blob is used to get both text or blob value (like 
>>> in sqlite3.c at line ~93615 in routine  attachFunc).
>>>
>>> If no response I opt for the alternative fix and place it at
>>> http://h1972688.stratoserver.net/sqlite_mprint/160223
>>
>>
>> Suggest testing with text values and a utf-16 database.
>>
>> Dan.
>
> Thanks, testing with a utf-16 database does not yield any differences. 
> I inserted some 2-byte character and checked that it comes out 
> unchanged from mprint. Hope this will do.

Very good.

I think it's working because the call to sqlite3_value_bytes() is 
transforming the utf-16 text in the sqlite3_value to utf-8. And then 
value_blob() just returns whatever encoding the sqlite3_value has stored 
- turns out that's utf-8 by the time it's called.

Dan.



>
> sqlite> .version
> SQLite 3.11.0 2016-02-12 00:13:38 
> b5d771991686bf86a679b7dff9f16301a5029c8b
> sqlite> pragma encoding='utf-16';
> sqlite> pragma encoding;
> UTF-16be
> sqlite> create table t (a);
> sqlite> insert into t values ('abc');
> sqlite> insert into t values ('d'||char(1000)||'f');
> sqlite> select typeof(a), length(a), length(cast (a as blob)), a from t;
> text|3|6|abc
> text|3|6|d?f
> sqlite> .load ttt_mprint
> sqlite> select * from t where a=mprint(a);
> bytes: 3, memcmp: 0
> abc
> bytes: 4, memcmp: 0
> d?f
>
> ttt_mprint is compiled to compare sqlite3_value_blob and 
> sqlite3_value_text and print the outcome of memcmp. The relevant part is:
>
>         case SQLITE_TEXT: /* use sqlite3_value_blob */
>         case SQLITE_BLOB: /* use sqlite3_value_blob */
>           pval->n=sqlite3_value_bytes(arg);
>           if (!pval->n) {
>             pval->z="";
>             z2=""; //testing
>           } else {
>             pval->z=sqlite3_malloc(pval->n);
>             z2=sqlite3_malloc(pval->n); //testing
>             memcpy(pval->z,sqlite3_value_blob(arg),pval->n);
>             assert (pval->z); /* TODO: SQLITE_NOMEM*/
>             memcpy(z2,sqlite3_value_text(arg),pval->n); //testing
>           }
>           printf("bytes: %d, memcmp: %d \n",
>             pval->n,
>             memcmp(pval->z, z2, pval->n)); //testing
>           break;
>
>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to