Skip to content

Fix pg array parsing dropping backslashes in quoted elements - #6181

Open
eeshsaxena wants to merge 1 commit into
drizzle-team:mainfrom
eeshsaxena:fix/pg-array-backslash-unescape
Open

Fix pg array parsing dropping backslashes in quoted elements#6181
eeshsaxena wants to merge 1 commit into
drizzle-team:mainfrom
eeshsaxena:fix/pg-array-backslash-unescape

Conversation

@eeshsaxena

Copy link
Copy Markdown

What / Why

parsePgArrayValue unescapes a quoted Postgres array element with .replace(/\\/g, ''), which strips every backslash. That is right for an escaped quote (\"") but wrong for an escaped backslash (\\ should become a single \, not be removed). So a text[] / varchar[] value containing a backslash is corrupted on read.

Postgres doubles backslashes in its array output, so:

-- stored value is the string  a\b
select array['a\b']::text[];   -- wire format: {"a\\b"}

Reading that back through Drizzle today:

table.col.mapFromDriverValue('{"a\\\\b"}')            // => ['ab']            ❌ (should be ['a\b'])
table.col.mapFromDriverValue('{"c:\\\\temp\\\\x"}')   // => ['c:tempx']       ❌ (should be ['c:\temp\x'])

Any array value with a backslash is affected: Windows paths, regex patterns, LaTeX, escape sequences, etc.

Fix

Unescape with .replace(/\\(.)/g, '$1') so a backslash escapes the following character. This is the inverse of what makePgArray produces (it escapes \\\ and "\") and matches how Postgres formats array output.

  • Escaped backslashes now round-trip: {"a\\b"}['a\b'].
  • Escaped quotes are unchanged: {"a\"b"}['a"b'] (already covered by existing tests, still green).

Added tests for escaped backslashes and for a value containing both an escaped backslash and an escaped quote.

Testing

I verified the fixed parsePgArrayValue/parsePgNestedArray against every existing parsePgArray test input (all still pass) plus the new backslash cases. I wasn't able to spin up the full monorepo test run locally (slow dependency install in my environment), so I'd appreciate CI running the parsePgArray suite.

parsePgArrayValue unescaped a quoted array element with .replace(/\\/g, ''),
which strips every backslash. That is correct for an escaped quote (\" -> ")
but wrong for an escaped backslash (\\ -> should be \, not ''), so a text[]
value containing a backslash was corrupted on read: Postgres output {"a\\b"}
(the string a\b) parsed to 'ab', and a Windows path c:\temp\x parsed to
c:tempx.

Unescape with .replace(/\\(.)/g, '$1') so a backslash escapes the following
character, matching how makePgArray escapes and how Postgres formats array
output. Escaped quotes are unchanged. Adds tests for escaped backslashes.
@eeshsaxena

Copy link
Copy Markdown
Author

Worth flagging the blast radius: this hits any array column whose values can contain a backslash, so Windows paths, regex patterns, and escape sequences in a text[] silently lose data on read, and it is a read-path corruption rather than a crash so it can go unnoticed. The fix is a one-character-class change to the unescape and it leaves the escaped-quote handling and all existing tests untouched.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant