patternphpMinor
Functions to escape CSS rules in PHP
Viewed 0 times
cssphprulesfunctionsescape
Problem
Some context
I've been tasked with supplying an escaping function to arbitrary CSS values that are entered through a form. The goals and caveats are:
The Code
```
/**
* ord() alternative that works with UTF8 characters
* @param string $c
*
* @return int UTF-8 character code value
*/
function getUTF8CharCode($c) {
$h = ord($c{0});
if ($h <= 0x7F) {
return $h;
} else if ($h < 0xC2) {
return false;
} else if ($h <= 0xDF) {
return ($h & 0x1F) << 6 | (ord($c{1}) & 0x3F);
} else if ($h <= 0xEF) {
return ($h & 0x0F) << 12 | (ord($c{1}) & 0x3F) << 6
| (ord($c{2}) & 0x3F);
} else if ($h <= 0xF4) {
return ($h & 0x0F) << 18 | (ord($c{1}) & 0x3F) << 12
| (ord($c{2}) & 0x3F) << 6
| (ord($c{3}) & 0x3F);
} else {
return -1;
}
}
/**
* Escape a single character for CSS context.
* @param $c
* @return string
*/
function escapeCSSCharacter($c) {
return "\\" . base_convert(getUTF8CharCode($c), 10, 16) . " ";
}
/**
* Escape CSS rule
*
* @param string $data The CSS rule
* @param array $immuneChars Array of immune character. These characters will not be escaped.
*
* @return string Escaped string
*/
function escapeCSSValue($data, array $immuneChars = array()) {
$result = "";
for ($i = 0; $i < mb_strlen($data); $i++) {
$currChar = mb_substr($data, $i, 1);
if (getUTF8CharCode($currChar) < 256 && //Character value is less than 256
!preg_match("/^\w$/", $currChar) && //Character is not alphanumeric (underscore is considered safe too)
!in_array($currChar, $immuneChars) //Character is not immune
) {
$re
I've been tasked with supplying an escaping function to arbitrary CSS values that are entered through a form. The goals and caveats are:
- I know it's bad practice to let users input CSS. Deal with it.
- Data will be injected either to a
styleattribute, or to an external stylesheet.
- This is run on PHP 5.1 (Again, I know, deal with it).
- I'm trying to follow this cheat sheet as closely as possible.
The Code
```
/**
* ord() alternative that works with UTF8 characters
* @param string $c
*
* @return int UTF-8 character code value
*/
function getUTF8CharCode($c) {
$h = ord($c{0});
if ($h <= 0x7F) {
return $h;
} else if ($h < 0xC2) {
return false;
} else if ($h <= 0xDF) {
return ($h & 0x1F) << 6 | (ord($c{1}) & 0x3F);
} else if ($h <= 0xEF) {
return ($h & 0x0F) << 12 | (ord($c{1}) & 0x3F) << 6
| (ord($c{2}) & 0x3F);
} else if ($h <= 0xF4) {
return ($h & 0x0F) << 18 | (ord($c{1}) & 0x3F) << 12
| (ord($c{2}) & 0x3F) << 6
| (ord($c{3}) & 0x3F);
} else {
return -1;
}
}
/**
* Escape a single character for CSS context.
* @param $c
* @return string
*/
function escapeCSSCharacter($c) {
return "\\" . base_convert(getUTF8CharCode($c), 10, 16) . " ";
}
/**
* Escape CSS rule
*
* @param string $data The CSS rule
* @param array $immuneChars Array of immune character. These characters will not be escaped.
*
* @return string Escaped string
*/
function escapeCSSValue($data, array $immuneChars = array()) {
$result = "";
for ($i = 0; $i < mb_strlen($data); $i++) {
$currChar = mb_substr($data, $i, 1);
if (getUTF8CharCode($currChar) < 256 && //Character value is less than 256
!preg_match("/^\w$/", $currChar) && //Character is not alphanumeric (underscore is considered safe too)
!in_array($currChar, $immuneChars) //Character is not immune
) {
$re
Solution
There's not much to say. Overall, the code is small and quite readable.
Just a small nitpick:
These comments say the what, not the why. They're akin to:
Your
I can't comment on the security-side of things.
Just a small nitpick:
if (getUTF8CharCode($currChar) < 256 && //Character value is less than 256
!preg_match("/^\w$/", $currChar) && //Character is not alphanumeric (underscore is considered safe too)
!in_array($currChar, $immuneChars) //Character is not immuneThese comments say the what, not the why. They're akin to:
$i++; // increments i by oneYour
if condition should be commented, but not like this.I can't comment on the security-side of things.
Code Snippets
if (getUTF8CharCode($currChar) < 256 && //Character value is less than 256
!preg_match("/^\w$/", $currChar) && //Character is not alphanumeric (underscore is considered safe too)
!in_array($currChar, $immuneChars) //Character is not immune$i++; // increments i by oneContext
StackExchange Code Review Q#55667, answer score: 7
Revisions (0)
No revisions yet.