Yawp 1.0.5 Released

Yawp is a single PEAR-compliant class that encapsulates a number of other PEAR classes, and ties them all together with a simple configuration file. This release provides a minor functionality improvement.

Previously, when a hook script was called, it would be included directly in the calling code (e.g., a ‘start’ hook would be include()-ed in the middle of the Yawp::start() method; same for login, logout, and authErr hooks). This means it would be possible for the included script to use (and possibly overwrite) variables in the calling Yawp method; while not a security violation, that kind of thing could lead to unexpected behavior, and requires a much closer knowledge of the Yawp internals than should be necessary.

To solve this problem, I have added a method called run() — all it does is include a file. It doesn’t even need a parameter (using one would create a new variable in the scope of the function, and we want *everything* isolated for the included script).

function run() { include func_get_arg(0); }

This has the benefit of executing a script in its own scope, so that the hook script cannot accidentally overwrite variables in the calling Yawp method. All hooks now use the Yawp::run() method instead of include().

Restrictive (“Secure”) Compiler for Savant

This page is to track issues related to the new “secure” compiler for Savant. A number of people (notably and most recently RevJim) have opined that Savant needs a decent secure compiler so that untrusted users can be allowed to edit templates. I agree.

Note: The compiler is not a required element. The normal use of Savant remains; that is, PHP itself is the template markup. The only time you really need to compile a template is when you have anonymous or otherwise possibly mailicious users, and this compiler exists to support that relatively rare case.

So the idea now is to replace the existing “basic” compiler with a more-secure version; you can view the source code here. Note that it depends on Josh Eichorn’s excellent PHPCodeAnalyzer script, which itself depends on the tokenizer function in PHP 4.3.0 and later.

I don’t know if I like calling the new compiler “secure” or not, but it sure is restrictive. Here are the built-in restrictions and features:

  • The markup language is PHP in most cases, just surrounded in non-PHP tags
  • Prefix and suffix tags default to “{” and “}”, but are user-definable.
  • No <?php … ?> or <? … ?> tags allowed
  • Simple variable echoing via {$var}
  • Comments via {* … *}
  • Control structures are regular PHP ( {if (…):}, {else}, {foreach (…):}, etc)
  • No support for switch/case, but break and continue are allowed
  • Plugins supported via {[‘pluginName’, ‘arg1’, $arg2, … ]}
  • Certain language constructs are disallowed: eval, global, include[_once], require[_once], parent, self
  • The only way to include other templates is via the {tpl} tag
  • If the Savant $_restrict flag is on, template requests are restricted to specific allowed paths
  • Access to superglobals ($GLOBALS, $_GET, etc) is disallowed
  • Access to private $this properties is disallowed
  • Variable-variables and variable-functions are disallowed
  • Only whitelisted functions are allowed (the whitelist is user-definable)
  • Only whitelisted static method calls are allowed (the whitelist is user-definable)
  • Use of $this by itself is disallowed; it must be followed by -> (e.g., “$this” generates an error, but “$this_thing” and “$this->property” are allowed)

I think that’s it. If the compile generates errors, the compiled script is not saved and the compiler returns a list of restriction violations with line numbers (the number correspond to both the source template and the compiled template becuase the markup language is very close to native PHP).

Comments? Questions? Have I forgotten to take something into account? It’s only been a week, so I am sure to have missed some form of sneakiness.

Savant Article in PHP-Mag

My article on Savant has been published in the 01.2005 edition of International PHP Magazine. I subtitled it “How I learned to stop using Smarty and love PHP for template markup” (so what if I love old movies?).

In the Development track, Paul Jones elaborates on how he learned to stop using Smarty and love PHP for template markup. He holds forth on Savant, a lightweight, object-oriented, fast and powerful solution that leverages the power of PHP markup with the convenience of plugins and path management รขโ‚ฌโ€œ all without compiling.

Toward a Secure Compiler for Savant

Savant uses PHP for its template markup, but also supports extneral compilers. Unfortunately, the example compiler in the distro is not that secure.

But! Joshua Eichorn has put together a spiffy PHP code analysis tool called PHPCodeAnalyzer. It takes PHP code, runs the PHP tokenizer on it, and reports back what functions, methods, etc. are present in the code. This could serve as a basis for a secure compiler for Savant, which in turn might be the tipping point for RevJim.

(Reverend, if you’re reading, I’d be very happy to hear your comments on this).

Code Tests As Code Tutorials

Early in the development of Savant (back when it was HTML_Template_Dummy) I broke the assign() method without knowing it, then distributed the source to early adopter testers. Of course, they discovered the break right away. Embarrassed, I wrote up a quick series of “visual” test scripts to run on each release. They are not automated; basically, they instantiate Savant and print out the results of various method calls, which I then eyeball to look for problems. While not optimal, and certianly not “best practice,” it’s good enough most of the time.

However, such “eyeball” tests seem to have an unexpected benefit. I just got a comment from Alex at Sourcelibre saying:

In version 2.3.2, the directory … Savant2/tests are really usefull. I almost always prefer examples to explanations, and these examples are just perfect.

Well look at that. I wrote up code examples and I didn’t even know it. While it’s not documentation per se, it appears to add a lot of value to the package.

So now there’s at least one more reason to write non-automated tests for your libraries: if the tests are designed to be human readable, not machine readable, then they can serve the purpose of testing **and** tutorial.

Savant 2.3.2 released

Savant sees a new release today, version 2.3.2. It’s a bugfix release; the change notes are:

* can now use assign() to assign a null value by name (thanks, Michael Caplan)

* the dateformat plugin now correctly refers to named custom formats (thanks, maxim at inform-link dot co dot uk)

* added tests for named custom dateformat strings

In related news, it seems that Monte Ohrt (or someone using his name) of Smarty fame wanted to take issue with some of my comments about caching over at the house of Reverend Jim. Give Jim some traffic and see for yourself which point of view you agree with; when you’re done, be sure to check out his photography work.

Finally, the Savant site has seen quadruple its normal traffic in the past 24 hours. Normally it gets about 1000 hits/day, but right now it’s at 4000. Could it be that my new article for PHP Magazine on Savant has been released?

Savant is a template system for PHP that uses PHP itself as the template markup language. Savant has plugins, output filters, customized error handling, and allows you to hook in a compiler object to deal with customized non-PHP template markup. I call it the simple, elegant, and powerful alternative to Smarty.

Update: Looks like SitePoint Tech Times has a link to Savant, which explains the traffic increase. Thanks to Sean from #pear on IRC for the information, and thanks to the SitePoint folks for mentioning the project.

Update 2: At midnight: 6763 hits in 24 hours. Sweet. ๐Ÿ™‚