Skip to content

Commit

Permalink
Fixing issues with escaping single characters
Browse files Browse the repository at this point in the history
  • Loading branch information
kenshaw committed Oct 26, 2024
1 parent 4aba43b commit 59a557c
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 10 deletions.
9 changes: 4 additions & 5 deletions stmt/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,11 @@ func readVarName(r []rune, i, end int, q rune) (int, rune) {
// A command is defined as the first non-blank text after \, followed by
// parameters up to either the next \ or a control character (for example, \n):
func readCommand(r []rune, i, end int) (int, int) {
command:
// find end of command
c, next := rune(0), rune(0)
command:
for ; i < end; i++ {
next := grab(r, i+1, end)
switch {
switch next = grab(r, i+1, end); {
case next == 0:
return end, end
case next == '\\' || unicode.IsControl(next):
Expand All @@ -196,8 +196,7 @@ command:
params:
// find end of params
for ; i < end; i++ {
c, next := r[i], grab(r, i+1, end)
switch {
switch c, next = r[i], grab(r, i+1, end); {
case next == 0:
return cmd, end
case quote == 0 && (c == '\'' || c == '"' || c == '`'):
Expand Down
2 changes: 1 addition & 1 deletion stmt/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ func TestSubstituteVar(t *testing.T) {
for i, test := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
z := []rune(test.s)
y, l := substituteVar(z, test.v, test.sub)
y, l := test.v.Substitute(z, test.sub, true)
if sl := len([]rune(test.sub)); test.v.Len != sl {
t.Errorf("expected v.Len to be %d, got: %d", sl, test.v.Len)
}
Expand Down
10 changes: 6 additions & 4 deletions stmt/stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (b *Stmt) RawString() string {
i, s, z := 0, string(b.Buf), new(bytes.Buffer)
// deinterpolate vars
for _, v := range b.Vars {
if !v.Defined {
if !v.Defined && v.Quote != '\\' {
continue
}
if len(s) > i {
Expand Down Expand Up @@ -222,8 +222,6 @@ parse:
case b.quote != 0 || b.multilineComment || b.balanceCount != 0:
// skip escaped backslash, semicolon, colon
case c == '\\' && (next == '\\' || next == ';' || next == ':'):
// FIXME: the below works, but it may not make sense to keep this enabled.
// FIXME: also, the behavior is slightly different than psql
v := &Var{
I: i,
End: i + 2,
Expand All @@ -234,6 +232,7 @@ parse:
if b.r, b.rlen = v.Substitute(b.r, string(next), false); b.Len != 0 {
v.I += b.Len + 1
}
i++
// start of command
case c == '\\':
// parse command and params end positions
Expand Down Expand Up @@ -373,7 +372,10 @@ func (v *Var) String() string {

// Substitute substitutes part of r, with s.
func (v *Var) Substitute(r []rune, s string, ok bool) ([]rune, int) {
if v.Quote == '?' {
switch v.Quote {
case '\\':
s = "\\" + s
case '?':
s = trueFalse(ok)
}
sr, rcap := []rune(s), cap(r)
Expand Down

0 comments on commit 59a557c

Please sign in to comment.