mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
fix(chrome): validate attribute name in unknown-prefix branch
A selector like `foo]:has(*),body[x:value` previously produced [foo]:has(*),body[x="..."], a syntactically valid CSS selector that escaped the attribute match and selected `body`. Reject anything that isn't a plain HTML attribute name.
This commit is contained in:
1 parent
8c7470a1a6
commit
a69bac7abd
2 files changed
+24
No files matched your search
@@ -3,10 +3,16 @@ package chrome
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// attrNamePattern matches HTML attribute names that are safe to drop into a
|
||||
// CSS attribute selector without escaping. This avoids selectors like
|
||||
// `foo]:has(*),body[x="..."]` that would escape the intended match.
|
||||
var attrNamePattern = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9_-]*$`)
|
||||
|
||||
// TranslateStringSelector converts a legacy string selector ("id:foo",
|
||||
// "descPrefix:bar") into a CSS selector or XPath expression usable from the
|
||||
// chrome driver's TapSelector fallback path. The boolean return is true when
|
||||
@@ -41,6 +47,9 @@ func TranslateStringSelector(selector string) (string, bool, error) {
|
||||
case "placeholder", "placeholderValue", "hintText":
|
||||
return `[placeholder="` + cssEscape(value) + `"]`, false, nil
|
||||
default:
|
||||
if !attrNamePattern.MatchString(kind) {
|
||||
return "", false, fmt.Errorf("unsafe selector prefix %q", kind)
|
||||
}
|
||||
return `[` + kind + `="` + cssEscape(value) + `"]`, false, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,21 @@ func TestTranslateStringSelector_RejectsMissingPrefix(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTranslateStringSelector_RejectsUnsafePrefix(t *testing.T) {
|
||||
cases := []string{
|
||||
`foo]:has(*),body[x:value`,
|
||||
`x y:value`,
|
||||
`x"y:value`,
|
||||
`*:value`,
|
||||
`(:value`,
|
||||
}
|
||||
for _, selector := range cases {
|
||||
if _, _, err := TranslateStringSelector(selector); err == nil {
|
||||
t.Errorf("%q: expected error for unsafe prefix", selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCSSEscape_ControlCharactersAndNUL(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
|
||||
Reference in new issue
Block a user