From fe38ae10d389ec711d1cf1e65c5241908731e6c3 Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Tue, 9 Sep 2014 10:51:20 +0800 Subject: [PATCH] MDL-47154 behat: escape user supplied strings in xpath --- lib/tests/behat/behat_general.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/tests/behat/behat_general.php b/lib/tests/behat/behat_general.php index f3a17ffc98d..9f8dc9392c6 100644 --- a/lib/tests/behat/behat_general.php +++ b/lib/tests/behat/behat_general.php @@ -1000,11 +1000,15 @@ class behat_general extends behat_base { $tablenode = $this->get_selected_node('table', $table); $tablexpath = $tablenode->getXpath(); + $rowliteral = $this->getSession()->getSelectorsHandler()->xpathLiteral($row); + $valueliteral = $this->getSession()->getSelectorsHandler()->xpathLiteral($value); + $columnliteral = $this->getSession()->getSelectorsHandler()->xpathLiteral($column); + // Header can be in thead or tbody (first row), following xpath should work. - $theadheaderxpath = "thead/tr[1]/th[(normalize-space(.)='" . $column . "' or a[normalize-space(text())='" . - $column . "'])]"; - $tbodyheaderxpath = "tbody/tr[1]/td[(normalize-space(.)='" . $column . "' or a[normalize-space(text())='" . - $column . "'])]"; + $theadheaderxpath = "thead/tr[1]/th[(normalize-space(.)=" . $columnliteral . " or a[normalize-space(text())=" . + $columnliteral . "])]"; + $tbodyheaderxpath = "tbody/tr[1]/td[(normalize-space(.)=" . $columnliteral . " or a[normalize-space(text())=" . + $columnliteral . "])]"; // Check if column exists. $columnheaderxpath = $tablexpath . "[" . $theadheaderxpath . " | " . $tbodyheaderxpath . "]"; @@ -1016,21 +1020,21 @@ class behat_general extends behat_base { // Check if value exists in specific row/column. // Get row xpath. - $rowxpath = $tablexpath."/tbody/tr[th[normalize-space(.)='" . $row . "'] | td[normalize-space(.)='" . $row . "']]"; + $rowxpath = $tablexpath."/tbody/tr[th[normalize-space(.)=" . $rowliteral . "] | td[normalize-space(.)=" . $rowliteral . "]]"; // Following conditions were considered before finding column count. // 1. Table header can be in thead/tr/th or tbody/tr/td[1]. // 2. First column can have th (Gradebook -> user report), so having lenient sibling check. $columnpositionxpath = "/child::*[position() = count(" . $tablexpath . "/" . $theadheaderxpath . "/preceding-sibling::*) + 1]"; - $columnvaluexpath = $rowxpath . $columnpositionxpath . "[contains(normalize-space(.),'" . $value . "')]"; + $columnvaluexpath = $rowxpath . $columnpositionxpath . "[contains(normalize-space(.)," . $valueliteral . ")]"; // Looks for the requested node inside the container node. $coumnnode = $this->getSession()->getDriver()->find($columnvaluexpath); if (empty($coumnnode)) { // Check if tbody/tr[1] contains header selector. $columnpositionxpath = "/child::*[position() = count(" . $tablexpath . "/" . $tbodyheaderxpath . "/preceding-sibling::*) + 1]"; - $columnvaluexpath = $rowxpath . $columnpositionxpath . "[contains(normalize-space(.),'" . $value . "')]"; + $columnvaluexpath = $rowxpath . $columnpositionxpath . "[contains(normalize-space(.)," . $valueliteral . ")]"; $coumnnode = $this->getSession()->getDriver()->find($columnvaluexpath); if (empty($coumnnode)) { $locatorexceptionmsg = $value . '" in "' . $row . '" row with column "' . $column;