/** * Inspect each character in a string, copying quoted characters, with * their escaping, into the result. Look for unquoted non alphanumerics * and if not "*" or "?", add escaping. * @param $s * @return * @throws Exception representing parsing errors. */ private function addQuoting($s) { $result = ""; $idx = 0; $embedded = false; while ($idx < strlen($s)) { $c = substr($s, $idx, 1); if (Utilities::isAlphanum($c) || $c == "_") { // Alphanumeric characters pass untouched. $result = $result . $c; $idx = $idx + 1; $embedded = true; continue; } if ($c == "\\") { // Anything quoted in the bound string stays quoted in the // unbound string. $result = $result . substr($s, $idx, 2); $idx = $idx + 2; $embedded = true; continue; } if ($c == "*") { // An unquoted asterisk must appear at the beginning or the end // of the string. if ($idx == 0 || $idx == strlen($s) - 1) { $result = $result . $c; $idx = $idx + 1; $embedded = true; continue; } else { throw new Exception("Error! cannot have unquoted * embedded in formatted string.", 0); } } if ($c == "?") { // An unquoted question mark must appear at the beginning or // end of the string, or in a leading or trailing sequence. if ($idx == 0 || $idx == strlen($s) - 1 || !$embedded && substr($s, $idx - 1, 1) == "?" || $embedded && substr($s, $idx + 1, 1) == "?") { $result = $result . $c; $idx = $idx + 1; $embedded = false; continue; } else { throw new Exception("Error! cannot have unquoted ? embedded in formatted string.", 0); } } // All other characters must be quoted. $result = $result . "\\" . $c; $idx = $idx + 1; $embedded = true; } return $result; }
/** * Scans an input string and performs the following transformations: * - Pass alphanumeric characters thru untouched * - Percent-encode quoted non-alphanumerics as needed * - Unquoted special characters are mapped to their special forms * @param $s string to be transformed * @return transformed string */ private function transformForURI($s) { $result = ""; $idx = 0; while ($idx < strlen($s)) { // Get the idx'th character of s. $thischar = substr($s, $idx, 1); // Alphanumerics (incl. underscore) pass untouched. if (Utilities::isAlphanum($thischar)) { $result = $result . $thischar; $idx = $idx + 1; continue; } // Check for escape character. if ($thischar == "\\") { $idx = $idx + 1; $nxtchar = substr($s, $idx, 1); $result = $result . $this->pctEncode($nxtchar); $idx = $idx + 1; continue; } // Bind the unquoted '?' special character to "%01". if ($thischar == "?") { $result = $result . "%01"; } // Bind the unquoted '*' special character to "%02". if ($thischar == "*") { $result = $result . "%02"; } $idx = $idx + 1; } return $result; }
/** * Searches a string for the backslash character * @param $str string to search in * @param $idx end index * @return true if the number of backslash characters is even, false if odd */ private function isEvenWildcards($str, $idx) { $result = 0; while ($idx > 0 && strpos($str, "\\", $idx - 1) !== false) { $idx = $idx - 1; $result = $result + 1; } return Utilities::isEvenNumber($result); }