The below link is the issue-although the ".amp;" (I am seeing that my link is not appearing as I pasted it when I view this question before posting. This is exactly what I'm looking to do with my $_GET variable name, remove the amp; from the parameter name)
index.php?SearchResults&SearchString=aliquippa&AllWords=off
The $_GET elements are named with amp; preceding the name I expect. For example, $_GET[amp;AllWords'] is how the variables are named. I expect $_GET['AllWords'] format.
All links on my 'site' are built and returned by a standard class function that applies htmlspecialchars to the final return value. Each link is constructed by a class function specific to the required task and then returned through by calling this standard function. While all links are returned through the same standard function, I have only 1 link misbehaving.
This link is the first time I've tried taking user input and passing it (redirecting?) back through a $_GET parm. It's like the &'s are being doubled up. I am certain the code is not adding a second ampersand.
As a solution, I immediately found and tried htmlspecialchars_decode() against the POST variables. It made no difference with the name assigned to the $_GET parm. Other than decoding what was encoded and going through the logic, I'm at a loss for understanding. The code building the link in error looks the same as the code that is building links that work fine. All links are returned through the standard function, which applies htmlspecialchars. I would think all links either work or do not work, not a mixture.
Below is the code being used for redirect when the $_GET array contains a parm named 'Search' - this is the code I suspect of injecting the double &'s. I have added writing to a log file in this function and the "double &'s" are present in the return value from
Link::ToSearchResults.
if (isset($_GET['Search']))
{
$this->mSearchString = $_POST['search_string'];
$this->mAllWords = isset($_POST['all_words']) ? $_POST['all_words'] : 'off';
ob_clean();
header('HTTP/1.1 302 Found');
header('Location: ' . Link::ToSearchResults($this->mSearchString, $this->mAllWords));
flush();
ob_flush();
ob_end_clean();
exit;
}
Following is the ToSearchResults function code:
$link = 'index.php?SearchResults';
if (empty($searchString))
$link .= '/';
else
$link .= '&SearchString=' . $searchString;
$link .= '&AllWords=' . $allWords;
return self::Build($link);
Following is the return from standard class function Build(). All links are passed through this function before returning to caller.
return htmlspecialchars($link, ENT_QUOTES);
The problem occurs when you pass values containing '&' through the Build method, which is escaping HTML special characters with HTML entities. The resulting link will be of the form:
index.php?SearchResults&SearchString=aliquippa&AllWords=off
PHP's URL parser does not expect to encounter HTML entities, because they should not be present in URLs; it therefore correctly splits the query string on &, treating the trailing amp; as part of the key. To solve the problem, do not pass your URLs through htmlspecialchars().
Related
I am trying to hit a URL after generating the data to be filled for the parameters that are passed in URL using Python in back end. So the flow is:
User lands on a page with a form having some drop downs.
Python code in the backend reads the content from a file and returns single output based on some conditions for each of the dropdown.
User hits the submit button with the data.
The data gets generated correctly but when I hit submit button, I get %0D%0A characters at the end of the parameter values in the URL
E.g., sample.php?param1=20%0D%0A¶m2=50%0D%0A
How do I get rid of these values as this is causing trouble with the other code where I am using these values?
I take it you read the data from a file, so probably reading the file causes the line endings to be read as well.
In any case, try using strip() or rstrip() in your Python code to remove all/trailing whitespace before your assemble the target URL.
I understand that it's actually a PHP script that assembles the URL. In that case, use PHP's trim() function on the variables you use to assemble the URL.
For example: Assume that $val1 and $val2 are read from a file or some other place. Then the following line assembles above URL stripping whitespace from $val1 and $val2.
$url = "sample.php?param1=" . trim($val1) . "¶m2=" . trim($val2);
Some browsers do that automatically, you can try decoding it back using urldecode()
http://php.net/manual/en/function.urldecode.php
Try this :
<?Php
$str = "Your Inputed Value or string"
$url = str_replace(" ","-", $str);
?>
Link Menu
I have a little static function so that I can easily build html valid urls on my local website, it is below;
public static function url($path = false) {
// Build return url with special html characters escaped
return 'http://127.0.0.1/' . htmlspecialchars($path);
}
I have two urls one inside an anchor and another is inside a form action, they are below;
Root::url('test?category=' . $category . '&index=' . $index) // Href
Root::url('test?category=' . $_GET['category'] . '&index=' . $_GET['index']) // Form
GET === $, you can see inside my static function that I use htmlspecialchars to escape special html characters from my url.
The anchor one returns a valid link and works as expected. The form one however returns the following, as in when I click on the form submit, my url in my browser is as follows.
http://127.0.0.1/test?category=innate&index=0
Why is this? My website breaks because it is dependant on the GET parameters being valid.
Thanks for your time, hope this made sense.
EDIT
I insert the return value of the function call straight into my form action,
<form
action="<?= Root::url('test?category=' . $_GET['category'] . '&index=' . $_GET['index']); ?>"
method="post">
EDIT
The form html is as follows;
<form action="http://example.com/test?category=innate&index=0" method="post">
The anchor html is as follows
<a href="http://example.com/test?category=innate&index=0">
Could it be something to do with the server sending a POST request even though I have GET parameters?
EDIT #3
Ok so it has something to do with my function or what I am passing in, I hard typed in the url in the form submit and it worked, no problems, which means it can only be what my function is returning.
I myself cannot see what I may be!
ANSWER
After the form was being submitted, I was redirecting to the same page using header to counter form resubmission. The string for the header was being generated by Root::url().
Two hours this took me to figure out, but boy does it feel good!
Normally you wouldn't add a query string to a POST URL. It's not forbidden, though, it may only be somewhat confusing, especially if you use $_REQUEST (which you don't, it seems).
I don't know why your browser shows an uninterpreted &, it should interpret it.
Your problems are likely due to one of these:
a bad browser - try another one
bad content of the form input fields
other
This is quite logic.
I assume your url() method looks like this:
url($string){
echo htmlspecialchars($string);
}
Let's have a look at the $string you are passing:
'test?category=' . $_GET['category'] . '&index=' . $_GET['index'];
As I see in your output, replacing the values, the final string before htmlspecialchars() occur would be:
'test?category=innate&index=0' and after it: test?category=innate&index=0
What happened here? you first concatenated the string, and then htmlspecialchars()'ed the & used to separate the parameters. And to not break the url, you don't want to convert THAT '&'.
Also to sanitize the url you shouldn't use htmlspecialchars() because most html entities would convert to somthing like & + somename + ; for example the Euro symbol would convert to € and you don't want the actual & symbol in your url, the browsers will interpret it as you have another new parameter awaiting.
You should use urlencode(), which will convert your & into: %26 , also, the function's name is self-explanatory, it's encoding a string to use on a URL.
Still, you want the & to separate the parameters, but not in the $GET values. What should we do? to urlencode the values before concatenating the string. I would suggest a method like this one:
function url($page, $get){
$parameters = array();
foreach($get as $k => $v) $parameters[] = urlencode($k)."=".urlencode($v);
//We are concatenating with ? and & the urlencoded() values in the next line:
echo urlencode($page).'?'.implode('&', $parameters);
}
url('test', $_GET); // outputs: test?category=innate&index=0
This would get rid of the special chars from a form's field names and values.
I noticed you will use 2 fixed parameters, category and index, so the method could be like this:
function url($page, $get){
$page = urlencode($page);
$category = urlencode($get['category']);
$index = urlencode($get['index']);
echo "$page?category=$category&index=$index";
}
Hope this is what you needed
Edit: I think %27 is actually the wrong kind of quote. I am still stuck though, I cannot find a PHP function that does the conversion I want.
Edit (again): I found a solution where I stick %26rsquo%3bs into the URL and it turns into ’. It works so I posted it as an answer below but I'd still be interested in knowing how it'd be done with PHP functions.
I'm working on a website that uses a PHP tree as if it were a directory. For example, if someone types index.php?foo=visual programming (or index.php?foo=visual%20programming) then the website opens the item "Visual Programming" (I'm using strtolower()).
Another working example would be index.php?foo=visual programming&bar=animated path finder which opens "Animated Path Finder", a child of "Visual Programming".
The problem is that some of the items are named things like "Conway’s Game of Life" which uses a HTML entity. My guess of what someone should type to open this would be index.php?foo=visual%20programming&bar=conway%27s%20game%20of%20life. The problem is that ' is not === to ’.
What do I need to do to make this work? Here is my code that selects an item based on $_GET (the PHP is inside of <script type="text/javascript">):
<?php
function echoActiveDirectory($inTree) {
// Compare $_GET with PhpTree
$itemId = 0;
foreach ($_GET as $name) {
if ($inTree->children !== null) {
foreach ($inTree->children as $child) {
if (strtolower($child->title) === strtolower($name)) {
$itemId = $child->id;
$inTree = $child;
break;
}
}
}
}
// Set jsItems[$itemId].selected(), it will be 0 if nothing was found
echo "\t\tjsItems[".$itemId."].selected();\n";
}
echo "// Results of PHP echoActiveDirectory(\$root)\n";
echoActiveDirectory($root);
?>
The website is a work in progress, but it can be tested here to see $_GET working: http://alexsimes.com/index.php
The hex code %27 (39 decimal) will never translate to ’, since it is a completely different entity (Wikipedia). It could be translated to ', but PHP doesn't do that (although I don't know the reason for that).
Edit
While there is no standard for URL-encoding multibyte character sets, PHP will treat a string as just a set of bytes, and if those match an UTF-8 sequence, it will work:
php -r 'echo htmlentities(urldecode("%E2%80%99"), ENT_QUOTES|ENT_HTML401);'
should output
’
You can use html_entity_encode() and html_entity_decode() PHP functions to convert those characters to html entities or decode them back to desired characters before comparison.
You can try the htmlentities function to convert special characters to corresponding html entity. But in your case if data is already stored in db as html entity form, the data from $_GET parameter must be first passed through htmlentities before using it in your query.
I want to wrap a word in <strong> tags. Is it correct to do that right in the t() call, or am I supposed to do it some other way?
$help = '<p>' . t("Does this sample data look right for node type %node_type? If not, use your browser's <strong>back</strong> button to fix it on the previous page.", array('%node_type' => $_SESSION[NODE_TYPE_KEY])) . '</p>';
Also, what about just dropped variables directly into t(), like this?
foreach ($term_info['term_fields'] as $vocab) {
$options[$vocab] = t($vocab); // TODO: incorrect use of t()?
}
Both your questions are answered in the Drupal API documentation at http://api.drupal.org/api/function/t/6. A short summary:
You can wrap a word in html tags if you really must. Quote:
HTML markup within translation strings
is allowed, but should be avoided if
possible.
It is not allowed to drop variables into t() like you do in your code snippet. Quote:
Because t() is designed for handling
code-based strings, in almost all
cases, the actual string and not a
variable must be passed through t().
I'm sending a php script multiple urls (about 15) at once, all containing about 5 url variables. In my script, I'm parsing the chunk of urls into individual ones by splitting them with two backslashes (which i add upon before to the script), and then curling each individual url. However, when I run my script, it only accepts a url up to the "&" symbol. I'd like to have the entire chunk, so that I can split it up later in my script. What might be the best way to approach this issue?
Thanks.
An example of what happens when i send my script a url chunk:
<?php
/*
$url variable being sent to script:
http://www.test1.com?q1=a&q2=b&q3=c&q4=d\\http://www.test2.com?r1=a&r2=b&r3=c&r4=d\\http://www.test3.com?q1=a&q2=b&q3=c&q4=d\\http://www.test4.com?e1=a&e2=b&e3=c&e4=d
*/
$url = $_GET['url'];
echo $url; // returns http://www.test1.com?q1=a
//later on in my script, i just need to curl each "\\" seperated url
?>
You need to urlencode() the (data) URLs before appending them to your script's request.
Otherwise, PHP is going to to see ?listOfUrls=http://someurl.com/?someVar=SomeVal& and stop right there, due to the literal "&"
If you're building the query string in PHP you could try something like:
<?PHP
//imagine $urls is an array of urls
$qs = '?urls=';
foreach($urls as $u){
$q .= urlencode($u) .'\\';
}
I also suspect you can play with [] notation in the url so that on the other side of the GET, you get a nice clean array of URLs back, instead of having to parse on some delimiter like "\"
Since you didn't url encode your url param, everything after the first & is treated as the param to the original url.
The $_GET array is formed by splitting on ampersands. URL-encode the URLs before passing them as parameters. PHP should decode them for you.
Example: pass url=http://www.test1.com?q1=a%26q2=b%26q3=c%26q4=d\\http://www.test2.com?r1=a%26r2=b%26r3=c%26r4=d\\http://www.test3.com?q1=a%26q2=b%26q3=c%26q4=d\\http://www.test4.com?e1=a%26e2=b%26e3=c%26e4=d
You can do away with the '\\' by turning the parameter into an array. Example: use url[]=http://www.test1.com?q1=a%26q2=b%26q3=c%26q4=d&url[]=http://www.test2.com?r1=a%26r2=b%26r3=c%26r4=d&url[]=http://www.test3.com?q1=a%26q2=b%26q3=c%26q4=d&url[]=http://www.test4.com?e1=a%26e2=b%26e3=c%26e4=d