Markdown And Escaping Javascript Line Breaks - javascript

I am writing a markdown compiler in Erlang for server-side use. Because it will need to work with clients I have decided to adopt the client side library (showdown.js) as the specification and then test my code for compatibility with that.
In the first couple of iterations I built up 260-odd unit tests which checked that my programme produced output which was compatible with what I thought was valid markdown based on reading the syntax notes.
But now I am trying to write a javascript programme to generate my unit tests.
I have an input like:
"3 > 4\na"
I want to run 'showdown' on it to get:
"<p>3 > 4\na</p>"
and I want to stitch this up into an EUnit assertion:
"?_assert(conv(\"3 > 4\na\") == \"<p>3 > 4\na</p>\"),",
which is the valid Erlang syntax for the unit test. To make life easy, and to make the unit test generator portable I am doing it inside a web page so that by appending some lines to a javascript file and then view the page you get the new set of unit tests inside a <textarea /> which you then copy down into the module to run EUnit.
The problem is that I can't get the line breaks to convert to \n in the string so I end up with:
"?_assert(conv(\"3 > 4
a\") == \"<p>3 > 4
a</p>\"),",
I've tried converting the linefeeds to their escaped versions using code like:
text.replace("\\", "\\\\");
text.replace("\n", "\\n");
but no joy...

Tom McNulty helped me out and pointed out that my regex's were super-pants, in particular I wasn't using the global flag :(
The working code is:
var converter;
var text = "";
var item;
var input;
var output;
var head;
var tail;
converter = new Attacklab.showdown.converter();
item = document.getElementById("tests");
for (var test in tests) {
input = tests[test].replace(/[\n\r]+/gi,"\\n" );
input = input.replace(/[\"]+/gi, "\\\"");
output = converter.makeHtml(tests[test]).replace(/[\n\r]+/gi, "\\n");
output = output.replace(/[\"]+/gi, "\\\"");
text += " ?_assert(conv(\"" + input + "\") == \"" + output + "\"),\n";
};
head = "unit_test_() -> \n [\n";
tail = "\n ].";
text = text.slice(0, text.length - 2);
item.value = head + text + tail;

Related

String.split function is not working properly with some text

I have string parser in node.js. Input string comes from telegram channel.
Now I have serious problem with String.split function.
It works with some types of text but it doesn't work with some other texts.
When I receive not processed string in telegram, I just copy and send it in the channel again.
In this case, parser processes it well.
Is there any advise for this issue?
let teams = [];
teamSeps =[" vs ", " v ", " - ", " x " ,"-", " -"];
for(let i = 0; i< teamSeps.length; i++){
teams = newTip.Match.toLowerCase().split(teamSeps[i]);
if(teams.length === 2) break;
}
newTip.Home = teams[0].trim();
newTip.Away = teams[1].trim();
return;
Instead of adding multiple options with optional spaces on either side of -, you can use a single regex with some alternation.
/\s*-\s*|\s+(?:vs|v|x)\s+/
\s*-\s*: Allows optional space around -
\s+(?:vs|v|x)\s+: Allows at least one space around vs or v or x (Otherwise, if there is a x or v in the string, it will split)
function customSplit(str) {
return str.split(/\s*-\s*|\s+(?:vs|v|x)\s+/);
}
console.log(customSplit("Man United vs Man City"))
console.log(customSplit("France - Croatia"))
console.log(customSplit("Belgium-England"))
console.log(customSplit("Liverpool x Spurs"))

Why aren't there line breaks in this <pre> tag?

I'm using highlight.js to display some JSON I'm receiving from a pubnub subscription. It is coloring the text but it is not adding line breaks as expected (via their demos). Also, a couple places in the documentation give the impression that the library generates new lines. See the useBR option here.
Here is my current code (I've tried a few different things):
pubnub.subscribe({
channel : 'TEST',
message : function(m){
console.log(m);
var hlt = hljs.highlight('json',m);
$('#jsonOutput').html("<pre>" + hlt.value + "</pre>");
}
});
And here is what the DOM looks like:
But here is the output:
How can I get line breaks? I want it to look similar to this:
{
"id":"TESTWIDGET1",
"value":371,
"timestamp":"2016-08-31T11:39:57.8733485-05:00"
}
fiddle: https://jsfiddle.net/vgfnod58/
You don't have any line-breaks in your code. The highlight function will only apply the formatting options, when the json-string was formatted. You string is only one single line. So, you will have to bring it in the right format first and then you can highlight it:
function print_r(object,html){
if(html) return '<pre>' + JSON.stringify(object, null, 4) + '</pre>';
else return JSON.stringify(object, null, 4);
}
var m = {"id":"TESTWIDGET1","value":351,"timestamp":"2016-08-31T12:03:24.3403952-05:00"};
var hlt = hljs.highlight('json',print_r(m));
$('#codehere').html(hlt.value);
Please be aware that I changed the var m from string to object (just remove the sourrunding ').
A working fiddle: https://jsfiddle.net/WalterIT/vgfnod58/2/
You should be able to substitute using <div> element with css white-space set to pre for <pre> element
Edit, Updated
Alternative approach inserting non-breaking space and newline characters before and after highlighted <span> elements
var m = '{"id":"TESTWIDGET1","value":351,"timestamp":"2016-08-31T12:03:24.3403952-05:00"}';
// hljs.configure({useBR: true});
var hlt = hljs.highlight('json',m);
$('#codehere').html(hlt.value)
$('#codehere span').each(function(i) {
if (i % 2 === 0)
$(this).before("\n ");
if (i === $('#codehere span').length -1)
$(this).after("\n")
});
jsfiddle https://jsfiddle.net/vgfnod58/3/

regexp looping and logic in javascript

Not certain if this can be done in regexp under javascript, but thought it would be interesting to see if it is possible.
So thought I would clean up a piece of html to remove most tags, literally just dropping them, so <H1><img><a href ....>. And that would be relatively simple (well, stole the basis from another post, thanks karim79 Remove HTML Tags in Javascript with Regex).
function(inString, maxlength, callback){
console.log("Sting is " + inString)
console.log("Its " + inString.length)
var regex = /(<([^>]+)>)/ig
var outString = inString.replace(regex, "");
console.log("No HTML sting " + outString);
if ( outString.length < maxlength){
callback(outString)
} else {
console.log("Lets cut first bit")
}
}
But then I started thinking, is there a way where I can control regex execution. So lets say that I want to keep certain tabs, like b,br,i and maybe change H1-6 to b. So in pseudo code, something like:
for ( var i in inString.regex.hits ) {
if ( hits[i] == H1 ) {
hits[i] = b;
}
}
The issue is that I want the text thats not HTML tags to stay as it is, and I want it to just cut out by default. One option would of course be to change the ones I want to keep. Say change <b> to [[b]], once that is done to all the ones of interest. Then put them back to <b> once all unknown have been removed. So like this (only for b, and not certain the code below would work):
function(inString, maxlength, callback){
console.log("Sting is " + inString)
console.log("Its " + inString.length)
var regex-remHTML = /(<([^>]+)>)/ig
var regex-hideB = /(<b>)/ig
var regex-showB = /([b])/ig
var outString = inString.replace(regex-hideB, "[b]");
outString = outString.replace(regex-remHTML, "");
outString = outString.replace(regex-showB, "<b>");
console.log("No HTML sting " + outString);
if ( outString.length < maxlength){
callback(outString)
} else {
console.log("Lets cut first bit")
}
}
But would it be possible to be smarter, writing cod ethat says here is a peice of HTML tag, run this code against the match.
As Tim Biegeleisen sai in its comment, maybe a better solution could be using a parser instead of a Regex...
By the way, if you want to control what is going to be changed by the regex you can pass a callback to the String.prototype.replace:
var input = "<div><h1>CIAO Bello</h1></div>";
var output = input.replace(/(<([^>]+)>)/gi, (val) => {
if(val.indexOf("div") > -1) {
return "";
}
return val;
})
;
console.log("output", output);

Replace array-mapped variables with the actual variable name/string?

I am trying to edit a Greasemonkey/jQuery script. I can't post the link here.
The code is obfuscated and compressed with minify.
It starts like this:
var _0x21e9 = ["\x67\x65\x74\x4D\x6F\x6E\x74\x68", "\x67\x65\x74\x55\x54\x43\x44\x61\x74\x65", ...
After "decoding" it, I got this:
var _0x21e9=["getMonth","getUTCDate","getFullYear", ...
It is a huge list (500+ ). Then, it has some variables like this:
month = date[_0x21e9[0]](), day = date[_0x21e9[1]](), ...
_0x21e9[0] is getMonth, _0x21e9[1] is getUTCDate, etc.
Is it possible to replace the square brackets with the actual variable name? How?
I have little knowledge in javascript/jQuery and can not "read" the code the way it is right now.
I just want to use some functions from this huge script and remove the others I do not need.
Update: I tried using jsbeautifier.org as suggested here and in the duplicated question but nothing changed, except the "indent".
It did not replace the array variables with the decoded names.
For example:
jsbeautifier still gives: month = date[_0x21e9[0]]().
But I need: month = date["getMonth"]().
None of the online deobfuscators seem to do this, How can I?
Is there a way for me to share the code with someone, at least part of it? I read I can not post pastebin, or similar here. I can not post it the full code here.
Here is another part of the code:
$(_0x21e9[8] + vid)[_0x21e9[18]]();
[8] is "." and [18] is "remove". Manually replacing it gives a strange result.
I haven't seen any online deobfuscator that does this yet, but the principle is simple.
Construct a text filter that parses the "key" array and then replaces each instance that that array is referenced, with the appropriate array value.
For example, suppose you have a file, evil.js that looks like this (AFTER you have run it though jsbeautifier.org with the Detect packers and obfuscators? and the Unescape printable chars... options set):
var _0xf17f = ["(", ")", 'div', "createElement", "id", "log", "console"];
var _0x41dcx3 = eval(_0xf17f[0] + '{id: 3}' + _0xf17f[1]);
var _0x41dcx4 = document[_0xf17f[3]](_0xf17f[2]);
var _0x41dcx5 = _0x41dcx3[_0xf17f[4]];
window[_0xf17f[6]][_0xf17f[5]](_0x41dcx5);
In that case, the "key" variable would be _0xf17f and the "key" array would be ["(", ")", ...].
The filter process would look like this:
Extract the key name using text processing on the js file. Result: _0xf17f
Extract the string src of the key array. Result:
keyArrayStr = '["(", ")", \'div\', "createElement", "id", "log", "console"]';
In javascript, we can then use .replace() to parse the rest of the JS src. Like so:
var keyArrayStr = '["(", ")", \'div\', "createElement", "id", "log", "console"]';
var restOfSrc = "var _0x41dcx3 = eval(_0xf17f[0] + '{id: 3}' + _0xf17f[1]);\n"
+ "var _0x41dcx4 = document[_0xf17f[3]](_0xf17f[2]);\n"
+ "var _0x41dcx5 = _0x41dcx3[_0xf17f[4]];\n"
+ "window[_0xf17f[6]][_0xf17f[5]](_0x41dcx5);\n"
;
var keyArray = eval (keyArrayStr);
//-- Note that `_0xf17f` is the key name we already determined.
var keyRegExp = /_0xf17f\s*\[\s*(\d+)\s*\]/g;
var deObsTxt = restOfSrc.replace (keyRegExp, function (matchStr, p1Str) {
return '"' + keyArray[ parseInt(p1Str, 10) ] + '"';
} );
console.log (deObsTxt);
if you run that code, you get:
var _0x41dcx3 = eval("(" + '{id: 3}' + ")");
var _0x41dcx4 = document["createElement"]("div");
var _0x41dcx5 = _0x41dcx3["id"];
window["console"]["log"](_0x41dcx5);
-- which is a bit easier to read/understand.
I've also created an online page that takes JS source and does all 3 remapping steps in a slightly more automated and robust manner. You can see it at:
jsbin.com/hazevo
(Note that that tool expects the source to start with the "key" variable declaration, like your code samples do)
#Brock Adams solution is brilliant, but there is a small bug: it doesn't take into account simple quoted vars.
Example:
var _0xbd34 = ["hello ", '"my" world'];
(function($) {
alert(_0xbd34[0] + _0xbd34[1])
});
If you try to decipher this example, it will result on this:
alert("hello " + ""my" world")
To resolve this, just edit the replacedSrc.replace into #Brock code:
replacedSrc = replacedSrc.replace (nameRegex, function (matchStr, p1Str) {
var quote = keyArry[parseInt (p1Str, 10)].indexOf('"')==-1? '"' : "'";
return quote + keyArry[ parseInt (p1Str, 10) ] + quote;
} );
Here you have a patched version.
for (var i = 0; i < _0x21e9.length; i++) {
var funcName = _0x21e9[i];
_0x21e9[funcName] = funcName;
}
this will add all the function names as keys to the array. allowing you to do
date[_0x21e9["getMonth"]]()

Unexpected Token Illegal with onclick Java Script in Salesforce.com

I have been working on this most of the morning but to no end. I am trying to execute a button that uses OnClick Java in Salesforce.com and it keeps throwing errors. I think the issue may be with special characters in the data as it works when I simply use just text. But any time numbers or any special characters are present I get the error "unexpected token ILLEGAL". Can anyone help me to see what I am doing wrong and how I can get away from failing when special characters are involved?
{!REQUIRESCRIPT("/soap/ajax/28.0/connection.js")}
var opptyObj = new sforce.SObject("Opportunity");
var caseObj = new sforce.SObject("Case");
var today = new Date();
var sOpptyId = "{!Case.Opportunity__c}";
if( sOpptyId != "")
{
alert("This case is already tied to an opportunity!");
}
else
{
opptyObj.AccountId = "{!Case.AccountId}";
opptyObj.CloseDate = sforce.internal.dateTimeToString(today);
opptyObj.Description="{!Case.Description}";
opptyObj.Case__c = "{!Case.Id}";
opptyObj.Name = "{!Case.Subject}";
opptyObj.StageName = "Estimate in Progress";
opptyObj.Created_from_Case__c = "Y";
opptyObj.Type = "New Business";
opptyObj.Amount = ".01";
var opptyresult = sforce.connection.create([opptyObj]);
if (opptyresult[0].success=='false')
{
alert("Opportunity creation failed: " + opptyresult[0].errors.message);
}
else
{
caseObj.Id = '{!Case.Id}';
caseObj.Opportunity__c = opptyresult[0].id;
caseObj.Status = "Estimate in Progress";
var caseResult = sforce.connection.update([caseObj]);
if(caseResult[0].success == 'false')
{
alert("Case update failed: " + caseResult[0].errors.message);
}
else
{
alert("An opportunity has been created and linked to this case.");
location.reload(true);
}
}
}
Assuming this is some kind of template, whatever is rendering this needs to properly escape some values in the strings it's inserting.
Given this:
opptyObj.Description="{!Case.Description}";
Let's say I enter a description consisting of this:
"That is awesome," said John.
When that is rendered in your template the result is this:
opptyObj.Description=""That is awesome," said John.";
As you might be able to see, the result is a syntax error.
You need to escape quote characters in an text inserted this way. And without knowing what is technology rendering this template I can't give you any specifics, but you want to replace " with \" and ' with \'. The \ escapes characters, forcing them to be treated as literal characters in the string instead of other special meaning.
This must be done as it's being inserted into the script. Something in the spirit of this:
opptyObj.Description="{!Case.Description.replace(/'/, "\\'").replace(/"/, '\\"')}
Exactly how to do that depends on what language or template engine is being used here. But th eresult should look like this:
opptyObj.Description="\"That is awesome,\" said John.";
Ruby on Rails implements an escape_javascript method, which sanitizes data for injection into Javascript. It does the following replacements. It seems like a good baseline.
'\\' => '\\\\'
'</' => '<\/'
"\r\n" => '\n'
"\n" => '\n'
"\r" => '\n'
'"' => '\\"'
"'" => "\\'"
UPDATE:
According to this: http://www.salesforce.com/us/developer/docs/pages/Content/pages_security_tips_scontrols.htm
It looks like you want the JSENCODE function. Something like this, perhaps?
opptyObj.Description="{!JSENCODE(Case.Description)}";

Categories

Resources