Skip to content

Fix BLOB insert from URL failing on root context-path#1119

Merged
iroqueta merged 2 commits into
masterfrom
fix/blobfile-empty-contextpath-and-null-sqlstate
Jun 3, 2026
Merged

Fix BLOB insert from URL failing on root context-path#1119
iroqueta merged 2 commits into
masterfrom
fix/blobfile-empty-contextpath-and-null-sqlstate

Conversation

@iroqueta
Copy link
Copy Markdown
Collaborator

@iroqueta iroqueta commented Jun 3, 2026

Problem

Inserting a record whose BLOB / multimedia attribute is set from a URL fails on apps deployed at the root context-path (/).

When binding the parameters, setBLOBFile / setGXDbFileURI try to strip the servlet context path from the temp file name. For a root-context app, getContextPath() returns "" (per servlet spec), so:

  • fileName.startsWith("") is always true
  • replaceFirst("", "").substring(1) (and substring(0 + 1)) strips the first character of the path
    • e.g. PublicTempStorage\3840px-rialto.jpgublicTempStorage\3840px-rialto.jpg

The corrupted path can't be found when the blob is read back, throwing SQLException("The filename does not exists in url ...") and aborting the insert.

The real error was additionally masked by a NullPointerException: GXDBMSpostgresql classifies the SQLException via getSQLState().toLowerCase() / getMessage().toLowerCase() without a null check, and the SQLException above (built with new SQLException(msg)) has a null SQLState — so the error handler threw an NPE instead of surfacing the real message.

Changes

GXPreparedStatement.javasetBLOBFile / setGXDbFileURI

  • Only strip the context-path prefix when it is non-empty and the file name actually starts with it. An empty context path (root deployment) is a legitimate value and must not corrupt the path.

GXDBMSpostgresql.javaObjectLocked / DuplicateKeyValue / ObjectNotFound

  • Added null-safe safeSQLState(e) / safeMessage(e) helpers so a SQLException with a null SQLState/message no longer triggers an NPE in the error classifier (which was hiding the real error).

How to reproduce

  1. Deploy a KB at root context-path (/).
  2. In a transaction with an Image/BLOB attribute, save a record setting the image from a remote URL.
  3. Before the fix: HTTP 500, internal error The filename does not exists in url ublicTempStorage\... (note the stripped first character).
  4. After the fix: the blob is stored and the record is inserted correctly.

When inserting a record whose BLOB/multimedia attribute is set from a URL,
setBLOBFile/setGXDbFileURI tried to strip the servlet context path from the
temp file name. For apps deployed at the root context-path ("/"),
getContextPath() returns "" (per servlet spec), so:

  - fileName.startsWith("") is always true
  - replaceFirst("","").substring(1) / substring(0+1) strips the first
    character of the path (e.g. "PublicTempStorage\..." -> "ublicTempStorage\...")

The corrupted path is not found when the blob is read back, throwing
SQLException("The filename does not exists in url ...") and aborting the insert.

Guard the prefix strip so it only runs when the context path is non-empty
and the file name actually starts with it.

Also harden GXDBMSpostgresql error classification: ObjectLocked/
DuplicateKeyValue/ObjectNotFound called getSQLState()/getMessage().toLowerCase()
without a null check. A SQLException with a null SQLState (such as the one
above, built via new SQLException(msg)) caused a NullPointerException in the
error handler, masking the real error. Use null-safe helpers.
@genexusbot
Copy link
Copy Markdown
Collaborator

Cherry pick to beta success

Comment thread java/src/main/java/com/genexus/db/driver/GXPreparedStatement.java Fixed
replaceFirst() treats its argument as a regular expression, so using the
context path as the pattern could misbehave if it contained regex
metacharacters (flagged by CodeQL as regular expression injection).

Since fileName.startsWith(ctxPath) is already checked, remove the prefix
with a literal substring(ctxPath.length() + 1), matching what the non-web
branch already does.
@genexusbot
Copy link
Copy Markdown
Collaborator

Cherry pick to beta success

@iroqueta iroqueta merged commit 305c6c2 into master Jun 3, 2026
10 checks passed
@iroqueta iroqueta deleted the fix/blobfile-empty-contextpath-and-null-sqlstate branch June 3, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants