Handling strings with linebreaks in vars - php

I'm trying to get it once again.
I got a JS var which looks like this:
var test;
Now I write some JS with PHP:
<?php
$phpvar = "a text with
a linebreak";
echo "<script type='text/javascript'>
var test;
test = '" . $phpvar . "';
</script>";
?>
Now, if I run it, it outputs the source as follows:
<script type='text/javascript'>
var test;
test = 'a text with
a linebreak';
</script>
This gives me a JS exception:
ERROR: unterminated string literal
Somehow, JS seems not to recognize that there is a string on more than one line.
How can I realize this if, in the end, the string must have its linebreak again? (So, if all execution finishes, I must have the string including all linebreaks)
Thank you for your help ;)

Try this, if you use a \ at the end of a Javascript line, you can use multiple lines within a string.
<?php
$phpvar = "a text with
a linebreak";
echo "<script type='text/javascript'>
var test;
test = '" . str_replace("\n", "\\\n",$phpvar) . "';
</script>";
?>

escaping in php:
js: php:
<linebreak> \n
\ \\
\n \\n
If you want this:
var test = "te\
st";
console.log(test) > "test"
in this case you need to use a \ and <linebreak> (in js), so you need to replace the \n to \\ plus \n (in php)
<?php
$phpvar = "a text with
a linebreak";
echo "<script type='text/javascript'>
var test;
test = '" . str_replace("\n", "\\\n",$phpvar) . "';
</script>";
?>
this keep the linebreaks as a php but not in the javasccript
But if you want to keep the linebreaks in javascript like this:
console.log(test) > "te
st"
You need to add a \n as an escaped string, not as a linebreak character.
So the code will look like this
var test = "te\n\
st"
console.log(test) > "te
st"
In this case you need a \n and a \ and a <linebeak> (in js), so you need to replace the the \n to a \\n plus \\ plus \n
<?php
$phpvar = "a text with
a linebreak";
echo "<script type='text/javascript'>
var test;
test = '" . str_replace("\n", "\\n\\\n",$phpvar) . "';
</script>";
?>
this keeps the linebreaks in php, and also add linebreaks into the javascript

Related

PHP str_replace of input from javascript

I am running some ajax that sends escaped text from the client to a php page running on the server. The text has some carriage returns in it. When I echo these out using php they show up in the text as \n.
However when I try to replace \n using str_replace, the function does not find them.
This has been driving me crazy.
By contrast, I manually created a variable in the same php file with a bunch of \n s in it and in that case the same str_replace code replaced them fine.
Could there be some invisible characters or something throwing it off?
Thanks for any suggestions.
Following replace (all in PHP) works fine
$var = "some text\nsomemore text\nsome more text\nsome more";
echo $var; //displays above text
$strComma = str_replace("\n",",",$var);
echo "strComma".$strComma; \\all of the \n instances are replaced by comma
Following replace does not work
javascript (abbreviated)
var text = document.getElementById(textbox).value; //grabs text from client html
var text2 = escape(text); //escape needed to handle special characters in text
//send to php page
xmlhttp.open("GET","storetext.php?text="+text2,true);
xmlhttp.send();
PHP
$var = $_REQUEST['text'];
echo $var; //displays \n as above. So far so good.
$strComma = str_replace("\n",",",$var);
echo "strComma".$strComma; \\ replacement does not take place
This should work:
$strComma = str_replace("\\n",",",$var);
Two backslashes and then the n character. Like escaping the escape sequence.
When I try with str_replace nothing changes, but using preg_replace it does like this
$strComma = preg_replace("/\n/",",",$var);
ok, html
<html>
<head>
<script src="../../js/jquery_1_8_min.js" type="text/javascript"></script>
</head>
<body>
<script>
text = "some text\nsomemore text\nsome more text\nsome more";
text2 = escape(text)
$.post('lixo.php?'+Math.random(),{text:text2}, function(data) {
alert(data);
});
</script>
</body>
</html>
php
<?php
$var = $_POST["text"];
echo $var; //displays above text
$strComma = preg_replace("/%0A/",",",$var);
$strComma = preg_replace("/%20/",",",$var);
echo "<br>strComma = ".$strComma;
?>
when you escape your text \n becames %0A and white space becames %20
better php
<?php
$var = $_POST["text"];
echo $var."<br>";
$patterns = array();
$patterns[0] = "/%0A/";
$patterns[1] = "/%20/";
$replacements = array();
$replacements[0] = ",";
$replacements[1] = " ";
$strComma = preg_replace($patterns, $replacements,$var);
echo "<br>strComma = ".$strComma;
?>

How to escape backslashes in files

I am trying to work on a script but I am stuck in one place.
Eg. To get a php output I have used..
str_php = """
<?php
echo "Hello World!";
?>"""
php_file = open("index.php", "w")
php_file.write(str_php)
php_file.close()
Ok, so I get the output as it is....
<?php
echo "Hello World!";
?>
So my php code is running. all good till here. But, the problem starts from when I try using "\" and "\n" and "\r"
str_php = """
<?php
echo "Hello World!"; \n echo "How are you"; \n echo "God bless you";
?>"""
php_file = open("index.php", "w")
php_file.write(str_php)
php_file.close()
But here I dont get the output as it is.
<?php
echo "Hello World!";
echo "How are you";
echo "God bless you";
?>
And the "\" it just vanishes... at an output.
Eg. I want an output of a php hyperlink something like...
str_php = """<?php
print("$dirArray[$index]");
?>"""
php_file = open("index.php", "w")
php_file.write(str_php)
php_file.close()
and the output I get is...
<?php
print("$dirArray[$index]");
?>
The "\" is missing and the php does not run creating error.
print("$dirArray[$index]") - Original
print("$dirArray[$index]") - python output
Can any one help me out with "\", "\n", "\r" ??
Just use "\" to escape the "\" character.
Since it is common to want to have long strings containing several "\", Python also allows one
to prefix the string opening quotes if ar r (for "raw") - inside such
a string, no escaping of "\n" to chr(10) or "\t" to chr(9) happens:
>>> print (r"Hello \n world!")
Hello \n world!
You need to escape your "\" with another backslash writting it as "\\".
If you use "\n" it will be parsed and make a newline. Try to use '\n', strings enclosed in '\n' are not parsed and it should print out as you want it to.

Php output breaks the Javascript

i have php variables that is like this
var externalData = '<?php echo $matches[0]; ?>';
I when i load the source code of the page comes like this
var externalData = 'data,data,data,data,data
';
this breaks the javascript code, and browser cant run it.
I want to be like this:
var externalData = 'data,data,data,data,data';
the php output is a full line of a file, so may contains the end of the line.
I test it by hand and working, how i can fix this?
You can use trim (or rtrim) to remove the line break at the end of the string:
var externalData = "<?php echo trim($matches[0]); ?>";
Alternatively you could pass the whole string to json_encode:
var externalData = <?php echo json_encode($matches[0]); ?>;
This would not remove the line break, but it would encode it and the resulting value will be a valid JS string literal (i.e. all other characters that could break the code, such as ' or ", will escaped as well).
Maybe you should strip all HTML
var externalData = "<?php echo strip_tags($matches[0];) ?>");
You can also use substr() to get rid of the last char of string.
Like this:
var externalData = "<?php echo substr($matches[0], 0, strlen($matches[0]) - 1); ?>";

How to handle newlines in Javascript? (from PHP)

I have code like this:
<?php
echo '<script type="text/javascript">';
echo 'var out="'.$txt.'";';
echo '</script>';
?>
Where $txt is a PHP variable that can contain newlines like this:
line1
line2 hello world
Which would end up like this:
var out="line1
line2 hello world";
Which will cause a Javascript error, of course.
What is the best way to handle this? The out variable will be used in a HTML textarea, so I don't think it can be parsed into <br>
$txt = str_replace( array( "\n", "\r" ), array( "\\n", "\\r" ), $txt );
should replace newlines. Don't do it this way.
This is a naïve implementation of string escaping for JavaScript. As you're actually trying to format a string for use in JavaScript, a much better solution would be to use json_encode:
$txt = json_encode($txt);
echo "<script>var out={$txt};</script>";
json_encode will correctly escape special characters in strings, such as quotes, tabs, form feeds, and other special unicode characters. It will also perform all the correct escaping for converting objects, arrays, numbers, and booleans.
you can add a \ at the end of a line to create a multi line String
var out="line1 \
line2 hello world";
Most of these don't work for me.
Normally, I'd use json_encode like
<?php
$MyVar = json_encode($MyVar);
?>
<javascript language='javascript'>
MyVar = <?php echo $MyVar; ?>
But for a quick fix you can just break a line like this:
Pay attention to the double quotes.
<?php
$MyVar = "line one here
then line two here
finally line five here";
//** OR
$MyVar = $MyVarA .
"
"
. $MyVarB;
?>
<HTML>
<HEAD>
<javascript language='javascript'>
Myvar = "<?php echo $MyVar; ?>";
. . .
You can use str_replace to convert line breaks into a different character (in this case, perhaps a space, but it depends how you want the output to show up)
$out = str_replace("\n", '\n', $in);
$content = str_replace( "\\n", "\\\\\\n", $content );
Result:
var a = "Hello \
World"
I tried this and it worked well.
<?php
echo '<script type="text/javascript">';
$txt = "line1 \\n line2 hello world";
echo 'var out="'.$txt.'";';
echo '</script>';
?>
I am using PHP 5.3

PHP's json_encode does not escape all JSON control characters

Is there any reasons why PHP's json_encode function does not escape all JSON control characters in a string?
For example let's take a string which spans two rows and has control characters (\r \n " / \) in it:
<?php
$s = <<<END
First row.
Second row w/ "double quotes" and backslash: \.
END;
$s = json_encode($s);
echo $s;
// Will output: "First row.\r\nSecond row w\/ \"double quotes\" and backslash: \\."
?>
Note that carriage return and newline chars are unescaped. Why?
I'm using jQuery as my JS library and it's $.getJSON() function will do fine when you fully, 100% trust incoming data. Otherwise I use JSON.org's library json2.js like everybody else.
But if you try to parse that encoded string it throws an error:
<script type="text/javascript">
JSON.parse(<?php echo $s ?>); // Will throw SyntaxError
</script>
And you can't get the data! If you remove or escape \r \n " and \ in that string then JSON.parse() will not throw error.
Is there any existing, good PHP function for escaping control characters. Simple str_replace with search and replace arrays will not work.
function escapeJsonString($value) {
# list from www.json.org: (\b backspace, \f formfeed)
$escapers = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c");
$replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b");
$result = str_replace($escapers, $replacements, $value);
return $result;
}
I'm using the above function which escapes a backslash (must be first in the arrays) and should deal with formfeeds and backspaces (I don't think \f and \b are supported in PHP).
D'oh - you need to double-encode: JSON.parse is expecting a string of course:
<script type="text/javascript">
JSON.parse(<?php echo json_encode($s) ?>);
</script>
I still haven't figured out any solution without str_replace..
Try this code.
$json_encoded_string = json_encode(...);
$json_encoded_string = str_replace("\r", '\r', $json_encoded_string);
$json_encoded_string = str_replace("\n", '\n', $json_encoded_string);
Hope that helps...
$search = array("\n", "\r", "\u", "\t", "\f", "\b", "/", '"');
$replace = array("\\n", "\\r", "\\u", "\\t", "\\f", "\\b", "\/", "\"");
$encoded_string = str_replace($search, $replace, $json);
This is the correct way
Converting to and fro from PHP should not be an issue.
PHP's json_encode does proper encoding but reinterpreting that inside java script can cause issues. Like
1) original string - [string with nnn newline in it] (where nnn is actual newline character)
2) json_encode will convert this to
[string with "\\n" newline in it] (control character converted to "\\n" - Literal "\n"
3) However when you print this again in a literal string using php echo then "\\n" is interpreted as "\n" and that causes heartache. Because JSON.parse will understand a literal printed "\n" as newline - a control character (nnn)
so to work around this: -
A)
First encode the json object in php using json_enocde and get a string. Then run it through a filter that makes it safe to be used inside html and java script.
B)
use the JSON string coming from PHP as a "literal" and put it inside single quotes instead of double quotes.
<?php
function form_safe_json($json) {
$json = empty($json) ? '[]' : $json ;
$search = array('\\',"\n","\r","\f","\t","\b","'") ;
$replace = array('\\\\',"\\n", "\\r","\\f","\\t","\\b", "&#039");
$json = str_replace($search,$replace,$json);
return $json;
}
$title = "Tiger's /new \\found \/freedom " ;
$description = <<<END
Tiger was caged
in a Zoo
And now he is in jungle
with freedom
END;
$book = new \stdClass ;
$book->title = $title ;
$book->description = $description ;
$strBook = json_encode($book);
$strBook = form_safe_json($strBook);
?>
<!DOCTYPE html>
<html>
<head>
<title> title</title>
<meta charset="utf-8">
<script type="text/javascript" src="/3p/jquery/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var strBookObj = '<?php echo $strBook; ?>' ;
try{
bookObj = JSON.parse(strBookObj) ;
console.log(bookObj.title);
console.log(bookObj.description);
$("#title").html(bookObj.title);
$("#description").html(bookObj.description);
} catch(ex) {
console.log("Error parsing book object json");
}
});
</script>
</head>
<body>
<h2> Json parsing test page </h2>
<div id="title"> </div>
<div id="description"> </div>
</body>
</html>
Put the string inside single quote in java script. Putting JSON string inside double quotes would cause the parser to fail at attribute markers (something like { "id" : "value" } ). No other escaping should be required if you put the string as "literal" and let JSON parser do the work.
I don't fully understand how var_export works, so I will update if I run into trouble, but this seems to be working for me:
<script>
window.things = JSON.parse(<?php var_export(json_encode($s)); ?>);
</script>
Maybe I'm blind, but in your example they ARE escaped. What about
<script type="text/javascript">
JSON.parse("<?php echo $s ?>"); // Will throw SyntaxError
</script>
(note different quotes)
Just an addition to Greg's response: the output of json_encode() is already contained in double-quotes ("), so there is no need to surround them with quotes again:
<script type="text/javascript">
JSON.parse(<?php echo $s ?>);
</script>
Control characters have no special meaning in HTML except for new line in textarea.value . JSON_encode on PHP > 5.2 will do it like you expected.
If you just want to show text you don't need to go after JSON. JSON is for arrays and objects in JavaScript (and indexed and associative array for PHP).
If you need a line feed for the texarea-tag:
$s=preg_replace('/\r */','',$s);
echo preg_replace('/ *\n */','
',$s);
This is what I use personally and it's never not worked. Had similar problems originally.
Source script (ajax) will take an array and json_encode it. Example:
$return['value'] = 'test';
$return['value2'] = 'derp';
echo json_encode($return);
My javascript will make an AJAX call and get the echoed "json_encode($return)" as its input, and in the script I'll use the following:
myVar = jQuery.parseJSON(msg.replace(/"/ig,'"'));
with "msg" being the returned value. So, for you, something like...
var msg = '<?php echo $s ?>';
myVar = jQuery.parseJSON(msg.replace(/"/ig,'"'));
...might work for you.
There are 2 solutions unless AJAX is used:
Write data into input like and read it in JS:
<input type="hidden" value="<?= htmlencode(json_encode($data)) ?>"/>
Use addslashes
var json = '<?= addslashes(json_encode($data)) ?>';
When using any form of Ajax, detailed documentation for the format of responses received from the CGI server seems to be lacking on the Web. Some Notes here and entries at stackoverflow.com point out that newlines in returned text or json data must be escaped to prevent infinite loops (hangs) in JSON conversion (possibly created by throwing an uncaught exception), whether done automatically by jQuery or manually using Javascript system or library JSON parsing calls.
In each case where programmers post this problem, inadequate solutions are presented (most often replacing \n by \\n on the sending side) and the matter is dropped. Their inadequacy is revealed when passing string values that accidentally embed control escape sequences, such as Windows pathnames. An example is "C:\Chris\Roberts.php", which contains the control characters ^c and ^r, which can cause JSON conversion of the string {"file":"C:\Chris\Roberts.php"} to loop forever. One way of generating such values is deliberately to attempt to pass PHP warning and error messages from server to client, a reasonable idea.
By definition, Ajax uses HTTP connections behind the scenes. Such connections pass data using GET and POST, both of which require encoding sent data to avoid incorrect syntax, including control characters.
This gives enough of a hint to construct what seems to be a solution (it needs more testing): to use rawurlencode on the PHP (sending) side to encode the data, and unescape on the Javascript (receiving) side to decode the data. In some cases, you will apply these to entire text strings, in other cases you will apply them only to values inside JSON.
If this idea turns out to be correct, simple examples can be constructed to help programmers at all levels solve this problem once and for all.

Categories