Skip to content

Commit 4e19a75

Browse files
committed
product: fix CREATE DATABASE failure on special characters
The PostgreSQL path of _create_database() interpolated the user-supplied database name directly into a CREATE DATABASE statement via an f-string. This caused syntax errors for any name that is not a legal unquoted PostgreSQL identifier - in particular names containing a dash (e.g. 'test-product') or starting with a digit (e.g. '1team') - both reported by users via the GUI's product creation dialog. SQLAlchemy does not auto-quote identifiers in free-form text() clauses, so the fix has two parts: * Quote the identifier explicitly using the dialect's IdentifierPreparer before embedding it in the statement. This produces a properly double-quoted name such as CREATE DATABASE "test-product", which PostgreSQL accepts. * Validate the database name in addProduct() using the new is_valid_postgresql_db_name() helper, so that inputs containing quotes, semicolons, whitespace, control characters, or that exceed PostgreSQL's 63-byte identifier limit are rejected with a clear error message before any SQL is issued, rather than crashing later with an opaque driver error.
1 parent c92bf27 commit 4e19a75

1 file changed

Lines changed: 18 additions & 2 deletions

File tree

web/server/codechecker_server/api/product_server.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
from .. import permissions
3232
from ..database.config_db_model import IDENTIFIER, Product, ProductPermission
3333
from ..database.database import DBSession, SQLServer, conv, escape_like
34-
from ..routing import is_valid_product_endpoint
34+
from ..routing import is_valid_product_endpoint, is_valid_postgresql_db_name
3535

3636
from .thrift_enum_helper import confidentiality_enum, \
3737
confidentiality_str
@@ -368,7 +368,10 @@ def __create_product_database(self, product):
368368
with engine.connect() as conn:
369369
conn.execute(text("commit"))
370370
LOG.info("Creating database '%s'", db_name)
371-
conn.execute(text(f"CREATE DATABASE {db_name}"))
371+
quoted_db_name = engine.dialect.identifier_preparer \
372+
.quote_identifier(db_name)
373+
conn.execute(
374+
text(f"CREATE DATABASE {quoted_db_name}"))
372375
conn.close()
373376
except exc.ProgrammingError as e:
374377
LOG.error("ProgrammingError occurred: %s", str(e))
@@ -411,6 +414,19 @@ def addProduct(self, product):
411414
codechecker_api_shared.ttypes.ErrorCode.GENERAL,
412415
msg)
413416

417+
if dbc.engine == 'postgresql' \
418+
and not is_valid_postgresql_db_name(dbc.database):
419+
msg = (
420+
f"The specified PostgreSQL database name "
421+
f"'{dbc.database}' contains characters that are "
422+
"not allowed (quotes, semicolons, whitespace, or "
423+
"control characters), or is empty, or exceeds "
424+
"PostgreSQL's 63-byte identifier limit.")
425+
LOG.error(msg)
426+
raise codechecker_api_shared.ttypes.RequestFailed(
427+
codechecker_api_shared.ttypes.ErrorCode.DATABASE,
428+
msg)
429+
414430
if self.__server.get_product(product.endpoint):
415431
msg = \
416432
f"A product endpoint '/{product.endpoint}' is already " \

0 commit comments

Comments
 (0)