Shouldn't rewrite dot in a string to index syntax (#502)
Co-authored-by: Casey Lee <cplee@nektos.com>
This commit is contained in:
		| @@ -16,10 +16,9 @@ import ( | ||||
| 	"gopkg.in/godo.v2/glob" | ||||
| ) | ||||
|  | ||||
| var contextPattern, expressionPattern, operatorPattern *regexp.Regexp | ||||
| var expressionPattern, operatorPattern *regexp.Regexp | ||||
|  | ||||
| func init() { | ||||
| 	contextPattern = regexp.MustCompile(`^([^.]*(?:\[.+])*)(?:\.([\w-]+))?(.*)$`) | ||||
| 	expressionPattern = regexp.MustCompile(`\${{\s*(.+?)\s*}}`) | ||||
| 	operatorPattern = regexp.MustCompile("^[!=><|&]+$") | ||||
| } | ||||
| @@ -123,22 +122,88 @@ func (ee *expressionEvaluator) InterpolateWithStringCheck(in string) (string, bo | ||||
| // Rewrite tries to transform any javascript property accessor into its bracket notation. | ||||
| // For instance, "object.property" would become "object['property']". | ||||
| func (ee *expressionEvaluator) Rewrite(in string) string { | ||||
| 	re := in | ||||
| 	var buf strings.Builder | ||||
| 	r := strings.NewReader(in) | ||||
| 	for { | ||||
| 		matches := contextPattern.FindStringSubmatch(re) | ||||
| 		if matches == nil { | ||||
| 			// No global match, we're done! | ||||
| 		c, _, err := r.ReadRune() | ||||
| 		if err == io.EOF { | ||||
| 			break | ||||
| 		} | ||||
| 		if matches[2] == "" { | ||||
| 			// No property match, we're done! | ||||
| 			break | ||||
| 		//nolint | ||||
| 		switch { | ||||
| 		default: | ||||
| 			buf.WriteRune(c) | ||||
| 		case c == '\'': | ||||
| 			buf.WriteRune(c) | ||||
| 			ee.advString(&buf, r) | ||||
| 		case c == '.': | ||||
| 			buf.WriteString("['") | ||||
| 			ee.advPropertyName(&buf, r) | ||||
| 			buf.WriteString("']") | ||||
| 		} | ||||
|  | ||||
| 		re = fmt.Sprintf("%s['%s']%s", matches[1], matches[2], matches[3]) | ||||
| 	} | ||||
| 	return buf.String() | ||||
| } | ||||
|  | ||||
| 	return re | ||||
| func (*expressionEvaluator) advString(w *strings.Builder, r *strings.Reader) error { | ||||
| 	for { | ||||
| 		c, _, err := r.ReadRune() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if c != '\'' { | ||||
| 			w.WriteRune(c) //nolint | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// Handles a escaped string: ex. 'It''s ok' | ||||
| 		c, _, err = r.ReadRune() | ||||
| 		if err != nil { | ||||
| 			w.WriteString("'") //nolint | ||||
| 			return err | ||||
| 		} | ||||
| 		if c != '\'' { | ||||
| 			w.WriteString("'") //nolint | ||||
| 			if err := r.UnreadRune(); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			break | ||||
| 		} | ||||
| 		w.WriteString(`\'`) //nolint | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (*expressionEvaluator) advPropertyName(w *strings.Builder, r *strings.Reader) error { | ||||
| 	for { | ||||
| 		c, _, err := r.ReadRune() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if !isLetter(c) { | ||||
| 			if err := r.UnreadRune(); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			break | ||||
| 		} | ||||
| 		w.WriteRune(c) //nolint | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func isLetter(c rune) bool { | ||||
| 	switch { | ||||
| 	case c >= 'a' && c <= 'z': | ||||
| 		return true | ||||
| 	case c >= 'A' && c <= 'Z': | ||||
| 		return true | ||||
| 	case c >= '0' && c <= '9': | ||||
| 		return true | ||||
| 	case c == '_' || c == '-': | ||||
| 		return true | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (rc *RunContext) newVM() *otto.Otto { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user