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