Jump to content
MakeWebGames

Alan

Members
  • Posts

    138
  • Joined

  • Last visited

  • Days Won

    12

Everything posted by Alan

  1. Might I also suggest a serious look at not only the overall T&C's but also certain key boards rules. While certain staff members may have had a good idea in introducing rules for how to post - for example in the help wanted section - those rules are useless and simply prevent some of us from posting. The boards concepts of post ownership is also highly suspect which is certainly one reason I seldom post anything these days of merit - and prefer to link to offsite resources which I can control as and when I see fit.
  2. If you consider the different forms of string handling within PHP, it should become pretty apparent that each serves a specific purpose; I'm a fan of using heredoc if I'm forced to use raw SQL queries rather than simple calls to stored-procedures as it makes copying and pasting the query into (for example) MySQL-Workbench very easy. There is also a strong case for using heredoc when outputting a mix of HTML and JavaScript however, I veer towards template solutions wherever possible saving me from this otherwise onerous task. Consider the following: $href = "#"; echo <<<CODE <div id="dummy" data-value="one"> <script type="text/javascript"> $(function(){ $("a[href='$href']").css({cursor:"default"}); }); </script> </div> CODE; vs $href = "#"; echo "<div id=\"dummy\" data-value=\"one\">"; echo "<script type=\"text/javascript\">"; echo "\$(function(){"; echo "\$(\"a[href='{$href}']\").css({cursor:\"default\"});"; echo "});"; echo "</script>"; echo "</div>"; Ask yourself which is easier to read, and in 6-weeks, 6-months, or 6-years time easier to maintain?
  3. Because " is not a valid delimiter i this context.echo <<<EOF <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> <p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> EOF; call_arbitrary_functions(); echo <<<EOF <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p> <p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> EOF; Would be the obvious solution after reading the heredoc reference in detail.
  4. Using explode() it extract the tokens is fine up to a point, but it's very restrictive. Most computer languages have some form of lexical analysis often created using 3rd party tools to define the token structure and output code. (lex, flex etc). The key here is to create something that is highly extendable, and can itself be used elsewhere. A long time when I initially wrote this type of eval() system, in part after watching one enterprising member from these very boards inject a project's crime table with something that essentially wiped the entire database (both the project and the member in question will remain nameless), I realized it could also be used to create a requirements system where the statement become highly complex - almost like a language in itself. I still use this system in the occasional PHP project today, so it's well worth the time and effort. @rockwood: no.
  5. Variables are symbols, which a basic lexer like the one I presented returns. One task of the parser is to lookup the symbols in some form of table - not database table, just an array will suffice, so you could start with something akin to: $symtab = new SymbolTable(); $symtab->defineConstant('PI', 3.14); // more constant definitions here... $symtab->defineFunction('sin', 'my_sin'); // sin, calls my_sin() function (see below) $symtab->defineFunction('log', 'log10'); // log, calls the builtin log10 function $symtab->defineFunction('floor'); // floor, calls the builtin floor function // more function definitions here $symtab->defineVariable('level', $ir['level']); // assuming the usual mccodes variable naming convention $symtab->defineVariable('will', $ir['will']); $symtab->defineVariable('exp', $ir['exp']); // more variables from the user's array here $parser = new Parse($symtab); $result = $parser->evaluate('5*WILL/EXP+6-LEVEL'); If you are wondering, my_sin() would perhaps be defined as: function my_sin( $degrees ) { return sin(deg2rad($degrees)); } It soons becomes pretty apparent, that you are really creating a whitelist expression evaluation, something that is pretty much bullet-proof. The symbol table itself can be very easy, an associative array containing the symbol, the type of symbol (constant, function or variable) and the value (or in the case of function, the name of the function). The parser of course is more fun to write, but is not difficult if you start small. There are some interesting problems to solve in the parser, operator precedence, and possibly conversion from infix to postfix, but both are very well covered at your local corner Google, and in fact I've already touched on a solution which does not require conversion to postfix, saving one possibly vital step.
  6. The question is not whether evel() itself is safe, it's more a case of the data you pass to it. How does that data get there? Is it stored in the database? Can it be manipulated by players and/or staff. If your project is vulnerable, then it's not a wise function to use. So this itself suggests an initial action - secure your project first before considering looking at alternatives to eval(). Assuming you have got a secure product - and no, this does not (to the best of my knowledge) include any out-of-the-box installs of GRPG, NWE, McCodes or ezRPG, then you have to look at what you want to evaluate. Arbitrary code? Use eval() and hope that no update to your code allows any form of rogue data to get evaluated. If however you want to evaluate simple mathematical statements ie 1 + 2 * 3 / PI + sin(5.1) - then there is a pretty decent case for writing your own system. How you choose to write it is dependent upon your level of skill, and whether you can be bothered to do it the proper way or take shortcuts. Personally, I'm in favor of a mix of the two - I skip certain error checking, but then as I'm the one using it on my product.. only a careless mistake would have knock on effects, and I test ... lots. Initially, you need to take the expression and split it into tokens - just like PHP itself does. ie: 1 + 2 * 3 / PI + sin(5.1) might become TOKEN_INTEGER(1) TOKEN_PLUS TOKEN_INTEGER(2) TOKEN_MULTIPLY TOKEN_INTEGER(3) TOKEN_DIVIDE TOKEN_CONSTANT(PI) TOKEN_PLUS TOKEN_SYMBOL(sin) TOKEN_OPEN_BRACKET TOKEN_FLOAT(5.1) TOKEN_CLOSE_BRACKET Once you have this - the lexer stage - then you need the parser stage; and this is usually where the fun begins. There are many different ways of doing it - from the simple to the insanely complex. A simple method is to use two stacks, one for operators, one for values and push items onto the relevant stack one at a time, checking at each stage if you can reduce the stack. For example: push to value stack TOKEN_INTEGER(1) push to operator stack TOKEN_PLUS push to value stack TOKEN_INTEGER(2) push to operator stack TOKEN_MULTIPLY push to value stack TOKEN_INTEGER(3) at this stage we can multiple 2 x 3 to get 6, leaving 1 and 6 on the value stack and + on the operator stack push to operator stack TOKEN_DIVIDE push to value stack 3.141... again, we can now reduce the stacks by dividing 6 by 3.141 to get 1.19, leaving 1 and 1.9 on the value stack and + on the operator stack. etc etc. You can try a very simple lexer out for yourself -- http://node86.com/pastebin/vmjjm/ (Please note the link will only be available for a short time).
×
×
  • Create New...