From d6cd0e819198f9805fb303e31fe4efb4d6de2fd7 Mon Sep 17 00:00:00 2001 From: mappu Date: Tue, 7 Apr 2020 22:51:31 +1200 Subject: [PATCH] node: parse and requote php single-quoted strings --- node.go | 10 ++++++++-- quote.go | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 quote.go diff --git a/node.go b/node.go index d0833d5..b2dfac9 100644 --- a/node.go +++ b/node.go @@ -927,8 +927,14 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) return n.Value, nil // number formats are compatible case *scalar.String: - return n.Value, nil // It's already quoted in PHP format - // return strconv.Quote(n.Value), nil // Go source code quoting format + // We need to transform the string format - e.g. Go does not support + // single-quoted strings + rawValue, err := phpUnquote(n.Value) + if err != nil { + return "", parseErr{n, err} + } + + return strconv.Quote(rawValue), nil // Go source code quoting format // // diff --git a/quote.go b/quote.go new file mode 100644 index 0000000..c098ed5 --- /dev/null +++ b/quote.go @@ -0,0 +1,26 @@ +package main + +import ( + "errors" + "strconv" + "strings" +) + +func phpUnquote(s string) (string, error) { + if len(s) == 0 { + return "", errors.New("expected quotes around string") + } + + if s[0] == '"' { + // Quote system is similar enough to Go's that strconv will probably just work + return strconv.Unquote(s) + } + + if s[0] == '\'' { + // Single-quotes escape fewer things + unSQuo := strings.NewReplacer(`\'`, `'`, `\\`, `\`) + return unSQuo.Replace(s[1 : len(s)-1]), nil + } + + return "", errors.New("expected single/double quotes") +}