Skip to content

fix(pgtype): return error instead of panicking on malformed geometric text#2566

Merged
jackc merged 1 commit into
jackc:masterfrom
ultramcu:fix/pgtype-geometric-parse-panic
May 30, 2026
Merged

fix(pgtype): return error instead of panicking on malformed geometric text#2566
jackc merged 1 commit into
jackc:masterfrom
ultramcu:fix/pgtype-geometric-parse-panic

Conversation

@ultramcu
Copy link
Copy Markdown
Contributor

Problem

The text scan plans for circle, box, lseg, path and polygon parse the value by calling strings.IndexByte to locate a , or ) separator and then slicing the string — without checking for the -1 "not found" result. Malformed text that is missing an expected separator therefore panics with slice bounds out of range [:-1] instead of returning an error.

This is reachable through the public database/sql Scanner API (e.g. Circle.Scan, or scanning a text-format column into one of these types), so malformed/corrupt input turns into a process-crashing panic rather than a normal scan error.

Repro (panics before this change):

var c pgtype.Circle
_ = c.Scan("<(123456789>") // panic: slice bounds out of range [:-1]

var b pgtype.Box
_ = b.Scan("(1234567890")  // panic

var l pgtype.Lseg
_ = l.Scan("[(123456789")  // panic

var p pgtype.Path
_ = p.Scan("((1234567")    // panic

var g pgtype.Polygon
_ = g.Scan("((1234567")    // panic

point.go already guards this correctly (it uses strings.Cut and returns "invalid format for point"); these five types were missed. This is the same class of malformed-input panic recently fixed for other types (#2507, #2519, #2520, #2522).

Fix

Guard every strings.IndexByte result with an if end == -1 { return fmt.Errorf("invalid format for <type>") } before slicing, matching the existing point.go behavior. Behavior for well-formed input is unchanged; this only turns a panic into a returned error (no public API change).

Tests

Adds (in pgtype/geometric_malformed_test.go, no database required):

  • TestGeometricScanMalformedReturnsError — each of the five types returns an error (no panic) on malformed input. Fails before this change (panics), passes after.
  • TestGeometricScanValid — well-formed values still parse correctly.

gofmt -l -s, go vet ./pgtype/, and go build ./... are clean.


Disclosure (per CONTRIBUTING.md): this is an AI-assisted contribution. The bug was surfaced by an automated audit; the fix and tests were written with AI assistance and reviewed and verified locally (fail-before / pass-after).

… text

The text scan plans for circle, box, lseg, path and polygon used the result
of strings.IndexByte to slice the input without checking for -1. Malformed
text missing a ',' or ')' separator caused a "slice bounds out of range
[:-1]" panic, reachable through the public database/sql Scanner API (e.g.
Circle.Scan). Guard each IndexByte and return an "invalid format" error,
matching the existing point.go behavior.

Adds TestGeometricScanMalformedReturnsError and TestGeometricScanValid.
@jackc jackc merged commit 71ffa5e into jackc:master May 30, 2026
@jackc
Copy link
Copy Markdown
Owner

jackc commented May 30, 2026

Merged with some additional fixes found during review.

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.

2 participants