Symfony: escape single quote string from database? - php

I need to generate a link with a Javascript confirmation dialog using Symfony's link_to() method. The confirmation dialog text gets some of it's content from a database entry:
<?php echo link_to( "click here", 'category/delete?id='.$id, array( 'confirm' => 'Are you sure you want to delete the category: '.$category->getName().'?' ) ) ?>
But if the database entry has a single quote in it, the confirm dialog doesn't work because the generated JS is surrounded with single quotes. So if I have a category called "John's Articles", the generated JS starts like this:
<a onclick="if (confirm('Are you sure you want to delete the category: John's Articles?')) { var f = document.createElement('form'); f.styl.... etc... "
So, the single quote in there screws up the confirmation, etc...
Anyways I thought I would simply run $category->getName() through addslashes() but it didn't add any slashes... I also tried saving out the category name as a separate variable ahead of time and adding slashes to that. But it didn't add any. Then I started looking at Symfony's escaping methods and found methods like esc_entities() but they resulted in the text looking like John&#039;s Articles.
What do I do? All I want to do is add in a single slash before single quotes in that string. I never tried str_replace("'","\'",$category->getName()) but THAT didn't even do anything. I can create my own basic string in my template like Alex's Test and addslashes() to it just fine. It's just this value from the database that I can't add any slashes to.
When I look at the value in the database, it looks just like John's Articles. There are no special characters or encoded characters.
What am I missing here?
UPDATE
I've tried the following code with the following results:
echo $category->getName()."<br/>";
echo addslashes($category->getName())."<br/>";
$tmp = $category->getName();
echo addslashes($tmp)."<br/>";
$tmp = addslashes($category->getName());
echo $tmp."<br/>";
$tmp = "Testing's the Testing";
echo addslashes($tmp)."<br/>";
$tmp = str_replace("'","\\'",$category->getName());
echo $tmp;
Results:
John's Articles
John's Articles
John's Articles
John's Articles
Testing\'s the Testing
John's Articles
The values from the database simply will not get slashes added to them...

Seems like you just use
addslashes($category->getName())
But you need assign returned value to other variable, ex.
$nameWithSlashes=addslashes($category->getName())

use json_encode() when inserting into Javascript. It's specifically intended to turn arbitrary data structures into syntactically valid Javascript.
<?php echo link_to( ....snip snip... category: '. json_encode($category->getName()) .'?' ) ) ?>
^^^^^^^^^^^^ ^
will take care of the problem, without any "risky" regexes/string replacements.

Related

Add a hyperlink to each entry of a table from mysqli

I'm trying to add a direct link to the genomic region of each gene on a table generated with mysqli data, but can't figure out the way. The idea is that every gene name has a hyperlink to it's region on a genome browser.
The problem comes when I have to generate the link dynamically for each gene depending on the gene selected by the user.
I've tried this:
echo '<td><a href="http://genome.ucsc.edu/cgi-bin/hgTracks?"'.urlencode($genome.$row['name2'])'>'$row['name2']'</a></td>';
$genome is the par of the url specific for each species and assembly, and $row['name2'] is the name of each gene.
I complete my previous comment with some advice - maybe this is the answer to your question.
1. How to use echo
You should separate each part of the echo function by a separator.
The common separator is the coma ,. Of course, you can also concatenate with a dot .
echo 'a', 'b', 'c', $var, 'con'ca' . 'tenated';
Tips: use the coma only for echo instruction. It's faster :)
2. Issues on your code
If I take your generated output, you should have something like this - with **cho* corrections:
<td><a href="http://genome.ucsc.edu/cgi-bin/hgTracks?"%20gen%20The+name>The name</a><td>
As you can see, the link is http://genome.ucsc.edu/cgi-bin/hgTracks?. The content after the " is ignored.
Solution: Move to the dynamic part of the link, at the correct place :)
You had your quote double quote in wrong location if there are additional problems will need more info
// Yours
echo '<td><a href="http://genome.ucsc.edu/cgi-bin/hgTracks?"'.urlencode($genome.$row['name2'])'>'$row['name2']'</a></td>'
// Fixed Quote
echo '<td>'$row['name2']'</td>';

Insert strings with apostrophes into database by php

I want to post data into database in safe mode.
For example if i want to add this title to database:
$title = " here is title 'here is title' here is title ";
notice it has apostrophes.
I use this function to make string safe:
function stringsafe($string)
{
$string = strip_tags(trim(addslashes($string)));
return $string;
}
as you see it's adding slashes before apostrophes to make it safe.
I tried to remove slashes when i show the data by stripslashes, it's working but it's has some problems. Is there anyway to post data into database?
On a side note, in fact the general rules of thumb is that, you shouldn't alter user input at all. You should store whatever user input as it is, into your database, so that you can retain user input as original as possible, and only escape it when you need to display or use it.
In your case, yes you are right you have to prevent it from being injected, but you are altering the original input by adding slashes into the original input, which is not very favoured. What if my title contains a string like this <My 21st Birthday Party!> and you stripped it away?
Try using Prepared Statements instead so you can insert any data into your database, without the worries of injection. And only when you need the data to be displayed on a HTML page or console, you escape them accordingly such as htmlentities.

Passing MySQL data through an ajax form via javascript/PHP with specialchars

I've recently thrown together a basic PHP webpage that lists information pulled from an MySQL table and displays it in various sorts. I'm wanting to allow the user to add a new item to the table, edit an item in the list and delete an item in the list without refreshing the page (Ajax).
This currently goes;
To add/edit an article you click on a link which prompts the popover ajax form, and fills it's contents (if editing) by performing the function setEdit(comment) as below;
<a class="popup-button" title="<?php echo $row['comment']; ?>" onclick="setEdit('<?php if($row['comment']){ echo $row['comment']; } else { echo "Enter comment here..."; } ?>');"><?php echo $row['listitem']; ?></a>
The setEdit() comment is as follows;
function setEdit(editcomment)
{
if(editcomment){ document.getElementById('help-us-comment').value=editcomment; }
}
Which is then, after submitting the ajax form, handled by the following php code;
if(isset($_POST['comment_text']))
$comment=$_POST['comment_text'];
$sql = "INSERT INTO table SET
comment='$comment'";
Problem: I'm having constant issues trying to get the database contents through 1, 2, 3 without falling over at a new line, single or double quote. I've tried endless combinations of replacing tags, htmlspecialchars and nl2br with no half successes - where it's got to the point that it's so convoluted and encoded/decoded now that I'm assuming that there is a far simpler and obvious way that I'm missing.
The main problem happens when trying to load the data into the form, typically having either the form fall over and refuse to populate at all (typically by the a link becoming broken by the data extracted i.e. single quote or new line) or the form being populated with special characters instead of plain text to edit.
I've tried to go into as much detail as possible, but if any more is needed I'm happy to provide. Also apologies if this is an obvious fix/mistake, and I'm being an idiot.
You have two problems here: storing and displaying.
To display you should look in to htmlentities that makes it safe HTML (it does all the quotes replacing, html encoding, etc. for you) so that your string to be safe to be displayed as plain text, or as inputs' values.
To store the data, you should sanitize your queries. You could use mysqli and bind parameters, or use mysql_real_escape_string to escape your input manually.
Otherwise, say hi to Bobby Tables ;)

Slashes in text output

From a form, I'm asking the user to enter some text. I will retrieve this text using $_POST['text'].
The user enters the string "It's my text!"
$newText = mysql_real_escape_string($_POST['text']);
Now on the very same page after I've inserted $newText into the database I want to display
the text to the user and also use it as the value of an input text box using PHP.
// I want to make sure the user hasn't added any unsafe html in their string
$newText = htmlentities($newText);
echo "You've entered: " . $newText . "<br />";
echo "<form action=someaction.php method=post>";
echo "<input type=text value=\"" . $newText . "\">";
echo "</form>";
The output is:
You've entered: It\'s my text!
[It\'s my text!]
How do I avoid these slashes, and should I be doing anything else with my data?
You're passing the text through mysql_real_escape_string() which, as the name suggests, escapes the string, including apostrophes. mysql_real_escape_string() is meant only for preparing the data for saving to database. You shouldn't use it when displaying data to the user.
So, the solution is simple: remove the line and use htmlentities() only. Use mysql_real_escape_string() when you're saving the string to database (and only then).
Only use mysql_real_escape_string() on the variable you want to use in the query, because it will add slashes to escape some of the characters in the string. This works great for mysql, but when want to use it on the page it will look weird.
You could make 2 variables, 1 for MySQL and 1 for displaying the raw text.
$text = $_POST['text'];
$db_text = mysql_real_escape($text);
Also note that you should use strip_slashes() on the data you get from the database later, to remove the slashes.
Hope this clear things up a little bit.
Now on the very same page after I've inserted $newText into the database I want to display the text to the user
That's what you are doing wrong.
An HTTP standard require a GET method redirect after every successful POST request.
So, you have to redirect the user on the same page, where you may read inserted data from the database and show it to the user.
As for the mistake you made - just move escaping somewhere closer to the database operations, to make sure it is used only for the purpose (YET it is used obligatory, without the risk of forgetting it!).
Ideally you have to use some variables to represent the data in the query, and some handler to process them.
So, the query call may look like
DB::run("UPDATE table SET text=s:text",$_POST['text']);
where s:text is such a variable (called placeholder), which will be substituted with the $_POST['text'] value, properly prepared according to the type set in the placeholder name (s means "string", tells your function to escape and quote the data)
So, all the necessary preparations will be done inside and will spoil no source variable.
save normally using mysql_real_escape_string()
and when you want to display it in a form:
htmlspecialchars(stripslashes($row['text_data']))
it will do the trick.

How to echo randomly a portion of a string?

i have already succesfully translated some quotes via my translation function __(); and now I want to echo only one of those quotes at random. All quotes are separated in this string with a special character like a |
Sofar I only have this. What code could should go below this tackle my random echo?
$quotes =
__("IF YOU MAKE EVERYTHING BOLD, NOTHING IS BOLD") . "|" .
__("Quality of design is an indicator of credibility") . "|" .
__("People ignore design, that ignores people");
(An important restriction: it is essential that the quotes be exactly closed with __(" and "); sothat they can be checked and translated.) __($variable) doest not work with current clean up scripts that I have bought so these won't work.
You're already calling __() on each of your quotes individually, why not save all the extra translating and do something like:
$quotes = array('quote1', 'quote2', 'quote3');
$index = array_rand($quotes);
echo __($quotes[$index]);
Edit: To satisfy your other requirement, that the call to __() must immediately surround each string, you could do this:
$quotes = array(__('quote1'), __('quote2'), __('quote3'));
$index = array_rand($quotes);
echo $quotes[$index];
The big downside here is that you're now looking up a translation for every string in that array, even though only one is printed, but that's the same situation you had in the "one big string" solution.
Why don't you keep them in an array and translate only what is actually outputted?
$quotes = array(
"IF YOU MAKE EVERYTHING BOLD, NOTHING IS BOLD",
"Quality of design is an indicator of credibility",
"People ignore design, that ignores people",
);
$randomQuote = $quotes[ rand(0, count($quotes)-1)];
echo __($randomQuote);
Why the biscuits are they all in one string, and not an array? Your problem would be immediately solved if this was the case. As stands, split in | and index randomly into the array created to pick a random quote.

Categories