JavaScript - Alternatives To The Use Of The Eval Function
Hi - I wrote some code that uses the eval function. I am in the process of rewriting the code to improve on it where possible (a learning exercise). I have read that eval is evil because of security concerns and that the eval'd code is not compiled prior to runtime.
I don't think my use of eval presents a security concern. However, I wonder if there is some way to replace the eval function with a more natural technique. I have done this using eval(); also using a new Function method. I have tried using a window[] method but I can't get that to work. OK, on the the actual code: The purpose of the javascript is to count keystrokes. I have a bunch of global counter variables declared in this fashion: Code: MyLib.CountQ=0; MyLib.CountW=0; MyLib.CountE=0; MyLib.CountR=0; MyLib.CountT=0; MyLib.CountY=0; MyLib.CountU=0; MyLib.CountI=0; MyLib.CountO=0; MyLib.CountP=0; When the Count function is called I want to update the appropriate counter. Thus: MyLib.Count'+varkeyname+'+=1; Where varkeyname is 'q' or 'w' or 'e' etc. Code: //MyLib is a global variable namespace. function Count() {//updates counters var varkeyname= specialchars(MyLib.KeyName);//identity of the key pressed. var stra="Count"+varkeyname;// string used to change an html value. //var strb=eval("MyLib.Count"+varkeyname+"+=1");//original eval function that worked just fine. var strb='return MyLib.Count'+varkeyname+'+=1';//string to update a counter. var myfunc= new Function(strb);//Function intended to replace the eval function - this also works just fine. document.getElementById(stra).value = myfunc(); ... You can see that I have replaced the eval function with another function - but since this is also not compiled prior to runtime I don't think this is an improvement. I have read about using the window[string] method but I can't get it to work. This is not a critical issue but I'd appreciate any comments. Thanks, Jim Similar TutorialsHi All, This is my function function outputSelected() { alert(window.opener.document.forms[0].txt11_19.value); alert(window.opener.document.forms[0].rdo11.length); var questionID = document.forms[0].cntQuestion.value; var choiceID = document.forms[0].cntChoice.value; var txtValue = document.forms[0].strEmpNo.value + " " + document.forms[0].strName.value; alert(txtValue); var leftValue = 'window.opener.document.forms[0].txt' + questionID + '_' + choiceID + '.value =' + txtValue; eval(leftValue); } all the alerts work as expected. bu the eval function does not. error: expected ';' any ideas what is happening. or is there any other way of doing this. Here's the code: Code: for (var i = 1; i < 5; i++) var pl = eval("player" + i) var namepl = eval("document.charInput.name" + i + ".value"); var skillpl = eval("document.charInput.skill" + i + ".value"); var genderpl = eval("document.charInput.gender" + i + ".value"); switch (skillpl) { case "warrior": pl = new player(namepl, skillpl, genderpl, 20, 15, 0, 5, 5, 2, 2, 3, 3, 0, 0); logEntry("black", namepl + " is now a warrior."); break; case "mage": pl = new player(namepl, skillpl, genderpl, 15, 10, 20, 2, 5, 5, 5, 2, 3, 0, 0); logEntry("black", namepl + " is now a mage."); break; case "healer": pl = new player(namepl, skillpl, genderpl, 15, 10, 20, 2, 5, 5, 5, 2, 3, 0, 0); logEntry("black", namepl + " is now a healer."); break; case "archer": pl = new player(namepl, skillpl, genderpl, 20, 15, 0, 3, 3, 2, 2, 5, 5, 0, 0); logEntry("black", namepl + " is now an archer."); break; } } Each player has three form values: document.charInput.name1.value document.charInput.skill1.value document.charInput.gender1.value In the case of the 2nd-4th player, it changes to name2.value, etc. Based on these three inputs, I need to iterate through all four players and make the player object for each of them, as I've done above. If anybody has any ideas on how to correct this or an alternative method, please help. Hi, i want a page with rotation of images, with fading. I'm trying with two images, but i see only the first image. Firebug console give me this error: Quote: $ is not defined: eval ('div =$("#focus_'+categoria+'")'); This is the entire code: Code: <script type="text/javascript"> array_img_2 = Array(); array_img_2[0] = 'PhpLib/../upload/2-Galleria/ima_galleria_03.gif'; array_img_2[1] = 'PhpLib/../upload/2-Galleria/ima_galleria_02.gif'; </script> <noscript>...</noscript> <div id="focus_2"> <a href="index.php?cp=4" title="vai alla gallery"> <img width="924" alt="immagini dei prodotti" src="PhpLib/../upload/2-Galleria/ima_galleria_03.gif" /></a> </div> <script src="PhpLib/jquery-1.2.6.min.js" type="text/javascript"> </script> <script type="text/javascript"> categories = Array(); categories[0]='2'; var numvisible_2 = 0; function changeImage(categoria){ var d = document; var aux = parseInt(eval('numvisible_'+categoria)); var array_img = eval('d.MM_'+categoria); if (array_img.length>1){ var img_index =(aux+1)%array_img.length; var div,img; eval ('div =$("#focus_'+categoria+'")'); eval ('img =$("#focus_'+categoria+' img")'); var control = "url('"+ array_img[img_index].src+"')"; $(div).css('background-image', control); $(img).animate({opacity:0.01},3000,function(){ this.src = array_img[img_index].src; $(img).animate({opacity:1},1000); }); eval ("numvisible_"+categoria+"=img_index"); } } function Init_Focus(){ var j; for (j=0; j<categories.length; j++) { var categoria = categories[j]; var array_img = eval('array_img_'+categoria); MM_preloadImages(array_img, categoria); setInterval("changeImage("+categoria+")",5000); } } function MM_preloadImages(img, categoria) { //v3.0 var d=document; eval("d.MM_"+categoria+"= new Array()"); var i,j=0; var a = img; for(i=0; i<a.length; i++) if (a[i].indexOf("#")!=0){ eval("d.MM_"+categoria+"[j]=new Image"); eval("d.MM_"+categoria+"[j++].src=a[i]"); } } Init_Focus(); </script> Hi All, I have a problem in which I try to execute a funcition via a document.write() and it throws an "object expected" error. Overall I am making an interface for MS ACCESS .mdb table via ADODB using JavaScript and I want to be able to click on a link and the id is used to delete that entry. Code: My function is: Code: function deleteRecord(del) { var adoConn = new ActiveXObject("ADODB.Connection"); var adoRS = new ActiveXObject("ADODB.Recordset"); adoConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source = {path to }knowBA.mdb'"); adoRS.Open("Select * From know where ID="+ del, adoConn, 1, 3); adoRS.Delete; adoRS.Close(); adoConn.Close(); } The code using the funcition is - oh and the numric KEY is rs(0) : Code: if(!rs.bof) { document.write("<table width='700' border='1' align='center' cellpadding='2' cellspacing='0' bgcolor='#FFFFFF'>"); rs.MoveFirst() while(!rs.eof) { document.write("<tr><td><div align='center'><strong>"+rs(1)+"</strong></div>"); document.write("<strong>Keyword(s):</strong> "+rs(3)); document.write("<br><strong>Entry:</strong> " +rs(2)+" "); document.write("<A HREF='javascript:onClick=("+"eval(deleteRecord(" +rs(0)+"))"+")'>delete</A> "); document.write("</td></tr>"); cnt=cnt+1; rs.MoveNext() } document.write("</table></form>"); } if (cnt==0){ alert ("Sorry, there are no results on that search.");} rs.close() cn.Close(); } </script> Thanks for any hints on how to accomplish this! Hey guys, as of now these lines of code... Code: function lettergrade(grade) { if (grade >= 9){ document.write("A") } else if (grade >= 8){ document.write("B") } else if (grade >= 7){ document.write("C") } else{ document.write("F | Warning, your letter grade is very low.") } }; function goletter() { document.write("Sam's letter grade on the test is: " + lettergrade(sam) + ", <br \> Sally's letter grade on the test is: " + lettergrade(sally) + ", <br \> Donald's letter grade on the test is: " + lettergrade(donald)) } ...are supposed to display the "____'s letter grade on the test is: A" or the respective letter, but instead it is displaying this... ABF | Warning, your letter grade is very low.Sam's letter grade on the test is: undefined, Sally's letter grade on the test is: undefined, Donald's letter grade on the test is: undefined Any ideas as to why this is happening? I am a novice javascript user so if there are any good alternatives that are pretty basic i'm open to ideas. Thanks guys. Code: var i = 1; var obj = document.createElement("pStretch" + i); obj.id = "pStretch" + i; obj.className='circle_point drag'; eval("pStretch" + i + ".obj = ") = obj; document.body.appendChild(obj); Red does not work. What I want is to store all regarding DOM object into a property of another object named the same as id of that DOM object. What to do to make that work ? Hello again, I've continued to study and work on JavaScript. I've had some problems with the document.write() function. When I try to do a math problem, the whole content of the page clears out and only displays the solution. For example: Code: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Untitled</title> <script type="text/javascript"> function jahava() { var h = 1 var r = 4 var t = 5 document.write(h += r += t) } </script> </head> <body> <button OnClick="jahava()">Click Me!</button> </body> </html> So If I put other content, like the button I was displaying (which I wanted to stay visible), the function would make them all disappear. I would again appreciate any help towards this matter. Sincerely, Taro B. PS; This is not a calculator related problem, just in-general. In context, the following would be applied to an admin-only menu page under the WordPress Dashboard.(e.g. not for public access) Reading MUCH of the evils of eval() however, my use of it below appears nonetheless susceptible to injection attack, and I was hoping for suggestions as to better approach, as I myself am at something of a loss. PHP Code: <!-- as many as 15 of these per page --> <select class='glry_update' id='<?php echo $prd_tbl_id; ?>'> <option value=""> **** </option> <option value="syndicate">Syndicate</option> <option value="rescind">Rescind </option> <option value="feature">Feature </option> <option value="defeature">DeFeature</option> <option value="flag">Flag</option> <option value="deflag">DeFlag</option> <option value='edit'>Edit</option> <option value="drop">Delete</option> </select> PHP Code: //jQuery update of gallery item where $('.glry_update') is a select/dropdown input $('.glry_update').change(function() { var editId = $(this).attr('id');//corrisponds to record_id# in db Ex:"110" var call = $(this).val();//selected value Ex:"flag" $('#itemId').val(editId); //sole input(hidden) in form[editItem] $('#'+editId+' option[value=""]').attr('selected', true); //reuturn 'Select' to default state if(call == 'edit') $('#editItem').submit();// return record detail page for editing if(call == 'drop') { var cnfm = 'Do your really want to delete this item'; if (confirm(cnfm)) drop(editId,'glry'); else return false; } else { var functCall= call+'('+editId+')'; // Ex: flag(110) alert(functCall);return false; // DANGER? --- DANGER! --- DANGER? --- DANGER! --- eval(functCall); // DANGER? --- DANGER! --- // DANGER? --- DANGER! --- DANGER? --- DANGER! --- } }); Hi for purpose of learning only. Stretching myself by looking at OOP in JSBible. In the book he used a frameset which I hate so I changed to innerHTML. I have two issues A) the code uses eval (highlighted)--- i'd like to not use that but I can't work out how to change it. B) how to show selected ie Earth when the page loads. I've tried loads of ways but just not getting it. here is full code working Code: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>OOP test PLANETS</title> <style type="text/css"> .highlight{ color:orange; font-weight:bold; } </style> <script type="text/javascript"> //* <![CDATA[ //define method function showPlanet(){ var result = ''; result += "Planet: <span class='highlight'>"+this.name+"</span><br />"; result += "Diameter: <span class='highlight'>"+this.diameter+"</span><br />"; result += "Distance from Sun: <span class='highlight'>"+this.distance+"</span><br />"; result += "One Orbit Around Sun: <span class='highlight'>"+this.year+"</span><br />"; result += "One Revolution (Earth Time): <span class='highlight'>"+this.day+"</span>"; var insert = document.getElementById("myinsert"); insert.innerHTML = result; } function planet(name,diameter,distance,year,day){ this.name = name; this.diameter = diameter; this.distance = distance; this.year = year; this.day = day; this.showPlanet = showPlanet; //showPlanet func now a method of planet } //create new planet objects in series of variables var Mercury = new planet("Mercury","3100 miles","36 million miles","88 days","59 days"); var Venus = new planet("Venus","7700 miles","67 million miles","225 days","244 days"); var Earth = new planet("Earth","7920 miles","93 million miles","365.25 days","24 hours"); var Mars = new planet("Mars","4200 miles","141 millon miles","687 days","24 minutes"); var Jupiter = new planet("Jupiter","88.640 miles","483 million miles","11.9 years","9 hours 50 minutes"); var Saturn = new planet("Saturn","74,500 miles","886 million miles","29.5 yeras","10 hours 39 minutes"); var Uranus = new planet("Uranus","32,000 miles","1.782 billion miles","84 years","23 hours"); var Neptune = new planet("Neptune","2.793 billion miles","165 years","15 hours","48 minutes"); var Pluto = new planet("Pluto","1500 miles","3.67 billion miles","248 years","6 days, 7 hours"); function planetInfo(which){ i = which.selectedIndex; //how to get same result without using eval eval(which.options[i].text + ".showPlanet()"); } //*/// ]]> </script> </head> <body> <h1>Daily Planet</h1> <form> <select name="planetList" id="planetList" onchange="planetInfo(this)"> <option>Mercury</option> <option>Venus</option> <option selected="selected">Earth</option> <option>Mars</option> <option>Jupiter</option> <option>Saturn</option> <option>Uranus</option> <option>Neptune</option> <option>Pluto</option> </select> </form> <div id="myinsert"> </div> </body> </html> ok tell me if I wrote this properly Code: eval('windowBody' + windowCount + '.style.backgroundColor = "black";'); I'm attempting to be able to create multiple windows on my page http://opentech.durhamcollege.ca/~in...rittains/labs/ Hi Guys, I am a novice at javascript. I possibly need an alternative to document.write to output specifically the value contained in Code: {exp:lg_ml:translate key="phrase[i]"} This syntax is cms specific and carries a value like horse or a translated version of it like Pferd in German. The below code outputs: {exp:lg_ml:translate key="cat"}{exp:lg_ml:translate key="dog"}{exp:lg_ml:translate key="horse"} but I want it to output in the source code of my template so it can execute correctly with predetermined values and not just on screen as the syntax instead of the actual value it holds, if you know what I mean. Anyway after hours of trying and 5 cups of cheap Nescafe coffee I need to achieve exactly the below with an alternative possibly to document.write? I also need to keep the loop. Thanks Code: <html> <body> <script type="text/javascript"> var i; var phrase = new Array(); phrase[0] = "cat"; phrase[1] = "dog"; phrase[2] = "horse"; for (i=0;i<phrase.length;i++) { document.write("{exp:lg_ml:translate key=\""+phrase[i] +"\"}"); } </script> </body> </html> Code: <HTML> <HEAD> <TITLE>John's JavaScript!</TITLE> <SCRIPT TYPE="text/javascript"> function solve(math) { form.answer.value = eval(math); } </SCRIPT> </HEAD> <BODY> <FORM METHOD="POST"> Enter a JavaScript mathematical expression: <INPUT TYPE="text" NAME="entry" VALUE="" /> <BR /> The result of this expression is: <INPUT TYPE="text" NAME="answer" VALUE="" onFocus="blur()"/> <INPUT TYPE="button" NAME="submit" onClick="solve(form.entry.value)"/> </BODY> </HTML> The only problem I am facing is changing form.answer.value It won't change, why not? Hi there, I'm working with leaflet.js to create a web map which is working well so far however I've run into a rookie js problem. I have a js fiddle which shows my code here. The problem I have is that I need convert a string like "polygon" to polygon without the quotation marks. According to the Leaflet API, removeLayer takes an iLayer parameter eg removeLayer( <ILayer> layer ). Currently I'm passing it a string which I feed through eval, I gather is less than ideal. There is a post here on stack overflow but I can't make any sense of the answer unfortunately. If anyone can provide any advice it would be greatly appreciated. Thanks, Rowan Reply With Quote 01-07-2015, 12:50 PM #2 rnd me View Profile View Forum Posts Visit Homepage Senior Coder Join Date Jun 2007 Location Urbana Posts 4,497 Thanks 11 Thanked 603 Times in 583 Posts if you add Code: window.circle=circle; window.marker=marker; window.polygon=polygon; then you can use syntax like layerClicked = window[event.target.value]; instead of eval. you can use a different object than window, as long as it's global and consistent. Hi there! I set up a variable that should replace HTML code when run but it doesn't seem to be doing that... Here it is: Code: var finale = "document.getElementById(" + theid + ").innerHTML='test';"; eval("finale"); Any idea why? (My console isn't showing any issues) Thanks! Matt in IE9 Browser list of country names sorting on keys. we are using Ajax javascript: Code: var data= remoteRequest(url); the data like Code: data={" 11":"Australia"," 14":"Bermuda"," CAN":"Canada"," 12":"France"," 15":"Germany"," IND":"India"," 16":"Russia"," 13":"South Africa"," 10":"UK"," USA":"United States"} name_set= eval('('+data+')'); it fine in all browser the array like Code: name_set[11]=Australia name_set[14]=Bermuda name_set[CAN]=Canada name_set[12]=France name_set[15]=Germany name_set[IND]=India name_set[16]=Russia name_set[13]=South Africa name_set[10]=UK name_set[USA]=United States but in the IE9 browser array keys sorting as like. Code: name_set[10]=UK name_set[11]=Australia name_set[12]=France name_set[13]=South Africa name_set[14]=Bermuda name_set[15]=Germany name_set[16]=Russia name_set[CAN]=Canada name_set[IND]=India name_set[USA]=United States so please help me, how to stop the array sorting in IE9. thanks in Advance, Venu Dear all, I'm new with JavaScript, so can please help me with this macro? I need to reload URL (in this case refresh same page) until I don't have word beginning with capitalized A, B or C. I can't find the way to create loop inside EVAL. Can somebody help me please? Thank you! Code: VERSION BUILD=7401110 RECORDER=FX TAB T=1 URL GOTO=http://watchout4snakes.com/CreativityTools/RandomWord/RandomWord.aspx SET !EXTRACT_TEST_POPUP NO TAG POS=1 TYPE=SPAN ATTR=ID:tmpl_main_lblWord EXTRACT=TXT SET !VAR1 EVAL("var re = /^[A || B || C]/gi; var str = \"{{!EXTRACT}}\"; while(str.search(re) == -1) {URL GOTO=http://watchout4snakes.com/CreativityTools/RandomWord/RandomWord.aspx}") PROMPT {{!EXTRACT}} As it is, I'm using Walter Zorn's JS Graphics Library in an attempt to write a small screensaver-type-thing for jailbroken iPhones/iPod touches. However, on my mom's AMD Athlon 64 3000+, the drawing gets pretty laggy, so you can imagine how utterly choppy it is on my iPod. The look I'm going for is the Windows XP Mystify screen saver, with corners bouncing around the screen. So, my first question is this: are there any alternatives for this sort of thing, short of manually generating a video, gif, or multiple images to switch through, or is there any way to make my code more efficient for the CPU? (Code below) NOTE: I know I could make it look a lot nicer by making a 'corner' class, and having each corner be an object (and even nicer by using an array of 'corners'). But I'm not sure that would help the CPU's calculations much, and make the code more efficient as a whole. Code: <div id="Mystify"> <script type="text/javascript"> var mystifyCanvas = new jsGraphics("Mystify"); var tetraCorner1x = Math.floor(Math.random()*300) + 5; var tetraCorner1y = Math.floor(Math.random()*460) + 5; var tetraCorner2x = Math.floor(Math.random()*300) + 5; var tetraCorner2y = Math.floor(Math.random()*460) + 5; var tetraCorner3x = Math.floor(Math.random()*300) + 5; var tetraCorner3y = Math.floor(Math.random()*460) + 5; var tetraCorner4x = Math.floor(Math.random()*300) + 5; var tetraCorner4y = Math.floor(Math.random()*460) + 5; go1x = true; go1y = false; go2x = true; go2y = true; go3x = false; go3y = true; go4x = false; go4y = false; function MystifyJavaScript() { mystifyCanvas.clear(); mystifyCanvas.setColor("#ff0000"); mystifyCanvas.setStroke(2); if (go1x) { tetraCorner1x++; if (tetraCorner1x > 315) { go1x = false } } else { tetraCorner1x--; if (tetraCorner1x < 5) { go1x = true } } if (go1y) { tetraCorner1y++; if (tetraCorner1y > 475) { go1y = false } } else { tetraCorner1y--; if (tetraCorner1y < 5) { go1y = true } } if (go2x) { tetraCorner2x++; if (tetraCorner2x > 315) { go2x = false } } else { tetraCorner2x--; if (tetraCorner2x < 5) { go2x = true } } if (go2y) { tetraCorner2y++; if (tetraCorner2y > 475) { go2y = false } } else { tetraCorner2y--; if (tetraCorner2y < 5) { go2y = true } } if (go3x) { tetraCorner3x++; if (tetraCorner3x > 315) { go3x = false } } else { tetraCorner3x--; if (tetraCorner3x < 5) { go3x = true } } if (go3y) { tetraCorner3y++; if (tetraCorner3y > 475) { go3y = false } } else { tetraCorner3y--; if (tetraCorner3y < 5) { go3y = true } } if (go4x) { tetraCorner4x++; if (tetraCorner4x > 315) { go4x = false } } else { tetraCorner4x--; if (tetraCorner4x < 5) { go4x = true } } if (go4y) { tetraCorner4y++; if (tetraCorner4y > 475) { go4y = false } } else { tetraCorner4y--; if (tetraCorner4y < 5) { go4y = true } } mystifyCanvas.drawLine(tetraCorner1x, tetraCorner1y, tetraCorner2x, tetraCorner2y); mystifyCanvas.drawLine(tetraCorner2x, tetraCorner2y, tetraCorner3x, tetraCorner3y); mystifyCanvas.drawLine(tetraCorner3x, tetraCorner3y, tetraCorner4x, tetraCorner4y); mystifyCanvas.drawLine(tetraCorner4x, tetraCorner4y, tetraCorner1x, tetraCorner1y); mystifyCanvas.paint(); window.setTimeout("MystifyJavaScript()", 10); } MystifyJavaScript(); </script> </div> Please keep in mind, there's a LOT of repeat code, so you only have to read any one part once. To test/see/use the code, you'll need to download wz_graphics.zip. Then download the attached txt file to the same directory as the unzipped wz_graphics, change it to .html instead of .txt, and open it. Hi all, I have a website that allows users to enter complex mathematical formulas into a text field and evaluates them. I am currently using eval() because it not only can handle all the standard mathematical functions, but also gives them access to the Math object. That way the users can use functions such as Math.max() and everything else. I realize, though, that using eval is evil, I assume because a malicious user might throw in some more damaging javascript that would be run without checking it. (That's why eval is evil, right?) Is there a way that I can allow my users to construct complex mathematical formulas and use the Math object (or an equivalent) without potentially opening my site up to harm? Hi folks, Any suggestions on how you might achieve the following without using eval()? I've come up a bit short Code: function addOrSubtract(operator) { var a = 10; var b = 5; var answer = eval(a + operator + b); alert(answer); } addOrSubtract('+') // alerts 15 addOrSubtract('-') // alerts 5 Would help me tidy up some code a lot thanks. An application under development has a set of core functions that carry out common tasks and a 'machine' that animates panels of lists of names and menus and provides another panel for action calls. (see attached pic). Selection of a name identifies object(s) to be worked on and menu couplets like "Name+Edit" call devices (each in a separate js file). Each js file replaces any files in the deviceScript holder in the hta file. I used to use eval(couplet+"Start")() to initiate the device, but having read about the evils of eval it dawned on me that it was unnecessary and just gave each device a start() function ... and also an optional refresh(), and compulsory finish() to pick up results and clean up. This seems to work well on my machine. The hta is intended to run locally picking up json type data and devices locally and via the net and I am concerned that importing js files is just as evil, but isn't it just like opening a web page? Any guidance really appreciated. Chris |