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.
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;