Roxen.git / server / modules / scripting / piketag.pike

version» Context lines:

Roxen.git/server/modules/scripting/piketag.pike:1: - // This is a roxen module. Copyright © 1996 - 2000, Roxen IS. + // This is a roxen module. Copyright © 1996 - 2009, Roxen IS.   //   // Adds support for inline pike in documents.   //   // Example:   // <pike>   // return "Hello world!\n";   // </pike>    - constant cvs_version = "$Id: piketag.pike,v 2.31 2001/03/08 14:35:44 per Exp $"; + constant cvs_version = "$Id$";   constant thread_safe=1;      inherit "module";   #include <module.h>      constant module_type = MODULE_TAG;   constant module_name = "Scripting: Pike tag";   constant module_doc = #"   <p>This module adds a processing instruction tag, <code>&lt;?pike ...   ?&gt;</code>, for evaluating Pike code directly in the document.</p>
Roxen.git/server/modules/scripting/piketag.pike:183:    flat[i]->text=flat[i]->trailing_whitespaces=""; \    } \    else \    { \    X = flat[i]; \    flat[i]->text = flat[i]->text[3..]+"\n"; \    }      #define R(X) Parser.Pike.reconstitute_with_line_numbers(X)    - array helpers() + array helpers(function add_constant)   {    add_constant( "__ps_magic_helpers", Helpers );    add_constant( "__ps_magic_protos", HProtos );    return SPLIT("inherit __ps_magic_helpers;\nimport Roxen;\n",PREFN);   }      array helper_prototypes( )   {    return SPLIT("inherit __ps_magic_protos;\nimport Roxen;\n",PREFN);   }    - private static mapping(string:program) program_cache = ([]); + private mapping(string:program) program_cache = ([]);      string simple_pi_tag_pike( string tag, mapping m, string s,RequestID id )   {    program p;    object o;    string res;    mixed err;       id->misc->__added_helpers_in_tree=0;    id->misc->cacheable=0;       object e = ErrorContainer(); -  master()->set_inhibit_compile_errors(e); +     if(err=catch    { -  p = my_compile_string( s,id,1,"pike-tag("+id->not_query+")" ); +  p = my_compile_string( s,id,1,"pike-tag("+id->not_query+")",e );    if (sizeof(program_cache) > query("program_cache_limit"))    {    array a = indices(program_cache);    int i;       // Zap somewhere between 25 & 50% of the cache.    for(i = query("program_cache_limit")/2; i > 0; i--)    m_delete(program_cache, a[random(sizeof(a))]);    }    })    {    master()->set_inhibit_compile_errors(0); -  if (e->get()) -  RXML.parse_error ("Error compiling Pike code:\n%s", e->get()); +  if (e->get() && strlen(e->get())) +  RXML.parse_error ("Error while compiling Pike code:\n%s", e->get());    else throw (err);    }    master()->set_inhibit_compile_errors(0);       if(err = catch{    (o=p())->parse(id);    }) {    catch {    err = ({err[0], err[1][sizeof (backtrace())..]});    err[1][0] = ({"top level", err[1][0][1]});
Roxen.git/server/modules/scripting/piketag.pike:255:    return res;   }      string read_roxen_file( string what, object id )   {    // let there be magic    return id->conf->open_file(Roxen.fix_relative(what,id),"rR",id,1)    ->read()[0];   }    - program my_compile_string(string s, object id, int dom, string fn) + program my_compile_string(string s, object id, int dom, string fn, +  ErrorContainer e)   {    if( program_cache[ s ] )    return program_cache[ s ];    -  object key = Roxen.add_scope_constants(); -  [array ip, array data] = parse_magic(s,id,dom,fn); +  object compile_handler = class( ErrorContainer e ) +  { +  mapping constants = all_constants()+([]); +  void add_constant( string x, mixed v ) +  { +  constants[x] = v; +  } +  mapping(string:mixed) get_default_module() +  { +  return constants; +  } +  mixed resolv(string id, void|string fn, void|string ch) +  { +  return constants[id] || master()->resolv( id, fn, ch ); +  } +  void compile_error(string a, int b, string c) { +  e->compile_error( a, b, c ); +  } +  void compile_warning(string a, int b, string c) { +  e->compile_warning( a, b, c ); +  } +  }(e);    -  +  object key = Roxen.add_scope_constants( 0, compile_handler->add_constant ); +  [array ip, array data] = parse_magic(s,id,dom,fn,e); +     int cnt;       array pre;    if( !id->misc->__added_helpers_in_tree && !sizeof(ip))    {    id->misc->__added_helpers_in_tree=1; -  pre = helpers(); +  pre = helpers(compile_handler->add_constant);    }    else -  +  { +  helpers(compile_handler->add_constant);    pre = helper_prototypes(); -  +  }       foreach( ip, program ipc )    { -  add_constant( "____ih_"+cnt, ipc ); +  compile_handler->add_constant( "____ih_"+cnt, ipc );    pre += SPLIT("inherit ____ih_"+cnt++ + ";\n",PREFN);    }       if (dom)    pre += SPLIT("void parse(RequestID id)\n{\n",PREFN) +    data + SPLIT("}",POSTFN);    else    pre += data; -  program p = compile_string(R(pre), fn); +  program p = compile_string( R(pre), fn, compile_handler );    if (query ("program_cache_limit") > 0)    program_cache[ s ] = p;       cnt=0; -  foreach( ip, program ipc ) add_constant( "____ih_"+cnt++, 0 ); -  destruct( key ); +     return p;   }    - program handle_inherit( string what, RequestID id ) + program handle_inherit( string what, RequestID id, ErrorContainer e )   { -  array err; +     // ouch ouch ouch. -  return my_compile_string( read_roxen_file( what, id ),id,0,what); +  return my_compile_string( read_roxen_file( what, id ),id,0,what,e);   }    - array parse_magic( string data, RequestID id, int add_md, string filename ) + array parse_magic( string data, RequestID id, int add_md, string filename, +  ErrorContainer e )   {    array flat=SPLIT(data,filename);    object cip, cipup;    array inherits = ({});    for( int i = 0; i<sizeof( flat ); i++ )    {    switch( strlen(flat[i]->text) && flat[i]->text[0] )    {    case '.':    OCIP(); OCIPUP();    if( flat[i] == "." )    {    flat[i]->text = "[";    flat[i+1]->text = "\"" + flat[++i]->text + "\"]";    }    break;       case '/': -  if( flat[i]->text[2..2] == "X" ) +  if( strlen(flat[i]->text)>2 && +  (flat[i]->text[1]=='/' || flat[i]->text[1]=='*') )    { -  +  if( flat[i]->text[2] == 'X' ) +  {    if (flat[i]->text[1] == '*')    flat[i]->text = flat[i]->text[..sizeof (flat[i]->text) - 3];    OCIPUP();    CIP( cip );    } -  else if( flat[i]->text[2..2] == "O" ) +  else if( flat[i]->text[2] == 'O' )    {    if (flat[i]->text[1] == '*')    flat[i]->text = flat[i]->text[..sizeof (flat[i]->text) - 3];    OCIP();    CIP( cipup );    }    else    {    OCIPUP();    OCIP();    } -  +  } +  else +  { +  OCIPUP(); +  OCIP(); +  }    break;       case '#':    OCIP(); OCIPUP();    if( sscanf( flat[i]->text, "#%*[ \t]inherit%[ \t]%s",    string ws, string fn) == 3 && sizeof (ws))    { -  inherits += ({ handle_inherit( PS(fn), id ) }); +  flat[i]->text=""; +  inherits += ({ handle_inherit( PS(fn), id, e ) });    }    else if( sscanf( flat[i]->text, "#%*[ \t]include%[ \t]%s",    string ws, string fn) == 3 && sizeof (ws))    {    sscanf( fn, "%*s<%s>", fn );    sscanf( fn, "%*s\"%s\"", fn ); -  [array ih,flat[i]] = parse_magic(read_roxen_file(fn,id), id, 0, fn); +  [array ih,flat[i]] = parse_magic(read_roxen_file(fn,id), id, 0, fn,e);    inherits += ih;    }    break;       default:    OCIP();    OCIPUP();    }    }    OCIP();
Roxen.git/server/modules/scripting/piketag.pike:441:    return ";}";    else    return "}";   }      // Compile and run the contents of the tag (in s) as a pike   // program.   string container_pike(string tag, mapping m, string s, RequestID request_id,    object file, mapping defs)   { +  // COMPATIBILITY CODE, DO NOT CHANGE SEMANTICS +     program p;    object o;    string res;    mixed err;       request_id->misc->cacheable=0;       object e = ErrorContainer();    master()->set_inhibit_compile_errors(e);    if(err=catch
Roxen.git/server/modules/scripting/piketag.pike:475:    // Zap somewhere between 25 & 50% of the cache.    for(i = query("program_cache_limit")/2; i > 0; i--)    m_delete(program_cache, a[random(sizeof(a))]);    }    if (query ("program_cache_limit") > 0)    program_cache[s] = p;    }    })    {    master()->set_inhibit_compile_errors(0); -  if (e->get()) +  if (e->get() && strlen(e->get()))    { -  RXML.parse_error ("Error compiling Pike code:\n%s", e->get()); +  RXML.parse_error ("Error while compiling Pike code:\n%s", +  Roxen.html_encode_string( e->get()) );    }    else    throw (err);    }    master()->set_inhibit_compile_errors(0);       if(err = catch{    res = (o=p())->parse(request_id, defs, file, m);    })    RXML.run_error ("Error in Pike code: %s\n", describe_error (err));
Roxen.git/server/modules/scripting/piketag.pike:502:    destruct(o);       return res;   }      // --------------------- Documentation -----------------------      TAGDOCUMENTATION;   #ifdef manual   constant tagdoc=([ - "?pike":#"<desc pi='pi'><p><short hide='hide'> + "?pike":#"<desc type='pi'><p><short hide='hide'>    Pike processing instruction tag.</short>This processing intruction    tag allows for evaluating Pike code directly in the document.</p>       <p>Note: With this tag, users are able to run programs with the same    right as the server. This is a serious security hasard.</p>       <p>When the pike tag returns, the contents of the output buffer is    inserted into the page. It is not reparsed with the RXML parser.</p>       <p>Use entities within the Pike code, scope.variable is handled like
Roxen.git/server/modules/scripting/piketag.pike:564: Inside #if defined(manual)
     <attr name='#include \"...\"'><p>    An #include preprocessor directive includes the specified file.</p>   </attr>      <attr name='#inherit \"...\"'><p>    An #inherit preprocessor directive puts a corresponding inherit    declaration in the class that's generated to contain the Pike code in    the tag, i.e. it inherits a specified file from the Roxen filesystem.</p>    -  <ex type='box'> -  -  <?pike -  +  <ex-box><?pike    //O <pre>    int first = 1;    for( var.counter=100; var.counter>1; var.counter--,first=0 )    {    if( !first )    {    //X &var.counter; bottles of beer on the wall    //O    }    //X &var.counter; bottles of beer on the wall    //X &var.counter; bottles of beer    //O take one down, pass it around    }    //O one bottle of beer on the wall    //O one bottle of beer    //O take it down, pass it around    //O no bottles of beer on the wall    //O </pre> -  -  ?> -  </ex> + ?></ex-box>   </attr>",       ]);   #endif