[gxml] CssSelectorParser: improve attribute pasing
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml] CssSelectorParser: improve attribute pasing
- Date: Fri, 29 Sep 2017 16:26:08 +0000 (UTC)
commit a93bd5b35b4b5c0492f3579b67213dac2a633f2c
Author: Yannick Inizan <inizan yannick gmail com>
Date: Fri Sep 29 09:21:52 2017 -0700
CssSelectorParser: improve attribute pasing
Fixes bug:
https://bugzilla.gnome.org/show_bug.cgi?id=788129
gxml/CssSelectorParser.vala | 34 +++++++++---
test/CssSelectorTest.vala | 122 +++++++++++++++++++++++++++----------------
2 files changed, 102 insertions(+), 54 deletions(-)
---
diff --git a/gxml/CssSelectorParser.vala b/gxml/CssSelectorParser.vala
index b8a3e1a..12d78ca 100644
--- a/gxml/CssSelectorParser.vala
+++ b/gxml/CssSelectorParser.vala
@@ -73,6 +73,20 @@ public class GXml.CssSelectorParser : GLib.Object {
list = new Gee.ArrayList<CssSelectorData?>();
}
+ static bool is_valid_identifier (string data) {
+ unichar u = 0;
+ int index = 0;
+ while (data.get_next_char (ref index, out u))
+ if (u == '[' || u == ']' || u == '{' || u == '}' ||
+ u == '$' || u == '&' || u == '#' || u == '|' ||
+ u == '`' || u == '^' || u == '@' || u == '+' ||
+ u == '~' || u == '*' || u == '%' || u == '!' ||
+ u == '?' || u == '<' || u == '>' || u == '"' ||
+ u == '\'')
+ return false;
+ return true;
+ }
+
void parse_class (string css, ref int position) {
CssSelectorData idata = new CssSelectorData.with_values (CssSelectorType.INSIDE, "", "");
list.add (idata);
@@ -124,7 +138,7 @@ public class GXml.CssSelectorParser : GLib.Object {
if (!u.isalnum())
throw new CssSelectorError.ATTRIBUTE (_("Invalid attribute character"));
sb.append_unichar (u);
- while (css.get_next_char (ref position, out u) && u.isalnum())
+ while (css.get_next_char (ref position, out u) && (u.isalnum() || u == '-'))
sb.append_unichar (u);
while (u.isspace())
css.get_next_char (ref position, out u);
@@ -143,11 +157,12 @@ public class GXml.CssSelectorParser : GLib.Object {
s = u;
css.get_next_char (ref position, out u);
}
- if (!u.isalnum())
- throw new CssSelectorError.ATTRIBUTE (_("Invalid attribute selector
character"));
- sb1.append_unichar (u);
- while (css.get_next_char (ref position, out u) && (u.isalnum() || u.isspace()))
+ if (s != 0 || is_valid_identifier (u.to_string()))
+ sb1.append_unichar (u);
+ while (css.get_next_char (ref position, out u) && (s != 0 ? u != s : u != ']'))
sb1.append_unichar (u);
+ if (s == 0 && !is_valid_identifier (sb1.str))
+ throw new CssSelectorError.ATTRIBUTE (_("Invalid attribute selector value :
%s").printf (sb1.str));
if (s != 0) {
if (u != s)
throw new CssSelectorError.STRING (_("Invalid end of attribute
value"));
@@ -188,11 +203,12 @@ public class GXml.CssSelectorParser : GLib.Object {
s = u;
css.get_next_char (ref position, out u);
}
- if (!u.isalnum())
- throw new CssSelectorError.ATTRIBUTE (_("Invalid attribute selector character 2
(%s)").printf (u.to_string()));
- sb1.append_unichar (u);
- while (css.get_next_char (ref position, out u) && (u.isalnum() || u.isspace()))
+ if (s != 0 || is_valid_identifier (u.to_string()))
+ sb1.append_unichar (u);
+ while (css.get_next_char (ref position, out u) && (s != 0 ? u != s : u != ']'))
sb1.append_unichar (u);
+ if (s == 0 && !is_valid_identifier (sb1.str))
+ throw new CssSelectorError.ATTRIBUTE (_("Invalid attribute selector value :
%s").printf (sb1.str));
if (s != 0) {
if (u != s)
throw new CssSelectorError.STRING (_("Invalid end of attribute value"));
diff --git a/test/CssSelectorTest.vala b/test/CssSelectorTest.vala
index bc49c1e..a008d29 100644
--- a/test/CssSelectorTest.vala
+++ b/test/CssSelectorTest.vala
@@ -65,7 +65,7 @@ class CssSelectorTest : GXmlTest {
Test.add_func ("/gxml/css-selector/element/attribute/value", () => {
try {
var cp = new CssSelectorParser ();
- cp.parse ("child[prop]");
+ cp.parse ("child[prop-name]");
assert (cp.selectors.size == 3);
var s = cp.selectors[0];
assert (s != null);
@@ -82,7 +82,7 @@ class CssSelectorTest : GXmlTest {
var c1 = d.create_element ("child");
r.append_child (c1);
var c2 = d.create_element ("child");
- c2.set_attribute ("prop", "val");
+ c2.set_attribute ("prop-name", "val");
r.append_child (c2);
assert (!cp.match (r));
assert (!cp.match (c1));
@@ -94,7 +94,7 @@ class CssSelectorTest : GXmlTest {
Test.add_func ("/gxml/css-selector/element/attribute/contains", () => {
try {
var cp = new CssSelectorParser ();
- cp.parse ("child[prop~=\"val\"]");
+ cp.parse ("child[prop-name~=\"val\"]");
assert (cp.selectors.size == 3);
var s = cp.selectors[0];
assert (s != null);
@@ -111,13 +111,13 @@ class CssSelectorTest : GXmlTest {
var c1 = d.create_element ("child");
r.append_child (c1);
var c2 = d.create_element ("child");
- c2.set_attribute ("prop", "val calc soup");
+ c2.set_attribute ("prop-name", "val calc soup");
r.append_child (c2);
var c3 = d.create_element ("child");
- c3.set_attribute ("prop", "calc val soup");
+ c3.set_attribute ("prop-name", "calc val soup");
r.append_child (c3);
var c4 = d.create_element ("child");
- c4.set_attribute ("prop", "calc secondary soup");
+ c4.set_attribute ("prop-name", "calc secondary soup");
r.append_child (c4);
assert (!cp.match (r));
assert (!cp.match (c1));
@@ -131,7 +131,7 @@ class CssSelectorTest : GXmlTest {
Test.add_func ("/gxml/css-selector/element/attribute/starts_with", () => {
try {
var cp = new CssSelectorParser ();
- cp.parse ("child[prop^=\"val\"]");
+ cp.parse ("child[prop-name^=\"val\"]");
assert (cp.selectors.size == 3);
var s = cp.selectors[0];
assert (s != null);
@@ -148,13 +148,13 @@ class CssSelectorTest : GXmlTest {
var c1 = d.create_element ("child");
r.append_child (c1);
var c2 = d.create_element ("child");
- c2.set_attribute ("prop", "val");
+ c2.set_attribute ("prop-name", "val");
r.append_child (c2);
var c3 = d.create_element ("child");
- c3.set_attribute ("prop", "value");
+ c3.set_attribute ("prop-name", "value");
r.append_child (c3);
var c4 = d.create_element ("child");
- c4.set_attribute ("prop", "secondaryvalue");
+ c4.set_attribute ("prop-name", "secondaryvalue");
r.append_child (c4);
assert (!cp.match (r));
assert (!cp.match (c1));
@@ -168,7 +168,7 @@ class CssSelectorTest : GXmlTest {
Test.add_func ("/gxml/css-selector/element/attribute/starts_with_hyphen", () => {
try {
var cp = new CssSelectorParser ();
- cp.parse ("child[prop|=\"val\"]");
+ cp.parse ("child[prop-name|=\"val\"]");
assert (cp.selectors.size == 3);
var s = cp.selectors[0];
assert (s != null);
@@ -185,13 +185,13 @@ class CssSelectorTest : GXmlTest {
var c1 = d.create_element ("child");
r.append_child (c1);
var c2 = d.create_element ("child");
- c2.set_attribute ("prop", "val-");
+ c2.set_attribute ("prop-name", "val-");
r.append_child (c2);
var c3 = d.create_element ("child");
- c3.set_attribute ("prop", "value");
+ c3.set_attribute ("prop-name", "value");
r.append_child (c3);
var c4 = d.create_element ("child");
- c4.set_attribute ("prop", "secondaryvalue");
+ c4.set_attribute ("prop-name", "secondaryvalue");
r.append_child (c4);
assert (!cp.match (r));
assert (!cp.match (c1));
@@ -205,7 +205,7 @@ class CssSelectorTest : GXmlTest {
Test.add_func ("/gxml/css-selector/element/attribute/ends_with", () => {
try {
var cp = new CssSelectorParser ();
- cp.parse ("child[prop$=\"val\"]");
+ cp.parse ("child[prop-name$=\"val\"]");
assert (cp.selectors.size == 3);
var s = cp.selectors[0];
assert (s != null);
@@ -222,13 +222,13 @@ class CssSelectorTest : GXmlTest {
var c1 = d.create_element ("child");
r.append_child (c1);
var c2 = d.create_element ("child");
- c2.set_attribute ("prop", "subval");
+ c2.set_attribute ("prop-name", "subval");
r.append_child (c2);
var c3 = d.create_element ("child");
- c3.set_attribute ("prop", "techval");
+ c3.set_attribute ("prop-name", "techval");
r.append_child (c3);
var c4 = d.create_element ("child");
- c4.set_attribute ("prop", "secondaryvalue");
+ c4.set_attribute ("prop-name", "secondaryvalue");
r.append_child (c4);
assert (!cp.match (r));
assert (!cp.match (c1));
@@ -239,10 +239,42 @@ class CssSelectorTest : GXmlTest {
warning ("ERROR: "+e.message);
}
});
+ Test.add_func ("/gxml/css-selector/element/attribute-value-unquoted", () => {
+ try {
+ var cp = new CssSelectorParser ();
+ cp.parse ("child[prop-name=va7u3_unqu§ted]");
+ assert (cp.selectors.size == 3);
+ var s = cp.selectors[0];
+ assert (s != null);
+ assert (s.selector_type == CssSelectorType.ELEMENT);
+ var si = cp.selectors[1];
+ assert (si != null);
+ assert (si.selector_type == CssSelectorType.INSIDE);
+ var sa = cp.selectors[2];
+ assert (sa != null);
+ assert (sa.selector_type == CssSelectorType.ATTRIBUTE_EQUAL);
+ var d = new GomDocument ();
+ var r = d.create_element ("root");
+ d.append_child (r);
+ var c1 = d.create_element ("child");
+ r.append_child (c1);
+ var c2 = d.create_element ("child");
+ c2.set_attribute ("prop-name", "t");
+ var c3 = d.create_element ("child");
+ c3.set_attribute ("prop-name", "va7u3_unqu§ted");
+ r.append_child (c3);
+ assert (!cp.match (r));
+ assert (!cp.match (c1));
+ assert (!cp.match (c2));
+ assert (cp.match (c3));
+ } catch (GLib.Error e){
+ warning ("ERROR: "+e.message);
+ }
+ });
Test.add_func ("/gxml/css-selector/element/attribute-value", () => {
try {
var cp = new CssSelectorParser ();
- cp.parse ("child[prop=\"val\"]");
+ cp.parse ("child[prop-name=\"val\"]");
assert (cp.selectors.size == 3);
var s = cp.selectors[0];
assert (s != null);
@@ -259,9 +291,9 @@ class CssSelectorTest : GXmlTest {
var c1 = d.create_element ("child");
r.append_child (c1);
var c2 = d.create_element ("child");
- c2.set_attribute ("prop", "t");
+ c2.set_attribute ("prop-name", "t");
var c3 = d.create_element ("child");
- c3.set_attribute ("prop", "val");
+ c3.set_attribute ("prop-name", "val");
r.append_child (c3);
assert (!cp.match (r));
assert (!cp.match (c1));
@@ -370,13 +402,13 @@ class CssSelectorTest : GXmlTest {
var c1 = d.create_element ("child");
r.append_child (c1);
var c2 = d.create_element ("child");
- c2.set_attribute ("prop", "subval");
+ c2.set_attribute ("prop-name", "subval");
r.append_child (c2);
var c3 = d.create_element ("child");
- c3.set_attribute ("prop", "techval");
+ c3.set_attribute ("prop-name", "techval");
r.append_child (c3);
var c4 = d.create_element ("child");
- c4.set_attribute ("prop", "secondaryvalue");
+ c4.set_attribute ("prop-name", "secondaryvalue");
r.append_child (c4);
assert (cp.match (r));
assert (!cp.match (c1));
@@ -389,13 +421,13 @@ class CssSelectorTest : GXmlTest {
var c1g = d2.create_element ("child");
r2.append_child (c1g);
var c2g = d2.create_element ("child");
- c2g.set_attribute ("prop", "subval");
+ c2g.set_attribute ("prop-name", "subval");
r2.append_child (c2g);
var c3g = d2.create_element ("child");
- c3g.set_attribute ("prop", "techval");
+ c3g.set_attribute ("prop-name", "techval");
r2.append_child (c3g);
var c4g = d2.create_element ("child");
- c4g.set_attribute ("prop", "secondaryvalue");
+ c4g.set_attribute ("prop-name", "secondaryvalue");
r2.append_child (c4g);
assert (cp.match (r));
assert (!cp.match (c1g));
@@ -455,13 +487,13 @@ class CssSelectorTest : GXmlTest {
var c1 = d.create_element ("child");
r.append_child (c1);
var c2 = d.create_element ("child");
- c2.set_attribute ("prop", "subval");
+ c2.set_attribute ("prop-name", "subval");
r.append_child (c2);
var c3 = d.create_element ("child");
- c3.set_attribute ("prop", "techval");
+ c3.set_attribute ("prop-name", "techval");
r.append_child (c3);
var c4 = d.create_element ("child");
- c4.set_attribute ("prop", "secondaryvalue");
+ c4.set_attribute ("prop-name", "secondaryvalue");
r.append_child (c4);
var c5 = d.create_element ("common");
c4.append_child (c5);
@@ -482,13 +514,13 @@ class CssSelectorTest : GXmlTest {
var c1g = d2.create_element ("child");
r2.append_child (c1g);
var c2g = d2.create_element ("child");
- c2g.set_attribute ("prop", "subval");
+ c2g.set_attribute ("prop-name", "subval");
r2.append_child (c2g);
var c3g = d2.create_element ("child");
- c3g.set_attribute ("prop", "techval");
+ c3g.set_attribute ("prop-name", "techval");
r2.append_child (c3g);
var c4g = d2.create_element ("child");
- c4g.set_attribute ("prop", "secondaryvalue");
+ c4g.set_attribute ("prop-name", "secondaryvalue");
r2.append_child (c4g);
var c5g = d2.create_element ("common");
c4g.append_child (c5g);
@@ -522,13 +554,13 @@ class CssSelectorTest : GXmlTest {
var c1 = d.create_element ("child");
r.append_child (c1);
var c2 = d.create_element ("child");
- c2.set_attribute ("prop", "subval");
+ c2.set_attribute ("prop-name", "subval");
r.append_child (c2);
var c3 = d.create_element ("child");
- c3.set_attribute ("prop", "techval");
+ c3.set_attribute ("prop-name", "techval");
r.append_child (c3);
var c4 = d.create_element ("child");
- c4.set_attribute ("prop", "secondaryvalue");
+ c4.set_attribute ("prop-name", "secondaryvalue");
r.append_child (c4);
var c5 = d.create_element ("second");
c3.append_child (c5);
@@ -553,13 +585,13 @@ class CssSelectorTest : GXmlTest {
var c1g = d2.create_element ("child");
r2.append_child (c1g);
var c2g = d2.create_element ("child");
- c2g.set_attribute ("prop", "subval");
+ c2g.set_attribute ("prop-name", "subval");
r2.append_child (c2g);
var c3g = d2.create_element ("child");
- c3g.set_attribute ("prop", "techval");
+ c3g.set_attribute ("prop-name", "techval");
r2.append_child (c3g);
var c4g = d2.create_element ("child");
- c4g.set_attribute ("prop", "secondaryvalue");
+ c4g.set_attribute ("prop-name", "secondaryvalue");
r2.append_child (c4g);
var c5g = d2.create_element ("second");
c3g.append_child (c5g);
@@ -596,13 +628,13 @@ class CssSelectorTest : GXmlTest {
var c1 = d.create_element ("child");
r.append_child (c1);
var c2 = d.create_element ("child");
- c2.set_attribute ("prop", "subval");
+ c2.set_attribute ("prop-name", "subval");
r.append_child (c2);
var c3 = d.create_element ("child");
- c3.set_attribute ("prop", "techval");
+ c3.set_attribute ("prop-name", "techval");
r.append_child (c3);
var c4 = d.create_element ("child");
- c4.set_attribute ("prop", "secondaryvalue");
+ c4.set_attribute ("prop-name", "secondaryvalue");
r.append_child (c4);
var c5 = d.create_element ("second");
c3.append_child (c5);
@@ -624,13 +656,13 @@ class CssSelectorTest : GXmlTest {
var c1g = d2.create_element ("child");
r2.append_child (c1g);
var c2g = d2.create_element ("child");
- c2g.set_attribute ("prop", "subval");
+ c2g.set_attribute ("prop-name", "subval");
r2.append_child (c2g);
var c3g = d2.create_element ("child");
- c3g.set_attribute ("prop", "techval");
+ c3g.set_attribute ("prop-name", "techval");
r2.append_child (c3g);
var c4g = d2.create_element ("child");
- c4g.set_attribute ("prop", "secondaryvalue");
+ c4g.set_attribute ("prop-name", "secondaryvalue");
r2.append_child (c4g);
var c5g = d2.create_element ("second");
c3g.append_child (c5g);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]