Saving source code from HTML textarea to file - php

I am saving C++ code from a textarea of an HTML form using PHP.
The problem is if my code is like below,
printf("%d\n");
printf("%d\n");
the code that is saved to the file is like this:
printf(\"%d\\n\");\nprintf(\"%d\\n\");
I want the original code to be saved in the file. If I use,
$sourceCode = str_replace('\n',"\n", $sourceCode);
$sourceCode = str_replace('\"',"\"", $sourceCode);
the result is like below (saved in the file):
printf("%d\
");printf("%d\
");
It is clear that replacing \n in the source code replaces all the HTML created \n along with the \n that user gave as input (the original text). The only difference is user's input has an additional \ before the \n, that is \\n.
How can I resolve the problem such that only the implicit escape characters will be replaced, but the explicit escape characters, that the user wrote himself, will not be changed?

As mentioned by KenB, we need to see the PHP code that you are using to process the form input.
Processing Form Input
It looks to me like addslashes has been used on the form input.
If you are doing that in your code, don't. This is not the proper way to process form input. Instead, you should use the correct function (such as htmlspecialchars or mysqli_real_escape_string) to escape the input before you use it. Read about addslashes.
If you are using an older version of PHP where magic_quotes_gpc is on by default, then you should fix that. Read about 'Disabling Magic Quotes'.
Stripping Out the Slashes
If you have no control over the code that is adding the slashes, then you can remove them with a simple PHP function called stripslashes.
$sourceCode = stripslashes($sourceCode);
Read about stripslashes.
Understanding Escape Sequences
Your str_replace code shows a lack of understanding about escape sequences and/or a lack of understanding about single vs double quotes.
In the following code, a literal \n is replaced with a line break. With the double quotes, PHP interprets the \n as an escape sequence rather than a literal string.
$sourceCode = str_replace('\n',"\n", $sourceCode);
What you want is to replace a literal \\n with a literal \n. Note that to specify a literal backslash it must be doubled; hence the triple backslash you see below.
$sourceCode = str_replace('\\\n', '\n', $sourceCode);
And although this next line accomplishes what you wanted...
$sourceCode = str_replace('\"',"\"", $sourceCode);
...it could have been written differently. The following code is easier to read, saves you having to escape the literal ", and doesn't require PHP to interpret the string.
$sourceCode = str_replace('\"', '"', $sourceCode);
I've given the above code as examples to explain how PHP interprets escapes sequences, but don't use them. Either avoid adding the slashes in the first place or strip them using the proper function, as explained in the first part of this answer.
Read more about escape sequences and quoting strings.
The Literal \n Between Lines
I'm not sure what you are doing to add the literal \n between the lines. We'd need to see your code. But to remove it after the fact, you could try the following
$sourceCode = str_replace(';\n', ";\n", $sourceCode);
Of course, then you'd likely need to correct other C++ end-of-line sequences. So it is better to not add it in the first place.

Related

Backslashes breaking string in PHP

I have an issue. I'm trying to write a string with ASCII text like this: '/\'. But whenever I do that the backslash screws up the code by canceling out the quote defining it a string therefore screwing it up. Is there anyway to cancel out the backslash so it doesn't cancel out the quote? Thanks guys!
The \ is special character, that says: 'The next character has special meaning'.
So if you want to dispaly \ you should write... \\ to get one \ in output
It would be very helpful to show what you have tried, but this will produce the exact output you requested (as shown by SO)
echo '\'/\\' . "'\n" ;
'/\'
It should also give you an idea of how backslash escaping works in different types of strings.
A great solution when writing stuff like that is HEREDOC. Inside a heredoc block you don't need to worry about escaping anything, it will just be text.
For example:
echo <<<TEXT
/|\/|\/|\/|\/|\/|\/|\/|\/|\/|\
TEXT;
There is one catch. PHP will break if you don't align the echo at the start of the line, or if the TEXT; is not aligned at the start of the line.
Heredoc can also be assigned to a variable, like so:
$var = <<<SOME_MORE_TEXT
/|\/|\/|\/|\/|\/|\/|\/|\/|\/|\
SOME_MORE_TEXT;
Finally, HEREDOC preserves tabs and spaces. Which also might come in handy when doing ASCII art.
Refer to: http://php.net/manual/en/language.types.string.php for more information.
You only need to escape the final one when using single quotes.
$var = 'backslash\backslash\backslash\\';
// output is:
// backslash\backslash\backslash\

PHP: literal \n rather than new line

I have a php var which, when echoed, writes a JS function into the source of a page. The function loops through a CSV and so it has the following line within it:
$str="var lines = data.split('\n');";
At the present time, when echoed, I get this 'correct' JS written into the source:
var lines = data.split('
');
Instead, I want to echo the literal string \n into the source of the page.
Can anyone point me in the right direction? Thanks.
Escape the slash.
"\\n"
So that it is treated as a slash instead of an escape character.
Try this:
$str="var lines = data.split('\\n');";
you can escape \ like this: \\.
But I would put the whole JS functionality into a .js file, include that from the generated HTML, and call the specific function when needed. And generate a minimalistic js code, like var config = {....} if I have to communicate some page related information.
You almost never need dynamically generated JS code. It's a lot harder to read and you're wasting CPU and network bandwidth...
Either the solutions in the earlier answers, or invert the quotes by using single quotes as the PHP string delimiter:
$str='var lines = data.split("\n");';
Or escape the inner quotes, if you want to keep single quotes for javascript as well when using single quotes as the PHP string delimiter.
$str='var lines = data.split(\'\n\');';
See the docs on quoted strings in PHP as well about how single quoted strings and double quoted strings behave differently.

Apostrophe issue

I have built a search engine using php and mysql.
Problem:
When I submit a word with an apostrophe in it and return the value to the text field using $_GET the apostrophe has been replaced with a backslash and all characters after the apostrophe are missing.
Example:
Submitted Words: Just can't get enough
Returned Value (Using $_GET): Just can\
Also the url comes up like this:search=just+can%27t+get+enough
As you can see the ' has been replaced with a \ and get enough is missing.
Question:
Does anybody know what causes this to happen and what is the solution to fix this problem?
The code:
http://tinypaste.com/11d62
If you're running PHP version less than 5.3.0, the slash might be added by the Magic Quotes which you can turn off in the .ini file.
From your description of "value to the text field" I speculate you have some output code like this:
Redisplay
<input value='<?=$_GET['search']?>'>
In that case the contained single quote will terminate the html attribute. And anything behind the single quote is simply garbage to the browser. In this case applying htmlspecialchars to the output helps.
(The backslash is likely due to magic_quotes or mysql_*_escape before outputting the text. I doubt the question describes a database error here.)
Update: It seems it's indeed an output problem here:
echo "<a href='searchmusic.php?search=$search&s=$next'>Next</a>";
Regardless of if you use single or double quotes you would need:
echo "<a href='searchmusic.php?search="
. htmlspecialchars(stripslashes($search))
. "&s=$next'>Next</a>";
(Notice that using stripslashes is a workaround here. You should preserve the original search text, or disable the magic_quotes rather.)
Okay I forgot something crucial. htmlspecialchars needs the ENT_QUOTES parameter - always, and in your case particularly:
// prepare for later output:
$search = $_GET['search'];
$html_search = htmlspecialchars(stripslashes($search), ENT_QUOTES);
And then use that whereever you wanted to display $search before:
echo "<a href='searchmusic.php?search=$html_search&s=$next'>Next</a>";
Single quotes are important in PHP and MySQL.
A single quote is a delimeter for a string in PHP, for example:
$str = 'my string';
If you want to include a literal quote inside a string you must tell PHP that the quote is not the end of the string. It is escaped with the backslash, for example:
$str = 'my string with a quote \' inside it';
See PHP Strings for more on this.
MySQL operates in a similar way. An example query might be:
$username = 'andyb';
$quert = "SELECT * FROM users WHERE user_name = '$username'";
The single quote delimits the string parameter. If the $username included a single quote, this would cause the query to end prematurely. Correctly escaping parameters is an important concept to be familiar with as it is one attack vector for breaking into a database - see SQL Injection for more information.
One way to handle this escaping is with mysql_real_escape_string().

keep textarea input format after using mysql_real_escape_string to store

I am using php5.3.6 and mysql 5.1.56 and CodeIgniter. Here is what I did.
Input some text in textarea, something like this:
what's this?
I'm bob.
$string = $_POST['name'];
$insertdata = mysql_real_escape_string($string);
Insert $insertdata into database.
It shows "what\'s this?\n\n\nI\'m bob."(without double quotes) in the table.
Query the data stored in database, use stripslashes on it and then put it back to the textarea.
It shows "what's this?nnnI'm bob."(without double quotes) in the textarea.
My questions are:
In step 4, shouldn't it be "what\'s this?\n\n\n I\'m bob." stored in the table?
I checked php manual. It says:
mysql_real_escape_string() calls
MySQL's library function
mysql_real_escape_string, which
prepends backslashes to the following
characters: \x00, \n, \r, \, ', " and
\x1a.
How am I supposed to keep the textarea input format after using mysql_real_escape_string()?
Is there anyway to choose which slash to strip and which not to?
Notes:
magic quotes option is off
I did not use stripslashes() before
using mysql_real_escape_string()
If I use addslashes() instead of
mysql_real_escape_string(),
everything works fine.
I don' want to use addslashes() since
it is not as secure as
mysql_real_escape_string(), as far as
I know.
Thanks,
Milo
This really does feel a lot like magic_quotes_gpc = On. Are you disabling it in php.ini or at runtime? It needs to be the former, otherwise it'll remain on.
http://www.php.net/manual/en/security.magicquotes.disabling.php
The magic_quotes_gpc directive may only be disabled at the system level, and not at runtime. In otherwords, use of ini_set() is not an option.
Short answer:
// double quotes are *very* important, or chars are not interpreted
$text_from_db=str_replace("\\r","\r",str_replace("\\n","\n",$text_from_db));
Long answer
Pretty simple but tricky.
You write your textarea and hit the "return" key, there is placed a \r\n (on Windows systems) with slashes that escape the "r" and "n" letter rising their special meaning of carriage return and newline.
You actually can't see them because they are "not printable" chars.
The slash char itself (0x1B) is invisible, that is a single slash is a "not printable" char, to make it visible you have to "transform" it in a printable slash char (0x5C) and to achieve that you have to double it "\\".
Now back to the question: if you can read the slash, probably that's beacuse that slash is not the 0x1B but rather 0x5C, so the "n" and "r" lose their special meaning and you get them as mere strings.
The code I posted does this conversion, converting the "[0x5C]n" string in a "[0x1B]" char.
Notes
Hope this helps, it did for me. IMPORTANT : it is not normal that the text that comes from the db has this issue if it has been stored correctly. My suggestion is to triple check insertion and retrieving because (given from the issue) you could be applying the quoting twice somewhere.
The Best Solution..
$insertdata = mysql_real_escape_string($string); (You can insert it in your database if you want)
echo stripslashes(str_replace('\r\n',PHP_EOL,$insertdata)); (The output is exactly as your input was)
You must escape data before inserting it into the database, to ensure you do not produce broken queries and to avoid SQL injections.
However, when you retrieve that data via a SELECT, you'll receive the data unescaped, ready to be used.
MySQL escapes the string, but when displaying the result back to you it will give you the same result as if it was unescaped.

Can't see new lines on textarea - what could the problem be?

I have a php string with a lot of information to be displayed inside a textarea html element.
I don't have access to that textarea nor to the script (if any) that generates it.
$somestring = 'first line \nSecond line \nThird line.';
$somestring as NOT been "worked" with trim or filter_var. Nothing.
On the textfield, I get the \n printed on the textarea hence, not interpreted.
What can I try in order to have those new lines applied?
Thanks in advance.
Try wrapping $somestring with " (double quotes) instead of ' (single quotes)
\n, \r and other backslash escape characters only works in double quotes and heredoc. In single quotes and nowdoc (the single quote version of heredoc), they are read as literal \n and \r.
Example:
<?php
echo "Hello\nWorld"; // Two lines: 'Hello' and 'World'
echo 'Hello\nWorld'; // One line: literally 'Hello\nWorld'
echo <<<HEREDOC
Hello\nWorld
HEREDOC; // Same as "Hello\nWorld"
echo <<<'NOWDOC'
Hello\nWorld
NOWDOC; // Same as 'Hello\nWorld' - only works in PHP 5.3.0+
Read more about this behaviour in the PHP manual
EDIT:
The reason single and double quotes behave differently is because they are both needed in different situations.
For instance, if you would have a string with a lot of new lines, you would use double quotes:
echo "This\nstring\nhas\na\nlot\nof\nlines\n";
But if you would use a string with a lot of backslashes, such as a file name (on Windows) or a regular expression, you would use single quotes to simplify it and avoid having unexpected problems by forgetting to escape a backslash:
echo "C:\this\will\not\work"; // Prints a tab instead of \t and a newline instead of \n
echo 'C:\this\would\work'; // Prints the expected string
echo '/regular expression/'; // Best way to write a regular expression
$somestring = "first line \nSecond line \nThird line.";
http://php.net/types.string <-- extremely useful reading
this article is a cornerstone of PHP knowledge and it's just impossible to use PHP without it.
unlike most of manual pages which are are just for quick reference, this very page is one which every developer should learn by heart.

Categories