4 htmLawedTest.php, 16 July 2009
5 htmLawed 1.1.8.1, 16 July 2009
6 Copyright Santosh Patnaik
8 A PHP Labware internal utility - http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed
10 Test htmLawed; user provides text input; input and processed input are shown as highlighted code and rendered HTML; also shown are execution time and peak memory usage
14 $_errs = 0; // display PHP errors
15 $_limit = 8000; // input character limit
18 $_hlimit = 1000; // input character limit for showing hexdumps
19 $_hilite = 1; // 0 turns off slow Javascript-based code-highlighting, e.g., if $_limit is high
20 $_w3c_validate = 1; // 1 to show buttons to send input/output to w3c validator
21 $_sid = 'sid'; // session name; alphanum.
22 $_slife = 30; // session life in min.
25 error_reporting(E_ALL | (defined('E_STRICT') ? E_STRICT : 1));
26 ini_set('display_errors', $_errs);
30 session_cache_limiter('private');
31 session_cache_expire($_slife);
32 ini_set('session.gc_maxlifetime', $_slife * 60);
33 ini_set('session.use_only_cookies', 1);
34 ini_set('session.cookie_lifetime', 0);
36 if(!isset($_SESSION['token'])){
37 $_SESSION['token'] = md5(uniqid(rand(), 1));
41 if(get_magic_quotes_gpc()){
42 foreach($_POST as $k => $v){
43 $_POST[$k] = stripslashes($v);
45 ini_set('magic_quotes_gpc', 0);
47 set_magic_quotes_runtime(0);
49 $_POST['enc'] = (isset($_POST['enc']) and preg_match('`^[-\w]+$`', $_POST['enc'])) ? $_POST['enc'] : 'utf-8';
51 // token for anti-CSRF
53 if((empty($_GET['pre']) and ((!empty($_POST['token']) and !empty($_SESSION['token']) and $_POST['token'] != $_SESSION['token']) or empty($_POST[$_sid]) or $_POST[$_sid] != session_id() or empty($_COOKIE[$_sid]) or $_COOKIE[$_sid] != session_id())) or ($_POST[$_sid] != session_id())){
54 $_POST = array('enc'=>'utf-8');
57 if(empty($_GET['pre'])){
58 $_SESSION['token'] = md5(uniqid(rand(), 1));
59 $token = $_SESSION['token'];
60 session_regenerate_id(1);
64 if(function_exists('gzencode') && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && preg_match('`gzip|deflate`i', $_SERVER['HTTP_ACCEPT_ENCODING']) && !ini_get('zlib.output_compression')){
65 ob_start('ob_gzhandler');
68 // HTM for unprocessed
69 if(isset($_POST['inputH'])){
70 echo '<html><head><title>htmLawed test: HTML view of unprocessed input</title></head><body style="margin:0; padding: 0;"><p style="background-color: black; color: white; padding: 2px;"> Rendering of unprocessed input without an HTML doctype or charset declaration <small><a style="color: white; text-decoration: none;" href="1" onclick="javascript:window.close(this); return false;">close window</a> | <a style="color: white; text-decoration: none;" href="htmLawedTest.php" onclick="javascript: window.open(\'htmLawedTest.php\', \'hlmain\'); window.close(this); return false;">htmLawed test page</a></small></p><div>', $_POST['inputH'], '</div></body></html>';
75 $_POST['text'] = isset($_POST['text']) ? $_POST['text'] : 'text to process; < '. $_limit. ' characters'. ($_hlimit ? ' (for binary hexdump view, < '. $_hlimit. ')' : '');
76 $do = (!empty($_POST[$_sid]) && isset($_POST['text'][0]) && !isset($_POST['text'][$_limit])) ? 1 : 0;
77 $limit_exceeded = isset($_POST['text'][$_limit]) ? 1 : 0;
78 $pre_mem = memory_get_usage();
79 $validation = (!empty($_POST[$_sid]) and isset($_POST['w3c_validate'][0])) ? 1 : 0;
80 include './htmLawed.php';
83 $t = "\n". str_replace(array("\t", "\r\n", "\r", '&', '<', '>', "\n"), array(' ', "\n", "\n", '&', '<', '>', "<span class=\"newline\">¬</span><br />\n"), $t);
84 return str_replace(array('<br />', "\n ", ' '), array("\n<br />\n", "\n ", ' '), $t);
88 // Mainly by Aidan Lister <aidan@php.net>, Peter Waller <iridum@php.net>
95 for($i=$j=0; $i<$len; $i++)
97 // Convert to hexidecimal
98 $hexi .= sprintf("%02X ", ord($d[$i]));
99 // Replace non-viewable bytes with '.'
100 if(ord($d[$i]) >= 32){
101 $ascii .= htmlspecialchars($d[$i]);
105 // Add extra column spacing
111 if(++$j == 16 || $i == $len-1){
112 // Join the hexi / ascii output
113 echo sprintf("%04X %-49s %s", $offset, $hexi, $ascii);
125 $o = ob_get_contents();
131 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
132 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
133 <html lang="en" xml:lang="en">
135 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo htmlspecialchars($_POST['enc']); ?>" />
136 <meta name="description" content="htmLawed <?php echo hl_version();?> test page" />
137 <style type="text/css"><!--/*--><![CDATA[/*><!--*/
138 a, a.resizer{text-decoration:none;}
139 a:hover, a.resizer:hover{color:red;}
140 a.resizer{color:green; float:right;}
141 body{background-color:#efefef;}
142 body, button, div, html, input, p{font-size:13px; font-family:'Lucida grande', Verdana, Arial, Helvetica, sans-serif;}
143 button, input{font-size: 85%;}
144 div.help{border-top: 1px dotted gray; margin-top: 15px; padding-top: 15px; color:#999999;}
145 #inputC, #inputD, #inputF, #inputR, #outputD, #outputF, #outputH, #outputR, #settingF{display:block;}
146 #inputC, #settingF{background-color:white; border:1px gray solid; padding:3px;}
147 #inputC li{margin: 0; padding: 0;}
148 #inputC ul{margin: 0; padding: 0; margin-left: 14px;}
149 #inputC input{margin: 0; margin-left: 2px; margin-right: 2px; padding: 1px; vertical-align: middle;}
150 #inputD{overflow:auto; background-color:#ffff99; border:1px #cc9966 solid; padding:3px;}
151 #inputR{overflow:auto; background-color:#ffffcc; border:1px #ffcc99 solid; padding:3px;}
152 #inputC, #settingF, #inputD, #inputR, #outputD, #outputR, textarea{font-size:100%; font-family:'Bitstream vera sans mono', 'courier new', 'courier', monospace;}
153 #outputD{overflow:auto; background-color: #99ffcc; border:1px #66cc99 solid; padding:3px;}
154 #outputH{overflow:auto; background-color:white; padding:3px; border:1px #dcdcdc solid;}
155 #outputR{overflow:auto; background-color: #ccffcc; border:1px #99cc99 solid; padding:3px;}
156 span.cmtcdata{color: orange;}
157 span.ctag{color:red;}
158 span.ent{border-bottom:1px dotted #999999;}
159 span.etag{color:purple;}
160 span.help{color:#999999;}
161 span.newline{color:#dcdcdc;}
162 span.notice{color:green;}
163 span.otag{color:blue;}
164 #topmost{margin:auto; width:98%;}
166 <script type="text/javascript"><!--//--><![CDATA[//><!--
167 window.name = 'hlmain';
169 <?php if(!$_hilite){echo 'return;'; }?>
170 var e = document.getElementById(i);
172 run(e, '</[a-z1-6]+>', 'ctag');
173 run(e, '<[a-z]+(?:[^>]*)/>', 'etag');
174 run(e, '<[a-z1-6]+(?:[^>]*)>', 'otag');
175 run(e, '&[#a-z0-9]+;', 'ent');
176 run(e, '<!(?:(?:--(?:.|\n)*?--)|(?:\\[CDATA\\[(?:.|\n)*?\\]\\]))>', 'cmtcdata');
179 var f = document.getElementById('testform');
181 var e = document.createElement('input');
183 e.name = '<?php echo htmlspecialchars($_sid); ?>';
184 e.id = '<?php echo htmlspecialchars($_sid); ?>';
185 e.value = readCookie('<?php echo htmlspecialchars($_sid); ?>');
189 function readCookie(n){
191 var ca = document.cookie.split(';');
192 for(var i=0;i < ca.length;i++){
194 while(c.charAt(0)==' '){
195 c = c.substring(1,c.length);
197 if(c.indexOf(ne) == 0){
198 return c.substring(ne.length,c.length);
203 function run(e, q, c){
204 var q = new RegExp(q);
205 if(e.firstChild == null){
206 var m = q.exec(e.data);
209 var k2 = e.splitText(m.index);
210 var k3 = k2.splitText(v.length);
211 var s = e.ownerDocument.createElement('span');
212 e.parentNode.replaceChild(s, k2);
213 s.className = c; s.appendChild(k2);
216 for(var k = e.firstChild; k != null; k = k.nextSibling){
218 var m = q.exec(k.data);
221 var k2 = k.splitText(m.index);
222 var k3 = k2.splitText(v.length);
223 var s = k.ownerDocument.createElement('span');
224 k.parentNode.replaceChild(s, k2);
225 s.className = c; s.appendChild(k2);
228 else if(c == 'ent' && k.nodeType == 1){
229 var d = k.firstChild;
231 var m = q.exec(d.data);
234 var d2 = d.splitText(m.index);
235 var d3 = d2.splitText(v.length);
236 var s = d.ownerDocument.createElement('span');
237 d.parentNode.replaceChild(s, d2);
238 s.className = c; s.appendChild(d2);
245 var e = document.getElementById(i);
248 var a = e.style.display;
249 if(a == 'block'){e.style.display = 'none'; return;}
250 if(a == 'none'){e.style.display = 'block';}
251 else{e.style.display = 'none';}
254 var a = e.visibility;
255 if(a == 'hidden'){e.visibility = 'show'; return;}
256 if(a == 'show'){e.visibility = 'hidden';}
258 function sndUnproc(){
259 var i = document.getElementById('text');
262 i = i.replace(/>/g, '>');
263 i = i.replace(/</g, '<');
264 i = i.replace(/"/g, '"');
265 var w = window.open('htmLawedTest.php?pre=1', 'hlprehtm');
266 var f = document.createElement('form');
267 f.enctype = 'application/x-www-form-urlencoded';
269 f.acceptCharset = '<?php echo htmlspecialchars($_POST['enc']); ?>';
270 if(f.style){f.style.display = 'none';}
271 else{f.visibility = 'hidden';}
272 f.innerHTML = '<p style="display:none;"><input style="display:none;" type="hidden" name="token" id="token" value="<?php echo $token; ?>" /><input style="display:none;" type="hidden" name="<?php echo htmlspecialchars($_sid); ?>" id="<?php echo htmlspecialchars($_sid); ?>" value="' + readCookie('<?php echo htmlspecialchars($_sid); ?>') + '" /><input style="display:none;" type="hidden" name="inputH" id="inputH" value="'+ i+ '" /></p>';
273 f.action = 'htmLawedTest.php?pre=1';
274 f.target = 'hlprehtm';
276 var b = document.getElementsByTagName('body')[0];
281 function sndValidn(id, type){
282 var i = document.getElementById(id);
285 i = i.replace(/>/g, '>');
286 i = i.replace(/</g, '<');
287 i = i.replace(/"/g, '"');
288 var w = window.open('http://validator.w3.org/check', 'validate'+id+type);
289 var f = document.createElement('form');
290 f.enctype = 'application/x-www-form-urlencoded';
292 f.acceptCharset = '<?php echo htmlspecialchars($_POST['enc']); ?>';
293 if(f.style){f.style.display = 'none';}
294 else{f.visibility = 'hidden';}
295 f.innerHTML = '<p style="display:none;"><input style="display:none;" type="hidden" name="fragment" id="fragment" value="'+ i+ '" /><input style="display:none;" type="hidden" name="prefill" id="prefill" value="1" /><input style="display:none;" type="hidden" name="prefill_doctype" id="prefill_doctype" value="'+ type+ '" /><input style="display:none;" type="hidden" name="group" id="group" value="1" /><input type="hidden" name="ss" id="ss" value="1" /></p>';
296 f.action = 'http://validator.w3.org/check';
297 f.target = 'validate'+id+type;
298 var b = document.getElementsByTagName('body')[0];
305 resizeClass: 'textarea',
306 adEv: function(t,ev,fn){
307 if(typeof document.addEventListener != 'undefined'){
308 t.addEventListener(ev,fn,false);
310 t.attachEvent('on' + ev, fn);
313 rmEv: function(t,ev,fn){
314 if(typeof document.removeEventListener != 'undefined'){
315 t.removeEventListener(ev,fn,false);
318 t.detachEvent('on' + ev, fn);
322 var textareas = document.getElementsByTagName('textarea');
323 for(var i = 0; i < textareas.length; i++){
324 var txtclass=textareas[i].className;
325 if(txtclass.substring(0,tRs.resizeClass.length)==tRs.resizeClass ||
326 txtclass.substring(txtclass.length -tRs.resizeClass.length)==tRs.resizeClass){
327 var a = document.createElement('a');
328 a.appendChild(document.createTextNode("\u2195"));
329 a.style.cursor = 'n-resize';
330 a.className= 'resizer';
331 a.title = 'click-drag to resize'
332 tRs.adEv(a, 'mousedown', tRs.initResize);
333 textareas[i].parentNode.appendChild(a);
337 initResize: function(event){
338 if(typeof event == 'undefined'){
339 event = window.event;
341 if(event.srcElement){
342 var target = event.srcElement.previousSibling;
344 var target = event.target.previousSibling;
346 if(target.nodeName.toLowerCase() == 'textarea' || (target.nodeName.toLowerCase() == 'input' && target.type == 'text')){
348 tRs.formEl.startHeight = tRs.formEl.clientHeight;
349 tRs.formEl.startY = event.clientY;
350 tRs.adEv(document, 'mousemove', tRs.resize);
351 tRs.adEv(document, 'mouseup', tRs.stopResize);
352 tRs.formEl.parentNode.style.cursor = 'n-resize';
353 tRs.formEl.style.cursor = 'n-resize';
355 event.preventDefault();
360 resize: function(event){
361 if(typeof event == 'undefined'){
362 event = window.event;
364 if(tRs.formEl.nodeName.toLowerCase() == 'textarea'){
365 tRs.formEl.style.height = event.clientY - tRs.formEl.startY + tRs.formEl.startHeight + 'px';
368 stopResize: function(event){
369 tRs.rmEv(document, 'mousedown', tRs.initResize);
370 tRs.rmEv(document, 'mousemove', tRs.resize);
371 tRs.formEl.style.cursor = 'text';
372 tRs.formEl.parentNode.style.cursor = 'auto';
376 tRs.adEv(window, 'load', tRs.adBtn);
378 <title>htmLawed (<?php echo hl_version();?>) test</title>
383 <h5 style="float: left; display: inline; margin-top: 0; margin-bottom: 5px;"><a href="http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/index.php" title="htmLawed home">HTM<big><big>L</big></big>AWED</a> <?php echo hl_version();?> <a href="htmLawedTest.php" title="test home">TEST</a></h5>
384 <span style="float: right;" class="help"><a href="htmLawed_README.htm"><span class="notice">htm</span></a> / <a href="htmLawed_README.txt"><span class="notice">txt</span></a> documentation</span><br style="clear:both;" />
386 <a href="htmLawedTest.php" title="[toggle visibility] type or copy-paste" onclick="javascript:toggle('inputF'); return false;"><span class="notice">Input »</span> <span class="help" title="limit lower with multibyte characters<?php echo (($_hlimit < $_limit && $_hlimit)? '; limit is '. $_hlimit. ' for viewing binaries' : ''); ?>"><small>(max. <?php echo htmlspecialchars($_limit);?> chars)</small></span></a>
388 <form id="testform" name="testform" action="htmLawedTest.php" method="post" accept-charset="<?php echo htmlspecialchars($_POST['enc']); ?>" style="padding:0; margin: 0; display:inline;">
390 <div id="inputF" style="display: block;">
392 <input type="hidden" name="token" id="token" value="<?php echo $token; ?>" />
393 <div><textarea id="text" class="textarea" name="text" rows="5" cols="100" style="width: 100%;"><?php echo htmlspecialchars($_POST['text']);?></textarea></div>
394 <input type="submit" id="submitF" name="submitF" value="Process" style="float:left;" title="filter using htmLawed" onclick="javascript: sndProc(); return false;" onkeypress="javascript: sndProc(); return false;" />
399 echo '<input type="hidden" value="1" name="w3c_validate" id="w3c_validate" />';
403 <button type="button" title="rendered as web-page without a doctype or charset declaration" style="float: right;" onclick="javascript: sndUnproc(); return false;" onkeypress="javascript: sndUnproc(); return false;">View unprocessed</button>
404 <button type="button" onclick="javascript:document.getElementById('text').focus();document.getElementById('text').select()" title="select all to copy" style="float:right;">Select all</button>
407 if($_w3c_validate && $validation){
410 <button type="button" title="HTML 4.01 W3C online validation" style="float: right;" onclick="javascript: sndValidn('text', 'html401'); return false;" onkeypress="javascript: sndValidn('text', 'html401'); return false;">Check HTML</button>
411 <button type="button" title="XHTML 1.1 W3C online validation" style="float: right;" onclick="javascript: sndValidn('text', 'xhtml110'); return false;" onkeypress="javascript: sndValidn('text', 'xhtml110'); return false;">Check XHTML</button>
418 echo '<span style="float: right;" class="help" title="for direct submission of input or output code to W3C validator for (X)HTML validation"><span style="font-size: 85%;"> Validator tools: </span><input type="checkbox" value="1" name="w3c_validate" id="w3c_validate" style="vertical-align: middle;"', ($validation ? ' checked="checked"' : ''), ' /></span>';
423 <span style="float:right;" class="help"><span style="font-size: 85%;">Encoding: </span><input type="text" size="8" id="enc" name="enc" style="vertical-align: middle;" value="<?php echo htmlspecialchars($_POST['enc']); ?>" title="IANA-recognized name of the input character-set; can be multiple ;- or space-separated values; may not work in some browsers" /></span>
426 <br style="clear:both;" />
430 echo '<br /><strong>Input text is too long!</strong><br />';
436 <a href="htmLawedTest.php" title="[toggle visibility] htmLawed configuration" onclick="javascript:toggle('inputC'); return false;"><span class="notice">Settings »</span></a>
438 <div id="inputC" style="display: none;">
439 <table summary="none">
441 <td><span class="help" title="$config argument">Config:</span></td>
446 'abs_url'=>array('3', '0', 'absolute/relative URL conversion', '-1'),
447 'and_mark'=>array('2', '0', 'mark original <em>&</em> chars', '0', 'd'=>1), // 'd' to disable
448 'anti_link_spam'=>array('1', '0', 'modify <em>href</em> values as an anti-link spam measure', '0', array(array('30', '1', '', 'regex for extra <em>rel</em>'), array('30', '2', '', 'regex for no <em>href</em>'))),
449 'anti_mail_spam'=>array('1', '0', 'replace <em>@</em> in <em>mailto:</em> URLs', '0', '8', 'NO@SPAM', 'replacement'),
450 'balance'=>array('2', '1', 'fix nestings and balance tags', '0'),
451 'base_url'=>array('', '', 'base URL', '25'),
452 'cdata'=>array('4', 'nil', 'allow <em>CDATA</em> sections', 'nil'),
453 'clean_ms_char'=>array('3', '0', 'replace bad characters introduced by Microsoft apps. like <em>Word</em>', '0'),
454 'comment'=>array('4', 'nil', 'allow HTML comments', 'nil'),
455 'css_expression'=>array('2', 'nil', 'allow dynamic expressions in CSS style properties', 'nil'),
456 'deny_attribute'=>array('1', '0', 'denied attributes', '0', '50', '', 'these'),
457 'elements'=>array('', '', 'allowed elements', '50'),
458 'hexdec_entity'=>array('3', '1', 'convert hexadecimal numeric entities to decimal ones, or vice versa', '0'),
459 'hook'=>array('', '', 'name of hook function', '25'),
460 'hook_tag'=>array('', '', 'name of custom function to further check attribute values', '25'),
461 'keep_bad'=>array('7', '6', 'keep, or remove <em>bad</em> tag content', '0'),
462 'lc_std_val'=>array('2', '1', 'lower-case std. attribute values like <em>radio</em>', '0'),
463 'make_tag_strict'=>array('3', 'nil', 'transform deprecated elements', 'nil'),
464 'named_entity'=>array('2', '1', 'allow named entities, or convert numeric ones', '0'),
465 'no_deprecated_attr'=>array('3', '1', 'allow deprecated attributes, or transform them', '0'),
466 'parent'=>array('', 'div', 'name of parent element', '25'),
467 'safe'=>array('2', '0', 'for most <em>safe</em> HTML', '0'),
468 'schemes'=>array('', 'href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; *:file, http, https', 'allowed URL protocols', '50'),
469 'show_setting'=>array('', 'htmLawed_setting', 'variable name to record <em>finalized</em> htmLawed settings', '25', 'd'=>1),
470 'style_pass'=>array('2', 'nil', 'do not look at <em>style</em> attribute values', 'nil'),
471 'tidy'=>array('3', '0', 'beautify/compact', '-1', '8', '1t1', 'format'),
472 'unique_ids'=>array('2', '1', 'unique <em>id</em> values', '0', '8', 'my_', 'prefix'),
473 'valid_xhtml'=>array('2', 'nil', 'auto-set various parameters for most valid XHTML', 'nil'),
474 'xml:lang'=>array('3', 'nil', 'auto-add <em>xml:lang</em> attribute', '0'),
476 foreach($cfg as $k=>$v){
477 echo '<li>', $k, ': ';
478 if(!empty($v[0])){ // input radio
480 for($i = $j-1; ++$i < $v[0]+$v[3];++$j){
481 echo '<input type="radio" name="h', $k, '" value="', $i, '"', (!isset($_POST['h'. $k]) ? ($v[1] == $i ? ' checked="checked"' : '') : ($_POST['h'. $k] == $i ? ' checked="checked"' : '')), (isset($v['d']) ? ' disabled="disabled"' : ''), ' />', $i, ' ';
484 echo '<input type="radio" name="h', $k, '" value="nil"', ((!isset($_POST['h'. $k]) or $_POST['h'. $k] == 'nil') ? ' checked="checked"' : ''), (isset($v['d']) ? ' disabled="disabled"' : ''), ' />not set ';
486 if(!empty($v[4])){ // + input text box
487 echo '<input type="radio" name="h', $k, '" value="', $j, '"', (((isset($_POST['h'. $k]) && $_POST['h'. $k] == $j) or (!isset($_POST['h'. $k]) && $j == $v[1])) ? ' checked="checked"' : ''), (isset($v['d']) ? ' disabled="disabled"' : ''), ' />';
488 if(!is_array($v[4])){
489 echo $v[6], ': <input type="text" size="', $v[4], '" name="h', $k. $j, '" value="', htmlspecialchars(isset($_POST['h'. $k. $j][0]) ? $_POST['h'. $k. $j] : $v[5]), '"', (isset($v['d']) ? ' disabled="disabled"' : ''), ' />';
492 foreach($v[4] as $z){
493 echo ' ', $z[3], ': <input type="text" size="', $z[0], '" name="h', $k. $j. $z[1], '" value="', htmlspecialchars(isset($_POST['h'. $k. $j. $z[1]][0]) ? $_POST['h'. $k. $j. $z[1]] : $z[2]), '"', (isset($v['d']) ? ' disabled="disabled"' : ''), ' />';
498 elseif(ctype_digit($v[3])){ // input text
499 echo '<input type="text" size="', $v[3], '" name="h', $k, '" value="', htmlspecialchars(isset($_POST['h'. $k][0]) ? $_POST['h'. $k] : $v[1]), '"', (isset($v['d']) ? ' disabled="disabled"' : ''), ' />';
502 echo ' <span class="help">', $v[2], '</span></li>';
504 echo '</ul></td></tr><tr><td><span style="vertical-align: top;" class="help" title="$spec argument: element-specific attribute rules">Spec:</span></td><td><textarea name="spec" id="spec" cols="70" rows="3" style="width:80%;">', htmlspecialchars((isset($_POST['spec']) ? $_POST['spec'] : '')), '</textarea></td></tr></table>';
513 foreach($_POST as $k=>$v){
514 if($k[0] == 'h' && $v != 'nil'){
515 $cfg[substr($k, 1)] = $v;
519 if($cfg['anti_link_spam'] && (!empty($cfg['anti_link_spam11']) or !empty($cfg['anti_link_spam12']))){
520 $cfg['anti_link_spam'] = array($cfg['anti_link_spam11'], $cfg['anti_link_spam12']);
522 unset($cfg['anti_link_spam11'], $cfg['anti_link_spam12']);
523 if($cfg['anti_mail_spam'] == 1){
524 $cfg['anti_mail_spam'] = isset($cfg['anti_mail_spam1'][0]) ? $cfg['anti_mail_spam1'] : 0;
526 unset($cfg['anti_mail_spam11']);
527 if($cfg['deny_attribute'] == 1){
528 $cfg['deny_attribute'] = isset($cfg['deny_attribute1'][0]) ? $cfg['deny_attribute1'] : 0;
530 unset($cfg['deny_attribute1']);
531 if($cfg['tidy'] == 2){
532 $cfg['tidy'] = isset($cfg['tidy2'][0]) ? $cfg['tidy2'] : 0;
534 unset($cfg['tidy2']);
535 if($cfg['unique_ids'] == 2){
536 $cfg['unique_ids'] = isset($cfg['unique_ids2'][0]) ? $cfg['unique_ids2'] : 1;
538 unset($cfg['unique_ids2']);
539 unset($cfg['and_mark']); // disabling and_mark
541 $cfg['show_setting'] = 'hlcfg';
543 $out = htmLawed($_POST['text'], $cfg, str_replace(array('$', '{'), '', $_POST['spec']));
545 echo '<br /><a href="htmLawedTest.php" title="[toggle visibility] syntax-highlighted" onclick="javascript:toggle(\'inputR\'); return false;"><span class="notice">Input code »</span></a> <span class="help" title="tags estimated as half of total > and < chars; values may be inaccurate for non-ASCII text"><small><big>', strlen($_POST['text']), '</big> chars, ~<big>', round((substr_count($_POST['text'], '>') + substr_count($_POST['text'], '<'))/2), '</big> tags</small> </span><div id="inputR" style="display: none;">', format($_POST['text']), '</div><script type="text/javascript">hl(\'inputR\');</script>', (!isset($_POST['text'][$_hlimit]) ? ' <a href="htmLawedTest.php" title="[toggle visibility] hexdump; non-viewable characters like line-returns are shown as dots" onclick="javascript:toggle(\'inputD\'); return false;"><span class="notice">Input binary » </span></a><div id="inputD" style="display: none;">'. hexdump($_POST['text']). '</div>' : ''), ' <a href="htmLawedTest.php" title="[toggle visibility] finalized internal settings as interpreted by htmLawed; for developers" onclick="javascript:toggle(\'settingF\'); return false;"><span class="notice">Finalized internal settings » </span></a> <div id="settingF" style="display: none;">', str_replace(array(' ', "\t", ' '), array(' ', ' ', ' '), nl2br(htmlspecialchars(print_r($GLOBALS['hlcfg']['config'], true)))), '</div><script type="text/javascript">hl(\'settingF\');</script>', '<br /><a href="htmLawedTest.php" title="[toggle visibility] suitable for copy-paste" onclick="javascript:toggle(\'outputF\'); return false;"><span class="notice">Output »</span></a> <span class="help" title="approx., server-specific value excluding the \'include()\' call"><small>htmLawed processing time <big>', number_format(((substr($et,0,9)) + (substr($et,-10)) - (substr($st,0,9)) - (substr($st,-10))),4), '</big> s</small></span>', (($mem = memory_get_peak_usage()) !== false ? '<span class="help"><small>, peak memory usage <big>'. round(($mem-$pre_mem)/1048576, 2). '</big> <small>MB</small>' : ''), '</small></span><div id="outputF" style="display: block;"><div><textarea id="text2" class="textarea" name="text2" rows="5" cols="100" style="width: 100%;">', htmlspecialchars($out), '</textarea></div><button type="button" onclick="javascript:document.getElementById(\'text2\').focus();document.getElementById(\'text2\').select()" title="select all to copy" style="float:right;">Select all</button>';
546 if($_w3c_validate && $validation)
550 <button type="button" title="HTML 4.01 W3C online validation" style="float: right;" onclick="javascript: sndValidn('text2', 'html401'); return false;" onkeypress="javascript: sndValidn('text2', 'html401'); return false;">Check HTML</button>
551 <button type="button" title="XHTML 1.1 W3C online validation" style="float: right;" onclick="javascript: sndValidn('text2', 'xhtml110'); return false;" onkeypress="javascript: sndValidn('text2', 'xhtml110'); return false;">Check XHTML</button>
555 echo '</div><br /><a href="htmLawedTest.php" title="[toggle visibility] syntax-highlighted" onclick="javascript:toggle(\'outputR\'); return false;"><span class="notice">Output code »</span></a><div id="outputR" style="display: block;">', format($out), '</div><script type="text/javascript">hl(\'outputR\');</script>', (!isset($_POST['text'][$_hlimit]) ? '<br /><a href="htmLawedTest.php" title="[toggle visibility] hexdump; non-viewable characters like line-returns are shown as dots" onclick="javascript:toggle(\'outputD\'); return false;"><span class="notice">Output binary »</span></a><div id="outputD" style="display: none;">'. hexdump($out). '</div>' : ''), '<br /><a href="htmLawedTest.php" title="[toggle visibility] XHTML 1 Transitional doctype" onclick="javascript:toggle(\'outputH\'); return false;"><span class="notice">Output rendered »</span></a><div id="outputH" style="display: block;">', $out, '</div>';
562 <div class="help">Use with a Javascript- and cookie-enabled, relatively new version of a common browser. <em>Submitted input will also be HTML-rendered (XHTML 1) after htmLawed-filtering.</em>
564 <?php echo (file_exists('./htmLawed_TESTCASE.txt') ? '<br /><br />You can use text from <a href="htmLawed_TESTCASE.txt"><span class="notice">this collection of test-cases</span></a> in the input. Set the character encoding of the browser to Unicode/utf-8 before copying.' : ''); ?>
566 <br /><br />For anti-XSS tests, try the <a href="http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/htmLawedSafeModeTest.php"><span class="notice">special test-page</span></a> or see <a href="http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/rsnake/RSnakeXSSTest.htm"><span class="notice">these results</span></a>.
568 <br /><br /><small>Change <em>Encoding</em> to reflect the character encoding of the input text. Even then, it may not work or some characters may not display properly because of variable browser support and because of the form interface. Developers can write some PHP code to capture the filtered input to a file if this is important.
569 <br /><br />Refer to the htmLawed documentation (<a href="htmLawed_README.htm"><span class="notice">htm</span></a>/<a href="htmLawed_README.txt"><span class="notice">txt</span></a>) for details about <em>Settings</em>, and htmLawed's behavior and limitations. For <em>Settings</em>, incorrectly-specified values like regular expressions are silently ignored. One or more settings form-fields may have been disabled. Some characters are not allowed in the <em>Spec</em> field.
572 <br /><br />Hovering the mouse over some of the text can provide additional information in some browsers.</small>
578 <small><br /><br />Because of character-encoding issues, the W3C validator (anyway not perfect) may reject validation requests or invalidate otherwise-valid code, esp. if text was copy-pasted in the input box. Local applications like the <em>HTML Validator</em> Firefox browser add-on may be useful in such cases.</small>