I have a pretty complex problem.
I'm using PHP to parse a CSV file to an array and then
var array = <?php echo json_encode( $array ) ?>;
to pass it to the Javascript array.
array is 2-dimensional, like so:
var array = [["\/\\ssa","14104","26","2113","0","867","28083","15","43695"],
["Yee","8661","24","2215","0","991","25245","15","49086"],...]
Now sometimes there seems to be a problem with backslash escapes in the username when it is structured like this:
["username\","sth","sth",...], so when the username ends with a backslash \ .
The output will be:
username", sth, sth, ...
But this is only the first element of the sub-array, the other 8 places are empty.
I have already tried to fix it with a loop replace, but I don't know how to add \" as search value. Is this impossible to do in JS since \" always escapes? Already tried charAt() to compare the last character with the backslash, but no success. Do I have to replace it before passing it to JS, in PHP?
The Parse function is this, if it's important:
<?php>
$url = "data.csv";
$csvData = file_get_contents($url);
$lines = explode(PHP_EOL, $csvData);
$array = array();
foreach ($lines as $line) {
$array[] = str_getcsv($line);
?>
Here a JSfiddle you can play with: https://jsfiddle.net/cLmbe0qf/
You just need to replace backslashes by an html special character :
foreach ($lines as $line) {
$line = str_replace("\\", "\", $line);
// ...
}
This is a little bit more tricky since you have to parse the javascript into an object/array. Anytime you do this, the backslash is parsed out. To avoid doing this you need to store the value in the HTML page or use String.raw to get the literal version of the string.
One way to implement it is to put the the string in the html and get the value of a hidden textarea. (you could store it anywhere, i just chose textarea). You then pass it through this javascript function slashParse which will replace all slashes with ~{}~ then run the javascript parsing algorithm, then replace the ~{}~ back to the backslashes.
function slashParse(target) {
var value = document.getElementById(target).value;
var replacedVal = value.replace(/\\/g, '~{}~');
var parsedVal = JSON.parse(replacedVal);
var mappedVal = parsedVal.map(function(item) {
return item.replace(/~{}~/g, '\\');
});
return mappedVal;
}
var parsed = slashParse('input');
console.log(parsed)
document.getElementById("test").innerText = parsed;
<body>
<div id="test"></div>
</body>
<textarea style="display:none" id="input">["use\rna</textarea><textarea>me\\","2","3","4"]</textarea>
What echoing it out onto the page might look like would be like this.
<textarea style="display:none" id="php-part">
<?=json_encode(htmlentities($array,ENT_NOQUOTES))?>
</textarea>
This is only one solution of a few more. Another option is to do more parsing on the php side of things. The problem you will run into, is that at some point you need to run the string through the JavaScript parsing program. When that happens you cannot have any backslashes. Then after you run it through the parsing, you will have to convert all hidden backslashes back to backslashes.
The one problem with this method is that if there is anywhere EVER where ~{}~ is being placed in the string, it will be converted to backslashes afterwards. Something you can do in order to make it more aloof is to make the string backslashes get turn into even more obfuscated. Such as ~{BACKSLASH_ESCAPE}~
Related
I have a for loop in which I am printing out content on a web page. Anything with a line break in the database will not work with innerHTML.
Here is the process of how to get a string from the db:
1. Submit a form with text thats gets queried into the database.
2. For loop which displays all the contents in the database using an array,
say $content[i].
value.innerHTML works with any strings that don't have a line break.
For example, in the db:
Hello
there
----- Will not work.
Hello there
----- Will work.
I have tried using regexes to get a line break and change them to br and such, but inner html will not display content with line breaks. Only those without.
My code that I am using:
var commentSection = document.createElement("div");
var str = '<?php echo $comment['contents'];?>';
str = str.replace(/\r\n?|\n/g, '<br />');
var userCommentData = document.createElement("div");
userCommentData.innerHTML = str;
commentSection.appendChild(userCommentData);
And a more clearer picture of the error I am having:
A step of a query string
Use following functions:
htmlentities:Convert all applicable characters to HTML entities
nl2br Inserts HTML line breaks before all newlines in a string
Or maybe change your sql query with TRIM function as used in link
Use backtick character ( ` ) for multiline string in javascript.
use this line { Replace backtick with ( ` ) }
var str = backtick <?php echo $comment['contents'];? > backtick ;
insted of this line
var str = '<?php echo $comment['contents'];? >';
I have some javascript code that gets the value of two html form input fields. I escaped the values to allow users to enter in special characters and then placed them into an array that is stringified and then posted.
$(document).ready(function() {
$("#submit").click(function() {
var BuilderName = escape($('[name=BuilderName]').val());
var OwnersName = escape($('[name=OwnersName]').val());
var arraydata = [BuilderName, OwnersName];
$.post("DCF_Update_Query.php", {
data: JSON.stringify(arraydata)
}, function() {
alert('Successful');
}).fail(function() {
alert('Failed');
});
});
});
In my PHP file I retrieve and decode the array and insert it into my database.
$data = json_decode($_POST['data']);
mysqli_query($conn,"INSERT INTO dcf (BuilderName, OwnersName)
VALUES ('$data[0]','$data[1]')");
My problem is that the escaped characters are entering in the database as %26, %27, etc.. How can I un-escape those characters and then re-escape them using mysqli_real_escape_string(). Also, I've heard that json_decode() automatically escapes special characters. If this is the case, then do I even need to escape them with mysqli_real_escape_string()? I'd greatly appreciate any help, Thanks!
You really, really, REALLY need a prepared statement here. No escaping needed
$prep = $conn->prepare("INSERT INTO dcf (BuilderName, OwnersName) VALUES (?, ?)");
$prep->bind_param('ss', $data[0], $data[1]);
$prep->execute();
Try passing the contents of your $data variable through the urldecode function:
$data = urldecode(json_decode($_POST['data']));
I'm trying to output Javascript code heredoc syntax and I want it to be printed out with the PHP print_r function. Is it possible to do that?
PHP:
<?php
function printR($val){
echo "<pre>";
print_r($val);
echo "</pre>";
}
$str = <<<EOT
var msg = "Hello my name is ";
var name = "Jermaine Forbes";
function writeIt(m,n){
console.log(m+n);
}
writeIt(msg,name);
EOT;
printR($str);
?>
(by #FirstOne: I kept EOT; idented since there was* a comment about it)
Yes you can. If you expect to have only Javascript in the string (no PHP variable), I would use nowdoc instead of heredoc (use single quotes around the opening EOT
$str = <<<'EOT'
var msg = "Hello my name is ";
var name = "Jermaine Forbes";
function writeIt(m,n){
console.log(m+n);
}
writeIt(msg,name);
EOT;
Note also that the closing delimiter must be alone on the final line. You can't have any space before or after it. Your code didn't work because you have indented EOT;. From the docs:
Warning: It is very important to note that the line with the closing
identifier must contain no other characters, except a semicolon (;).
That means especially that the identifier may not be indented, and
there may not be any spaces or tabs before or after the semicolon.
I am trying to parse an KML-File in PHP and parse it using JavaScript. Now I have tried different approaches so far. My problem is, that I seem not to be able to remove every line break from the "xml". With the following method I could force all XML in one line but failed to remove spaces from "<![CDATA[...."
$dom = new DOMDocument();
$dom->preserveWhitespaces = false;
$dom->load("FILE-URL goes here");
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//text()') as $domText) {
$domText->data = trim(str_replace("\r\n","",$domText->nodeValue));
}
$dom->formatOutput = true;
$string = $dom->saveHTML();
With my next try I was able to convert everything into a string, but unable to remove any line breaks from it:
$xml = simplexml_load_file("FILE-URL goes here", 'SimpleXMLElement', LIBXML_NOCDATA);
$string = (string)$xml->asXML();
print_r(trim(preg_replace("/\r\n\t+/","",$string)));
Removing the breaks is necessary for the following JS code to be executed:
geoXml.parseKmlString('<?php print(STRING FROM ABOVE) ?>');
Unfortunately I can't download files onto the server so I am bound to something like the above. Also I can't use PHP to display the map. The KML-File itself is a normal Google-Maps-KML-File.
Your regex in preg_replace is looking for a specific string of whitespace characters:
preg_replace("/\r\n\t+/","",$string);
I'm fairly sure you want to look for any of those characters, i.e.
preg_replace("/[\r\n\t+]/", "", $string);
You can also use str_replace with an array of the whitespace entities that you're looking for:
$ws = array("\r", "\n", "\t");
$newstr = str_replace($ws, "", $string);
Unless speed is an issue, the regex is more flexible.
I am running into an odd little problem with parsing some JSON which has quotes in it. I am using the native JSON.stringify and JSON.parse functions to do this. If I stringify an object which an object which has quote marks in it, they are escaped as one would expect. If I then parse this back into an object, it again works fine.
The problem is occurring where I stringify, then print the object to a page, then parse the resulting string. If I try to do this, the parse function fails as stringify has only put single slashes before each of the offending quote marks.
The reason I need to achieve this is I am working on an application that dynamically loads content stored in a database as JSON strings. The strings at some point need to be printed onto the page somewhere so that the javascript can find them and build the page based on their contents. I need some way of robustly passing the object into and out of strings which will not fail if a user inputs the wrong characters!
I can solve this for the moment by inserting extra slashes into the code with a replace call, but I was wondering if there is a better way to handle this?
I have put together a couple of jsfiddles to illustrate what I am trying to describe:
http://jsfiddle.net/qwUAJ/ (Stringify then parse back)
var ob = {};
ob["number1"] = 'Number "1"';
ob["number2"] = 'Number 2';
ob["number3"] = 'Number 3';
var string = JSON.stringify(ob);
var reOb = JSON.parse('{"number1":"Number \"1\"","number2":"Number 2","number3":"Number 3"}');
$('div').html(string);
http://jsfiddle.net/a3gBf/4/ (Stringify, then print, then parse back)
// Make an object
var ob = {};
ob["number1"] = 'Number "1"';
ob["number2"] = 'Number 2';
ob["number3"] = 'Number 3';
// Turn the object into a JSON string
var string = JSON.stringify(ob);
// Printing the string outputs
// {"number1":"Number \"1\"","number2":"Number 2","number3":"Number 3"}
$('.stringified').html(string);
// Attempt to turn the printed string back into an object
var reOb = JSON.parse('{"number1":"Number \"1\"","number2":"Number 2","number3":"Number 3"}');
// This fails due to the single escaped quote marks.
Thank you for any help in advance!
This is a problem which arises from re-evaluating a String without first converting it back into a string literal, so the meaning changes if it is even still valid.
You need to consider what does '\"' as a literal actually mean? The answer is ", without the \. Why?
\" resolves to "
If you want to have \" as the result of the literal, you need to write '\\\"'
\\ resolves to \
\" resolves to "
So basically, the extra slashes are required to escape any characters with special meaning in string literals.
If you did var reOb = JSON.parse($('.stringified').html()); it would work fine as is.
Consider further
str = '\\\"\\\''; // \"\'
str = '\"\''; // "'
str = '"''; // SyntaxError: Unexpected token ILLEGAL
As far as I'm aware, JavaScript offers no native implementation to convert strings as desired, so the easiest method I know of is using a replace
function toLiteral(str) {
var dict = {'\b': 'b', '\t': 't', '\n': 'n', '\v': 'v', '\f': 'f', '\r': 'r'};
return str.replace(/([\\'"\b\t\n\v\f\r])/g, function ($0, $1) {
return '\\' + (dict[$1] || $1);
});
}
toLiteral('foo\\bar'); // "foo\\bar"
If you generate JS with PHP code you should escape the quotes in your JSON string:
//PHP code generating js code
echo "var myJSONString = \"". str_replace("\"","\\\"",$mySqlJSON)."\";";