Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions sqlite-vec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2206,20 +2206,20 @@ int vec0_parse_table_option(const char *source, int source_length,
vec0_scanner_init(&scanner, source, source_length);

rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
key = token.start;
keyLength = token.end - token.start;

rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME && token.token_type != TOKEN_TYPE_EQ) {
if (rc != VEC0_TOKEN_RESULT_SOME || token.token_type != TOKEN_TYPE_EQ) {
return SQLITE_EMPTY;
}

rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
!((token.token_type == TOKEN_TYPE_IDENTIFIER) ||
(token.token_type == TOKEN_TYPE_DIGIT))) {
return SQLITE_ERROR;
Expand Down Expand Up @@ -2262,7 +2262,7 @@ int vec0_parse_partition_key_definition(const char *source, int source_length,

// Check first token is identifier, will be the column name
int rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
Expand All @@ -2272,7 +2272,7 @@ int vec0_parse_partition_key_definition(const char *source, int source_length,

// Check the next token matches "text" or "integer", as column type
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
Expand All @@ -2289,7 +2289,7 @@ int vec0_parse_partition_key_definition(const char *source, int source_length,

// Check the next token is identifier and matches "partition"
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
Expand All @@ -2299,7 +2299,7 @@ int vec0_parse_partition_key_definition(const char *source, int source_length,

// Check the next token is identifier and matches "key"
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
Expand Down Expand Up @@ -2345,7 +2345,7 @@ int vec0_parse_auxiliary_column_definition(const char *source, int source_length
}

rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
Expand All @@ -2355,7 +2355,7 @@ int vec0_parse_auxiliary_column_definition(const char *source, int source_length

// Check the next token matches "text" or "integer", as column type
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
Expand Down Expand Up @@ -2477,7 +2477,7 @@ int vec0_parse_primary_key_definition(const char *source, int source_length,

// Check first token is identifier, will be the column name
int rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
Expand All @@ -2487,7 +2487,7 @@ int vec0_parse_primary_key_definition(const char *source, int source_length,

// Check the next token matches "text" or "integer", as column type
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
Expand All @@ -2504,7 +2504,7 @@ int vec0_parse_primary_key_definition(const char *source, int source_length,

// Check the next token is identifier and matches "primary"
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
Expand All @@ -2514,7 +2514,7 @@ int vec0_parse_primary_key_definition(const char *source, int source_length,

// Check the next token is identifier and matches "key"
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
Expand Down Expand Up @@ -2997,7 +2997,7 @@ int vec0_parse_vector_column(const char *source, int source_length,
// starts with an identifier
rc = vec0_scanner_next(&scanner, &token);

if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_EMPTY;
}
Expand Down Expand Up @@ -3026,13 +3026,13 @@ int vec0_parse_vector_column(const char *source, int source_length,

// left '[' bracket
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME && token.token_type != TOKEN_TYPE_LBRACKET) {
if (rc != VEC0_TOKEN_RESULT_SOME || token.token_type != TOKEN_TYPE_LBRACKET) {
return SQLITE_EMPTY;
}

// digit, for vector dimension length
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME && token.token_type != TOKEN_TYPE_DIGIT) {
if (rc != VEC0_TOKEN_RESULT_SOME || token.token_type != TOKEN_TYPE_DIGIT) {
return SQLITE_ERROR;
}
dimensions = atoi(token.start);
Expand All @@ -3042,7 +3042,7 @@ int vec0_parse_vector_column(const char *source, int source_length,

// // right ']' bracket
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME && token.token_type != TOKEN_TYPE_RBRACKET) {
if (rc != VEC0_TOKEN_RESULT_SOME || token.token_type != TOKEN_TYPE_RBRACKET) {
return SQLITE_ERROR;
}

Expand All @@ -3055,7 +3055,7 @@ int vec0_parse_vector_column(const char *source, int source_length,
break;
}

if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_ERROR;
}
Expand All @@ -3070,13 +3070,13 @@ int vec0_parse_vector_column(const char *source, int source_length,
}
// ensure equal sign after distance_metric
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME && token.token_type != TOKEN_TYPE_EQ) {
if (rc != VEC0_TOKEN_RESULT_SOME || token.token_type != TOKEN_TYPE_EQ) {
return SQLITE_ERROR;
}

// distance_metric value, an identifier (L2, cosine, etc)
rc = vec0_scanner_next(&scanner, &token);
if (rc != VEC0_TOKEN_RESULT_SOME &&
if (rc != VEC0_TOKEN_RESULT_SOME ||
token.token_type != TOKEN_TYPE_IDENTIFIER) {
return SQLITE_ERROR;
}
Expand Down
12 changes: 12 additions & 0 deletions tests/test-loadable.py
Original file line number Diff line number Diff line change
Expand Up @@ -2183,6 +2183,18 @@ def test_vec0_distance_metric():
]


def test_vec0_column_option_malformed_value():
# vec0_parse_vector_column's "option value" guard used to be:
# if (rc != VEC0_TOKEN_RESULT_SOME && token.token_type != TOKEN_TYPE_IDENTIFIER)
# With && instead of ||, hitting EOF right after "distance_metric=" left
# `token` uninitialised and the guard could spuriously not fire, falling
# through to use token.start/token.end (uninitialised) as the option value.
# Fixed to || so any non-identifier token (including EOF, where rc !=
# VEC0_TOKEN_RESULT_SOME) deterministically rejects the column definition.
with pytest.raises(sqlite3.DatabaseError):
db.execute("create virtual table t using vec0(a float[2] distance_metric=)")


def test_vec0_vacuum():
db = connect(EXT_PATH)
db.execute("create virtual table vec_t using vec0(a float[1]);")
Expand Down