Skip to content

Sanitize column names after applying column name transformation#38

Merged
klaidliadon merged 3 commits intomasterfrom
fix-escape
Feb 12, 2026
Merged

Sanitize column names after applying column name transformation#38
klaidliadon merged 3 commits intomasterfrom
fix-escape

Conversation

@klaidliadon
Copy link
Contributor

No description provided.

This comment was marked as outdated.

@klaidliadon klaidliadon merged commit dfb0f24 into master Feb 12, 2026
1 check passed
@klaidliadon klaidliadon deleted the fix-escape branch February 12, 2026 12:43
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (1)

page.go:66

  • NewPage no longer applies defaults when size/page are passed as 0. This is a behavior change for callers that relied on NewPage(0,0) producing {Size: DefaultPageSize, Page: 1} immediately (before passing it into PrepareQuery). If this change is intentional, it should be documented; otherwise consider restoring the previous defaulting behavior in NewPage.
func NewPage(size, page uint32, sort ...Sort) *Page {
	return &Page{
		Size: size,
		Page: page,
		Sort: sort,
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +87 to 89
func (p *Page) GetOrder(columnFunc func(string) string, defaultSort ...string) []Sort {
var sorts []Sort
if p != nil && len(p.Sort) != 0 {
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

Page.GetOrder changed signature to require a columnFunc parameter. Since GetOrder is exported, this is a breaking API change for downstream users. If the goal is to apply ColumnFunc before sanitization, consider keeping the original GetOrder(...defaultSort) API and handling ColumnFunc inside Paginator.getOrder (or add a new method and keep the old one for compatibility).

Copilot uses AI. Check for mistakes.
sql, args, err := query.ToSql()
require.NoError(t, err)
require.Equal(t, "SELECT * FROM t ORDER BY id ASC LIMIT 6 OFFSET 0", sql)
require.Equal(t, `SELECT * FROM t ORDER BY "id" ASC LIMIT 3 OFFSET 0`, sql)
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

With column sanitization now happening after ColumnFunc (via pgx.Identifier(...).Sanitize()), the default sort column should be quoted consistently (as in the other tests). This assertion likely needs to expect ORDER BY "id" ASC ... rather than ORDER BY id ASC ....

Copilot uses AI. Check for mistakes.

limit, offset := page.Limit(), page.Offset()

q = q + " ORDER BY " + strings.Join(p.getOrder(page), ", ")
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

PrepareRaw unconditionally appends ORDER BY ... to the raw query string. If p.getOrder(page) returns an empty slice (e.g., no default sort configured and no page sort/column provided), this generates invalid SQL (... ORDER BY LIMIT ...). Consider only appending the ORDER BY clause when there is at least one sort term.

Suggested change
q = q + " ORDER BY " + strings.Join(p.getOrder(page), ", ")
orders := p.getOrder(page)
if len(orders) > 0 {
q = q + " ORDER BY " + strings.Join(orders, ", ")
}

Copilot uses AI. Check for mistakes.
Comment on lines +240 to +244
if page == nil {
page = &Page{}
}
page.SetDefaults(&p.settings)

Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

PrepareRaw may return a query containing @limit/@offset without adding the corresponding pgx.NamedArgs when args is empty, because the current loop only appends named args inside the for range args body. Add an explicit if len(args)==0 { args = append(args, pgx.NamedArgs{...}) } (or similar) before the loop.

Copilot uses AI. Check for mistakes.
return ""
}
s.Order = sanitizeOrder(s.Order)
return fmt.Sprintf("%s %s", s.Column, s.Order)
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

Sort.String() no longer normalizes/sanitizes Order (and no longer guards against empty Column). Since Sort and String() are exported, this is a behavioral/security regression for any external callers building SQL using Sort.String(). Consider restoring the previous behavior (normalize order to ASC/DESC, and return "" when Column is empty) or making stringification explicitly unsafe/unexported.

Suggested change
return fmt.Sprintf("%s %s", s.Column, s.Order)
if s.Column == "" {
return ""
}
order := strings.ToUpper(strings.TrimSpace(string(s.Order)))
switch order {
case "DESC":
order = "DESC"
default:
order = "ASC"
}
return fmt.Sprintf("%s %s", s.Column, order)

Copilot uses AI. Check for mistakes.
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

Comments