1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Add new APIs that take 64-bit length parameters:

sqlite3_malloc64(),
sqlite3_realloc64(),
sqlite3_bind_blob64(),
sqlite3_bind_texte64(),
sqlite3_result_blob64(),
and sqlite3_result_texte64().
Internal memory allocation routines also now use 64-bit unsigned length
parameters for safety.
Also add the sqlite3_msize() interface.
Fix the sqlite3_get_table() to use sqlite3_realloc64() to avoid a
integer overflow problem.

FossilOrigin-Name: 94954850cf2e1ec0b7f590c7f46cdc54c72558ce
This commit is contained in:
drh
2014-09-09 17:27:35 +00:00
parent 524a733d89
commit da4ca9d19c
10 changed files with 196 additions and 61 deletions

View File

@@ -215,6 +215,9 @@ int sqlite3_value_type(sqlite3_value* pVal){
** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the
** result as a string or blob but if the string or blob is too large, it
** then sets the error code to SQLITE_TOOBIG
**
** The invokeValueDestructor(P,X) routine invokes destructor function X()
** on value P is not going to be used and need to be destroyed.
*/
static void setResultStrOrError(
sqlite3_context *pCtx, /* Function context */
@@ -227,6 +230,23 @@ static void setResultStrOrError(
sqlite3_result_error_toobig(pCtx);
}
}
static int invokeValueDestructor(
const void *p, /* Value to destroy */
void (*xDel)(void*), /* The destructor */
sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */
){
if( xDel==0 ){
/* noop */
}else if( xDel==SQLITE_TRANSIENT ){
/* noop */
}else if( xDel==SQLITE_DYNAMIC ){
sqlite3_free((void*)p);
}else{
xDel((void*)p);
}
if( pCtx ) sqlite3_result_error_toobig(pCtx);
return SQLITE_TOOBIG;
}
void sqlite3_result_blob(
sqlite3_context *pCtx,
const void *z,
@@ -237,6 +257,19 @@ void sqlite3_result_blob(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, 0, xDel);
}
void sqlite3_result_blob64(
sqlite3_context *pCtx,
const void *z,
sqlite3_uint64 n,
void (*xDel)(void *)
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
if( n>0x7fffffff ){
(void)invokeValueDestructor(z, xDel, pCtx);
}else{
setResultStrOrError(pCtx, z, (int)n, 0, xDel);
}
}
void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
@@ -276,6 +309,20 @@ void sqlite3_result_text(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
}
void sqlite3_result_texte64(
sqlite3_context *pCtx,
const char *z,
sqlite3_uint64 n,
void (*xDel)(void *),
unsigned char enc
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
if( n>0x7fffffff ){
(void)invokeValueDestructor(z, xDel, pCtx);
}else{
setResultStrOrError(pCtx, z, (int)n, enc, xDel);
}
}
#ifndef SQLITE_OMIT_UTF16
void sqlite3_result_text16(
sqlite3_context *pCtx,
@@ -1125,6 +1172,19 @@ int sqlite3_bind_blob(
){
return bindText(pStmt, i, zData, nData, xDel, 0);
}
int sqlite3_bind_blob64(
sqlite3_stmt *pStmt,
int i,
const void *zData,
sqlite3_uint64 nData,
void (*xDel)(void*)
){
if( nData>0x7fffffff ){
return invokeValueDestructor(zData, xDel, 0);
}else{
return bindText(pStmt, i, zData, nData, xDel, 0);
}
}
int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
@@ -1166,6 +1226,20 @@ int sqlite3_bind_text(
){
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
}
int sqlite3_bind_texte64(
sqlite3_stmt *pStmt,
int i,
const char *zData,
sqlite3_uint64 nData,
void (*xDel)(void*),
unsigned char enc
){
if( nData>0x7fffffff ){
return invokeValueDestructor(zData, xDel, 0);
}else{
return bindText(pStmt, i, zData, nData, xDel, enc);
}
}
#ifndef SQLITE_OMIT_UTF16
int sqlite3_bind_text16(
sqlite3_stmt *pStmt,