jBBCode
jBBCode copied to clipboard
Tags with setOptionValidator do not run uppercase tags through the validator.
Steps to reproduce:
- Have these code definitions set in
DefaultCodeDefinitionSet.php:
// [color] color tag
$builder = new CodeDefinitionBuilder('color', '<span style="color:{option}">{param}</span>');
$builder->setUseOption(TRUE)->setOptionValidator(new \JBBCode\validators\CssColorValidator());
array_push($this->definitions, $builder->build());
// [size=3] font size tag
$builder = new CodeDefinitionBuilder('size', '<font size="{option}">{param}</font>');
$builder->setUseOption(TRUE)->setParseContent(TRUE)->setOptionValidator(new \JBBCode\validators\FontSizeValidator());
array_push($this->definitions, $builder->build());
- Have these validators:
CssColorValidator.php
<?php
namespace JBBCode\validators;
require_once dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'InputValidator.php';
/**
* An InputValidator for CSS color values. This is a very rudimentary
* validator. It will allow a lot of color values that are invalid. However,
* it shouldn't allow any invalid color values that are also a security
* concern.
*
* @author jbowens
* @since May 2013
*/
class CssColorValidator implements \JBBCode\InputValidator
{
/**
* Returns true if $input uses only valid CSS color value
* characters.
*
* @param $input the string to validate
*/
public function validate($input) {
return (bool) preg_match('/^[A-z0-9\-#., ()%]+$/', $input);
}
}
FontSizeValidator.php
<?php
namespace JBBCode\validators;
require_once dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'InputValidator.php';
/**
* An InputValidator for font size values.
*/
class FontSizeValidator implements \JBBCode\InputValidator {
/**
* Returns true if $input uses a valid font size value.
*
* @param $input the string to validate
*/
public function validate($input) {
return (bool) in_array($input, array(1, 2, 3, 4, 5, 6, 7));
}
}
- Place text like this in an appropriate test input:
[SIZE="8"]Uppercase SIZE "8"[/SIZE]
[size="8"]Lowercase SIZE "8"[/size]
[COLOR="!@$%^"]Uppercase COLOR !@$%^[/COLOR]
[color="!@$%^"]Lowercase COLOR !@$%^[/color]
- Notice this inconsistent output:
<font size="8">Uppercase SIZE "8"</font><br>
[size=8]Lowercase SIZE "8"[/size]<br>
<br>
<span style="color:!@$%^">Uppercase COLOR !@$%^</span><br>
[color=!@$%^]Lowercase COLOR !@$%^[/color]
Proposed fix to CodeDefinition.php:
public function hasValidInputs(ElementNode $el)
{
if ($this->usesOption() && $this->optionValidator) {
$att = $el->getAttribute();
foreach($att as $name => $value){
+ $name = strtolower($name);
if(isset($this->optionValidator[$name]) && !$this->optionValidator[$name]->validate($value)){
return false;
}
}
}
I've confirmed this works very well on my end.
Although I can imagine a different fix applied to ElementNode.php in the correct spot(s) but I am too busy to work out any unintended consequences.
Oh wow, I just realized I'm on JBBCode v1.3.0 and apparently the project is on v1.4.2 right now. I had no idea...
I guess I should update my copy. If I can get around to it, I will do that. Otherwise, I guess someone else on v1.4.2 could test to see if the same problem exists. If not, of course we can close this ticket.
Again, this might be entirely irrelevant because v1.4.2 exists, but for those on v1.3.0 and wanting to solve this problem, I actually took the time to look into fixing this in a more holistic may. I think this solution is preferable to the crude solution above.
ElementNode.php
public function setTagName($tagName)
{
- $this->tagName = $tagName;
+ $this->tagName = strtolower($tagName);
}
Parser.php
protected function parseOptions($tagContent)
{
$buffer = '';
$tagName = '';
$state = static::OPTION_STATE_TAGNAME;
$keys = array();
$values = array();
$options = array();
$len = strlen($tagContent);
$done = false;
$idx = 0;
try{
while(!$done){
$char = $idx < $len ? $tagContent[$idx]:null;
switch($state){
case static::OPTION_STATE_TAGNAME:
switch($char){
case '=':
$state = static::OPTION_STATE_VALUE;
- $tagName = $buffer;
+ $tagName = strtolower($buffer);
$keys[] = $tagName;
$buffer = "";
break;
case ' ':
$state = static::OPTION_STATE_DEFAULT;
- $tagName = $buffer;
+ $tagName = strtolower($buffer);
$buffer = '';
$keys[] = $tagName;
break;
case null:
- $tagName = $buffer;
+ $tagName = strtolower($buffer);
$buffer = '';
$keys[] = $tagName;
break;
default:
$buffer .= $char;
}
break;
visitors/NestLimitVisitor.php
public function visitElementNode(\JBBCode\ElementNode $elementNode)
{
- $tagName = strtolower($elementNode->getTagName());
+ $tagName = $elementNode->getTagName();
visitors/TagCountingVisitor.php
public function visitElementNode(\JBBCode\ElementNode $elementNode)
{
- $tagName = strtolower($elementNode->getTagName());
+ $tagName = $elementNode->getTagName();