With SQLite 3.7.13 (the current version), if you pass a negative
length to sqlite3_bind_blob, you get an assertion failure:

    sqlite3.c:59949: sqlite3VdbeMemSetStr: Assertion `enc!=0' failed.

Here is the relevant source code:

    ...
      if( nByte<0 ){
        assert( enc!=0 );
        if( enc==SQLITE_UTF8 ){
          for(nByte=0; nByte<=iLimit && z[nByte]; nByte++){}
        }else{
          for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
        }
        flags |= MEM_Term;
      }
    ...

If assertions are not turned on, it takes the second branch, treating
the string as UTF-16 (output of attached test program):

    sqlite3_bind_blob returned 0
    column type:  BLOB
    column text:  foo^@garbage^@
    column bytes: 12

This is not a bug, strictly speaking.  It doesn't really make sense
for a BLOB to be NUL-terminated.  But the documentation does not make
it clear that this is undefined behavior [1]:

>In those routines that have a fourth argument, its value is the number of 
>bytes in the parameter. To be clear: the value is the number of bytes in the 
>value, not the number of characters. If the fourth parameter is negative, the 
>length of the string is the number of bytes up to the first zero terminator. 
>...

 [1]: http://www.sqlite.org/c3ref/bind_blob.html

Giving a negative length to sqlite3_bind_blob might be an easy trap to
fall into, since sqlite3_bind_text *does* let you give a negative
length, which basically means strlen(value).

I think the documentation should mention that a negative length
argument is only allowed for text and text16.

Thanks,
-Joey
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to