Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unquote function panics when an escape character exists in string. #295

Closed
krum110487 opened this issue Feb 20, 2023 · 4 comments
Closed

Comments

@krum110487
Copy link

krum110487 commented Feb 20, 2023

I found a bug in the function "unquote" where if there is a "\" in the string it fails.
Here is an example of it broken.

func main() {
	example := "'te\\st'"
	s, err := unquote(example)
	if err != nil {
		panic(err)
	}
	fmt.Println(s)
}

func unquote(s string) (string, error) {
	quote := s[0]
	s = s[1 : len(s)-1]
	out := ""
	for s != "" {
		value, _, tail, err := strconv.UnquoteChar(s, quote)
		if err != nil {
			return "", err
		}
		s = tail
		out += string(value)
	}
	return out, nil
}

I just pulled the unquote from the code to test it. I did this to fix it.

func unquote(s string) (string, error) {
	quote := s[0]
	s = s[1 : len(s)-1]
	out := ""
	for s != "" {
		if s[:1] == "\\" {
			out += "\\"
			s = s[1:len(s)]
			continue
		}
		value, _, tail, err := strconv.UnquoteChar(s, quote)
		if err != nil {
			return "", err
		}
		s = tail
		out += string(value)
	}
	return out, nil
}

Basically, the issue is if the string starts with a \, it will error in "UnquoteChar" which is why I am skipping it and manually adding it. Not sure if this is the "Best" approach, but it gets the point around.

It could also be fixed by replacing \\ with \\\\ before processing.

@alecthomas
Copy link
Owner

alecthomas commented Feb 21, 2023

There may be a bug, but your test case is not one. In this case:

	example := "'te\\st'"

The Go parser is unquoting the \\, so what Participle sees is \s. If you change this to use backticks, Participle behaves as you would expect because Go is no longer unescaping:

	example := `'te\\st'`

@krum110487
Copy link
Author

krum110487 commented Feb 21, 2023

Why would my example be wrong, I was unquoting text which is sometimes regex which is literally a \s and not \\s and it errored, I know I can escape it, are you saying I have to escape all backslashes in strings by writing my own custom consumer? I would expect the built in unquoting to do fl that instead of erroring.

@alecthomas
Copy link
Owner

alecthomas commented Feb 21, 2023

The builtin unquote uses Go's unquoting rules, which doesn't support \s. If you want to support something else you'll need to roll your own.

@krum110487
Copy link
Author

The builtin unquote uses Go's unquoting rules, which doesn't support \s. If you want to support something else you'll need to roll your own.

got ya, ok I understand! Thank you for responding. May I recommend an EscapeQuoted String property than, to maybe allow it to work out of the box? Thank you!

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

No branches or pull requests

2 participants