BBCode in symfony

March 15, 2007

I’m currently working on a site that requires bbcode but most implementations available on the net use either the preg_replace or the str_replace function to replace bbcode with their corresponding html-tags (for exampe ‘[b]’ to ‘<b>’)

$text = preg_replace ('/[b](.*)[/b]/Us', '<strong>\1</strong>', $text); 

$text = str_replace("[b]", "<strong>", $text );
$text = str_replace("[/b]", "</strong>", $text );

Using str_replace is crap because it cannot ensure that each tag is closed properly while the preg_replace function is slightly better but it cannot ensure the correct nesting of elements.

Sure, with a bit hacking this shouldn’t be a problem, but i wanted a class that integrates nicely in symfony. It should parse the complete text character by character and build a tree structure out of it for correct nesting, have the most used bbcodes predefined and must not be vulnerable to any XSS-attacks.

I found the sfBBCodeParserPlugin in the symfony-wiki and tried to install it with the symfony plugin-install command, unfortunately this didn’t work. After a little research it turned out that this package is outdated and the package.xml requires a symfony version between 0.8.0 and 0.9.999.
After downloading & unpacking the tarball, modifying the package.xml and creating a new pear package, the installation went fine. (Maybe –force would be a better idea)

The first thing i noticed was that the plugin saves the bbcode in the database, which actually isn’t that good because i hardly change bbcode and storing it in the database is one of the slowest solutions (especially with propel as the orm).
After playing around a bit, i had modified the plugin to parse the bbcode from a cached yaml-file, which results in much better performance!
But there were two more things that were bugging me: The first one was that variables got passed without validation, which makes the website vulnerable to XSS-attacks.
For example the [url]-tag:

<a href="${attr}">${content}</a>

Here, both ${attr} and ${content} are getting passed without any validation.
Fixing this would require some time, because i noticed that the [color]-tag also uses the ${attr} variable:

<span style="color:${attr};">${content}</span>

In order to fix this, it would require to make a list with allowed colors.
Also when using htmlspecialchars or html_entities to espace the values, tags like [url] shouldn’t be escaped because they contain a url:

[url=”https://symfoniac.wordpress.com”%5DSymfoniac blog[/url]

Finally, here’s a little to-do list for the plugin:

  • Replace the datebase-backend by a yaml one
  • Escape the passed values (but not all!)
  • For the [color]-tag, make a list with allowed colors
  • Maybe [img]-tag could use the alt-attribute (based on the filename, like symfony does it)

If i find some time, i’ll work on it.
Till then i would recommend using a modified version of the PEAR HTML_BBCodeParser class which can be found in this bug report (No errors/warnings, faster than the original HTML_BBCodeParser and even has Unit tests) – this class is just awesome! Or you can use the StringParser_BBCode class (which is very configurable but throws a Strict Standards error when parsing the text (using PHP 5.2)).

Advertisements

2 Responses to “BBCode in symfony”

  1. Sebastian Says:

    No need to get the modified version of HTML_BBCodeParser, according to the bug comments this all has been fixed in the new release 1.2.2 (2007-07-02):

    http://pear.php.net/package/HTML_BBCodeParser/download/

  2. Alex Says:

    Hi I’m sitting at the same problem at moment. For i project I had to implement BBCode parsing in Symfony after 2 hours playing around I discovered this plugin:

    http://trac.symfony-project.org/wiki/sfPayloadFilterChain_TextTransformationPlugin

    which uses the HTML_BBCodeParser plugin to modifie BBCode. Once it runs its easy to use with helpers filters aso….


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: