Skip to content

fix(firestore): parse quoted field path names that end in a backslash - #18772

Open
sebxt wants to merge 1 commit into
googleapis:mainfrom
sebxt:fix/firestore-field-path-trailing-backslash
Open

sebxt wants to merge 1 commit into
googleapis:mainfrom
sebxt:fix/firestore-field-path-trailing-backslash

Conversation

@sebxt

@sebxt sebxt commented Oct 19, 2026

Copy link
Copy Markdown
  • Tests and linter pass
  • Code coverage does not decrease
  • Appropriate docs were updated (not needed)

FieldPath("dir\\", "file name").to_api_repr() produces `dir\\`.`file name`, but the tokenizer in field_path.py reads the escaped backslash plus the closing backtick as an escaped backtick. FieldPath.from_api_repr() then raises ValueError, and FieldPath.from_string() (used by update() and merge handling) falls back to splitting on . and returns parts that still include the backticks, so the write targets the wrong field.

This changes the QUOTED token pattern from r"`(?:\\`|[^`])*?`" to r"`(?:\\.|[^`\\])*`", so a backslash always consumes the character after it as an escape. Existing behavior for valid paths is unchanged, and an unterminated quoted name such as `a\`b.c.d is still rejected.

Tests added in tests/unit/v1/test_field_path.py for the tokenizer, parse_field_path, and a to_api_repr() / from_string() round trip. All three fail on main and pass with the change.

Fixes #<issue_number_goes_here>

Fixes #18771

Signed-off-by: Sebastian Turner <sebastiant3484@gmail.com>
@sebxt
sebxt requested a review from a team as a code owner October 19, 2026 19:17

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the regular expression for matching quoted elements in Firestore field paths to correctly handle trailing escaped backslashes, and adds corresponding unit tests. The review feedback suggests improving the regex to handle escaped newlines by matching any character (including newlines) instead of using a dot, and renaming a variable in the unit tests to avoid shadowing the imported field_path module.

PATH_ELEMENT_TOKENS = [
("SIMPLE", r"[_a-zA-Z][_a-zA-Z0-9]*"), # unquoted elements
("QUOTED", r"`(?:\\`|[^`])*?`"), # quoted elements, unquoted
("QUOTED", r"`(?:\\.|[^`\\])*`"), # quoted elements, unquoted

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The regex pattern uses \. to match escaped characters. However, in Python, the . character does not match newlines (\n) by default unless the re.DOTALL flag is active. If a field path contains an escaped newline, this pattern will fail to match.

To ensure robustness and handle any escaped character (including newlines) regardless of compilation flags, use \\[\s\S] instead of \. .

Suggested change
("QUOTED", r"`(?:\\.|[^`\\])*`"), # quoted elements, unquoted
("QUOTED", r"`(?:\\[\\s\\S]|[^`\\])*`"), # quoted elements, unquoted

Comment on lines +468 to +469
field_path = field_path.FieldPath.from_string(path_string)
assert field_path.parts == ("a\\", "b c")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Reassigning the variable field_path shadows the imported field_path module within the function scope. This makes the code fragile and harder to maintain or extend if other module-level attributes or classes need to be accessed later in the test.

Consider renaming the variable to parsed_path to avoid shadowing.

Suggested change
field_path = field_path.FieldPath.from_string(path_string)
assert field_path.parts == ("a\\", "b c")
parsed_path = field_path.FieldPath.from_string(path_string)
assert parsed_path.parts == ('a\\\\', 'b c')

This branch has not been deployed

No deployments
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.

firestore: field path with a quoted name ending in a backslash is misparsed

1 participant