Skip to content
Snippets Groups Projects
Commit d40d2a3a authored by Kirill Shcherbatov's avatar Kirill Shcherbatov
Browse files

sql: fixed possible leak in sqlite3EndTable

parent 96a02922
No related branches found
No related tags found
No related merge requests found
......@@ -654,11 +654,11 @@ sqlite3AddColumn(Parse * pParse, Token * pName, Token * pType)
memcpy(column_def, &field_def_default, sizeof(field_def_default));
column_def->name = z;
/*
* Marker on_conflict_action_MAX is used to detect
* Marker ON_CONFLICT_ACTION_DEFAULT is used to detect
* attempts to define NULL multiple time or to detect
* invalid primary key definition.
*/
column_def->nullable_action = on_conflict_action_MAX;
column_def->nullable_action = ON_CONFLICT_ACTION_DEFAULT;
column_def->is_nullable = true;
if (pType->n == 0) {
......@@ -701,8 +701,8 @@ sql_column_add_nullable_action(struct Parse *parser,
if (p == NULL || NEVER(p->def->field_count < 1))
return;
struct field_def *field = &p->def->fields[p->def->field_count - 1];
if (field->nullable_action != on_conflict_action_MAX &&
nullable_action != ON_CONFLICT_ACTION_DEFAULT) {
if (field->nullable_action != ON_CONFLICT_ACTION_DEFAULT &&
nullable_action != field->nullable_action) {
/* Prevent defining nullable_action many times. */
const char *err_msg =
tt_sprintf("NULL declaration for column '%s' of table "
......@@ -867,13 +867,12 @@ field_def_create_for_pk(struct Parse *parser, struct field_def *field,
const char *space_name)
{
if (field->nullable_action != ON_CONFLICT_ACTION_ABORT &&
field->nullable_action != ON_CONFLICT_ACTION_DEFAULT &&
field->nullable_action != on_conflict_action_MAX) {
field->nullable_action != ON_CONFLICT_ACTION_DEFAULT) {
diag_set(ClientError, ER_NULLABLE_PRIMARY, space_name);
parser->rc = SQL_TARANTOOL_ERROR;
parser->nErr++;
return -1;
} else if (field->nullable_action == on_conflict_action_MAX) {
} else if (field->nullable_action == ON_CONFLICT_ACTION_DEFAULT) {
field->nullable_action = ON_CONFLICT_ACTION_ABORT;
field->is_nullable = false;
}
......@@ -1636,14 +1635,14 @@ sqlite3EndTable(Parse * pParse, /* Parse context */
sqlite3ErrorMsg(pParse,
"PRIMARY KEY missing on table %s",
p->def->name);
return;
goto cleanup;
}
}
/* Set default on_nullable action if required. */
struct field_def *field = p->def->fields;
for (uint32_t i = 0; i < p->def->field_count; ++i, ++field) {
if (field->nullable_action == on_conflict_action_MAX) {
if (field->nullable_action == ON_CONFLICT_ACTION_DEFAULT) {
field->nullable_action = ON_CONFLICT_ACTION_NONE;
field->is_nullable = true;
}
......@@ -1654,7 +1653,7 @@ sqlite3EndTable(Parse * pParse, /* Parse context */
"only PRIMARY KEY constraint can "
"have ON CONFLICT REPLACE clause "
"- %s", p->def->name);
return;
goto cleanup;
}
if (db->init.busy) {
/*
......@@ -1666,7 +1665,7 @@ sqlite3EndTable(Parse * pParse, /* Parse context */
*/
struct ExprList *old_checks = p->def->opts.checks;
if (sql_table_def_rebuild(db, p) != 0)
return;
goto cleanup;
sql_expr_list_delete(db, old_checks);
}
......@@ -1684,7 +1683,7 @@ sqlite3EndTable(Parse * pParse, /* Parse context */
v = sqlite3GetVdbe(pParse);
if (NEVER(v == 0))
return;
goto cleanup;
/*
* Initialize zType for the new view or table.
......@@ -1769,7 +1768,7 @@ sqlite3EndTable(Parse * pParse, /* Parse context */
if (pOld) {
assert(p == pOld); /* Malloc must have failed inside HashInsert() */
sqlite3OomFault(db);
return;
goto cleanup;
}
pParse->pNewTable = 0;
current_session()->sql_flags |= SQLITE_InternChanges;
......@@ -1794,6 +1793,7 @@ sqlite3EndTable(Parse * pParse, /* Parse context */
* don't require make a copy on space_def_dup and to improve
* debuggability.
*/
cleanup:
sql_expr_list_delete(db, p->def->opts.checks);
p->def->opts.checks = NULL;
}
......
......@@ -275,13 +275,13 @@ ccons ::= DEFAULT id(X). {
ccons ::= NULL onconf(R). {
sql_column_add_nullable_action(pParse, ON_CONFLICT_ACTION_NONE);
/* Trigger nullability mismatch error if required. */
if (R != ON_CONFLICT_ACTION_DEFAULT)
if (R != ON_CONFLICT_ACTION_ABORT)
sql_column_add_nullable_action(pParse, R);
}
ccons ::= NOT NULL onconf(R). {sql_column_add_nullable_action(pParse, R);}
ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
{sqlite3AddPrimaryKey(pParse,0,R,I,Z);}
ccons ::= UNIQUE onconf(R). {sql_create_index(pParse,0,0,0,R,0,0,
ccons ::= UNIQUE index_onconf(R). {sql_create_index(pParse,0,0,0,R,0,0,
SORT_ORDER_ASC, false,
SQL_INDEX_TYPE_CONSTRAINT_UNIQUE);}
ccons ::= CHECK LP expr(X) RP. {sql_add_check_constraint(pParse,&X);}
......@@ -331,7 +331,7 @@ tconscomma ::= .
tcons ::= CONSTRAINT nm(X). {pParse->constraintName = X;}
tcons ::= PRIMARY KEY LP sortlist(X) autoinc(I) RP onconf(R).
{sqlite3AddPrimaryKey(pParse,X,R,I,0);}
tcons ::= UNIQUE LP sortlist(X) RP onconf(R).
tcons ::= UNIQUE LP sortlist(X) RP index_onconf(R).
{sql_create_index(pParse,0,0,X,R,0,0,
SORT_ORDER_ASC,false,
SQL_INDEX_TYPE_CONSTRAINT_UNIQUE);}
......@@ -350,9 +350,12 @@ defer_subclause_opt(A) ::= defer_subclause(A).
// default behavior when there is a constraint conflict.
//
%type onconf {int}
%type index_onconf {int}
%type orconf {int}
%type resolvetype {int}
onconf(A) ::= . {A = ON_CONFLICT_ACTION_DEFAULT;}
index_onconf(A) ::= . {A = ON_CONFLICT_ACTION_DEFAULT;}
index_onconf(A) ::= ON CONFLICT resolvetype(X). {A = X;}
onconf(A) ::= . {A = ON_CONFLICT_ACTION_ABORT;}
onconf(A) ::= ON CONFLICT resolvetype(X). {A = X;}
orconf(A) ::= . {A = ON_CONFLICT_ACTION_DEFAULT;}
orconf(A) ::= OR resolvetype(X). {A = X;}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment