Fix infinite loop

This commit is contained in:
Alexey Romanov
2011-04-25 18:05:15 +04:00
parent 81b42236a7
commit f9c8232e35

View File

@@ -365,20 +365,24 @@ static inline int decode_and_bind_param(
case ERL_BINARY_EXT: case ERL_BINARY_EXT:
char_buf_val = driver_alloc(*p_size * sizeof(char)); char_buf_val = driver_alloc(*p_size * sizeof(char));
ei_decode_binary(buffer, p_index, char_buf_val, &bin_size); ei_decode_binary(buffer, p_index, char_buf_val, &bin_size);
// assert(bin_size == *p_size)
result = sqlite3_bind_text(statement, param_index, char_buf_val, *p_size, &driver_free_fun); result = sqlite3_bind_text(statement, param_index, char_buf_val, *p_size, &driver_free_fun);
break; break;
case ERL_SMALL_TUPLE_EXT: case ERL_SMALL_TUPLE_EXT:
// assume this is {blob, Blob} // assume this is {blob, Blob}
ei_get_type(buffer, p_index, p_type, p_size); ei_get_type(buffer, p_index, p_type, p_size);
ei_decode_tuple_header(buffer, p_index, p_size); ei_decode_tuple_header(buffer, p_index, p_size);
assert (*p_size == 2); if (*p_size != 2) {
output_error(drv, SQLITE_MISUSE, "bad parameter type");
return 1;
}
ei_skip_term(buffer, p_index); // skipped the atom 'blob' ei_skip_term(buffer, p_index); // skipped the atom 'blob'
ei_get_type(buffer, p_index, p_type, p_size); ei_get_type(buffer, p_index, p_type, p_size);
assert (*p_type == ERL_BINARY_EXT); if (*p_type != ERL_BINARY_EXT) {
output_error(drv, SQLITE_MISUSE, "bad parameter type");
return 1;
}
char_buf_val = driver_alloc(*p_size * sizeof(char)); char_buf_val = driver_alloc(*p_size * sizeof(char));
ei_decode_binary(buffer, p_index, char_buf_val, &bin_size); ei_decode_binary(buffer, p_index, char_buf_val, &bin_size);
// assert(bin_size == *p_size)
result = sqlite3_bind_blob(statement, param_index, char_buf_val, *p_size, &driver_free_fun); result = sqlite3_bind_blob(statement, param_index, char_buf_val, *p_size, &driver_free_fun);
break; break;
default: default:
@@ -399,76 +403,82 @@ static int bind_parameters(
int i, cur_list_size = -1, param_index = 1, param_indices_are_explicit = 0, result = 0; int i, cur_list_size = -1, param_index = 1, param_indices_are_explicit = 0, result = 0;
long param_index_long; long param_index_long;
char param_name[MAXATOMLEN + 1]; // parameter names shouldn't be longer than 256! char param_name[MAXATOMLEN + 1]; // parameter names shouldn't be longer than 256!
while (*p_index < buffer_size) { result = ei_decode_list_header(buffer, p_index, &cur_list_size);
ei_decode_list_header(buffer, p_index, &cur_list_size); if (result) {
for (i = 0; i < cur_list_size; i++) { return output_error(drv, SQLITE_ERROR,
"error while binding parameters");
}
for (i = 0; i < cur_list_size; i++) {
if (*p_index >= buffer_size) {
return output_error(drv, SQLITE_ERROR,
"error while binding parameters");
}
ei_get_type(buffer, p_index, p_type, p_size);
if (*p_type == ERL_SMALL_TUPLE_EXT) {
int old_index = *p_index;
// param with name or explicit index
param_indices_are_explicit = 1;
if (*p_size != 2) {
return output_error(drv, SQLITE_MISUSE,
"tuple should contain index or name, and value");
}
ei_decode_tuple_header(buffer, p_index, p_size);
ei_get_type(buffer, p_index, p_type, p_size); ei_get_type(buffer, p_index, p_type, p_size);
if (*p_type == ERL_SMALL_TUPLE_EXT) { // first element of tuple is int (index), atom, or string (name)
int old_index = *p_index; switch (*p_type) {
// param with name or explicit index case ERL_SMALL_INTEGER_EXT:
param_indices_are_explicit = 1; case ERL_INTEGER_EXT:
if (*p_size != 2) { ei_decode_long(buffer, p_index, &param_index_long);
return output_error(drv, SQLITE_MISUSE, param_index = param_index_long;
"tuple should contain index or name, and value"); break;
case ERL_ATOM_EXT:
ei_decode_atom(buffer, p_index, param_name);
// insert zero terminator
param_name[*p_size] = '\0';
if (strncmp(param_name, "blob", 5) == 0) {
// this isn't really a parameter name!
*p_index = old_index;
param_indices_are_explicit = 0;
goto IMPLICIT_INDEX; // yuck
} }
ei_decode_tuple_header(buffer, p_index, p_size); else {
ei_get_type(buffer, p_index, p_type, p_size);
// first element of tuple is int (index), atom, or string (name)
switch (*p_type) {
case ERL_SMALL_INTEGER_EXT:
case ERL_INTEGER_EXT:
ei_decode_long(buffer, p_index, &param_index_long);
param_index = param_index_long;
break;
case ERL_ATOM_EXT:
ei_decode_atom(buffer, p_index, param_name);
// insert zero terminator
param_name[*p_size] = '\0';
if (strncmp(param_name, "blob", 5) == 0) {
// this isn't really a parameter name!
*p_index = old_index;
param_indices_are_explicit = 0;
goto IMPLICIT_INDEX; // yuck
}
else {
param_index = sqlite3_bind_parameter_index(statement, param_name);
}
break;
case ERL_STRING_EXT:
if (*p_size >= MAXATOMLEN) {
return output_error(drv, SQLITE_TOOBIG, "parameter name too long");
}
ei_decode_string(buffer, p_index, param_name);
// insert zero terminator
param_name[*p_size] = '\0';
param_index = sqlite3_bind_parameter_index(statement, param_name); param_index = sqlite3_bind_parameter_index(statement, param_name);
break;
default:
return output_error(
drv, SQLITE_MISMATCH,
"parameter index must be given as integer, atom, or string");
} }
result = decode_and_bind_param( break;
drv, buffer, p_index, statement, param_index, p_type, p_size); case ERL_STRING_EXT:
if (result != SQLITE_OK) { if (*p_size >= MAXATOMLEN) {
return result; // error has already been output return output_error(drv, SQLITE_TOOBIG, "parameter name too long");
} }
ei_decode_string(buffer, p_index, param_name);
// insert zero terminator
param_name[*p_size] = '\0';
param_index = sqlite3_bind_parameter_index(statement, param_name);
break;
default:
return output_error(
drv, SQLITE_MISMATCH,
"parameter index must be given as integer, atom, or string");
}
result = decode_and_bind_param(
drv, buffer, p_index, statement, param_index, p_type, p_size);
if (result != SQLITE_OK) {
return result; // error has already been output
}
}
else {
IMPLICIT_INDEX:
if (param_indices_are_explicit) {
return output_error(
drv, SQLITE_MISUSE,
"parameters without indices shouldn't follow indexed or named parameters");
} }
else {
IMPLICIT_INDEX:
if (param_indices_are_explicit) {
return output_error(
drv, SQLITE_MISUSE,
"parameters without indices shouldn't follow indexed or named parameters");
}
result = decode_and_bind_param( result = decode_and_bind_param(
drv, buffer, p_index, statement, param_index, p_type, p_size); drv, buffer, p_index, statement, param_index, p_type, p_size);
if (result != SQLITE_OK) { if (result != SQLITE_OK) {
return result; // error has already been output return result; // error has already been output
}
++param_index;
} }
++param_index;
} }
} }
return result; return result;
@@ -516,7 +526,7 @@ static int sql_bind_and_exec(sqlite3_drv_t *drv, char *buffer, int buffer_size)
ei_decode_version(buffer, &index, NULL); ei_decode_version(buffer, &index, NULL);
result = ei_decode_tuple_header(buffer, &index, &size); result = ei_decode_tuple_header(buffer, &index, &size);
if (size != 2) { if (result || (size != 2)) {
return output_error(drv, SQLITE_MISUSE, return output_error(drv, SQLITE_MISUSE,
"Expected a tuple of SQL command and params"); "Expected a tuple of SQL command and params");
} }