diff options
-rw-r--r-- | _test/tests/inc/mailer.test.php | 63 | ||||
-rw-r--r-- | _test/tests/inc/pageutils_clean_id.test.php | 3 | ||||
-rw-r--r-- | _test/tests/inc/parser/parser_table.test.php | 58 | ||||
-rw-r--r-- | inc/Mailer.class.php | 22 | ||||
-rw-r--r-- | inc/SimplePie.php | 6 | ||||
-rw-r--r-- | inc/common.php | 3 | ||||
-rw-r--r-- | inc/parser/handler.php | 3 | ||||
-rw-r--r-- | inc/parser/xhtml.php | 25 | ||||
-rw-r--r-- | lib/exe/css.php | 25 | ||||
-rw-r--r-- | lib/exe/js.php | 7 | ||||
-rw-r--r-- | lib/plugins/authmysql/lang/en/settings.php | 4 | ||||
-rw-r--r-- | lib/plugins/authpgsql/lang/en/settings.php | 2 | ||||
-rw-r--r-- | lib/scripts/cookie.js | 2 |
13 files changed, 169 insertions, 54 deletions
diff --git a/_test/tests/inc/mailer.test.php b/_test/tests/inc/mailer.test.php index ef78692b3..3a89413b4 100644 --- a/_test/tests/inc/mailer.test.php +++ b/_test/tests/inc/mailer.test.php @@ -156,5 +156,68 @@ class mailer_test extends DokuWikiTest { $this->assertEquals(0, preg_match('/(^|\n)Bcc: (\n|$)/', $header), 'Bcc found in headers.'); $this->assertEquals(0, preg_match('/(^|\n)Cc: (\n|$)/', $header), 'Bcc found in headers.'); } + + /** + * @group internet + */ + function test_lint(){ + // prepare a simple multipart message + $mail = new TestMailer(); + $mail->to(array('Möp <moep@example.com> ',' foo <foo@example.com>')); + $mail->from('Me <test@example.com>'); + $mail->subject('This is a töst'); + $mail->setBody('Hello Wörld, + + please don\'t burn, okay? + '); + $mail->attachContent('some test data', 'text/plain', 'a text.txt'); + $msg = $mail->dump(); + $msglines = explode("\n", $msg); + + //echo $msg; + + // ask message lint if it is okay + $html = new HTTPClient(); + $results = $html->post('http://tools.ietf.org/tools/msglint/msglint', array('msg'=>$msg)); + $this->assertTrue($results !== false); + + // parse the result lines + $lines = explode("\n", $results); + $rows = count($lines); + $i=0; + while(trim($lines[$i]) != '-----------' && $i<$rows) $i++; //skip preamble + for($i=$i+1; $i<$rows; $i++){ + $line = trim($lines[$i]); + if($line == '-----------') break; //skip appendix + + // get possible continuation of the line + while($lines[$i+1][0] == ' '){ + $line .= ' '.trim($lines[$i+1]); + $i++; + } + + // check the line for errors + if(substr($line,0,5) == 'ERROR' || substr($line,0,7) == 'WARNING'){ + // ignore some errors + if(strpos($line, "missing mandatory header 'return-path'")) continue; #set by MDA + if(strpos($line, "bare newline in text body decoded")) continue; #seems to be false positive + + // get the context in which the error occured + $errorin = ''; + if(preg_match('/line (\d+)$/', $line, $m)){ + $errorin .= "\n".$msglines[$m[1] - 1]; + } + if(preg_match('/lines (\d+)-(\d+)$/', $line, $m)){ + for($x=$m[1]-1; $x<$m[2]; $x++){ + $errorin .= "\n".$msglines[$x]; + } + } + + // raise the error + throw new Exception($line.$errorin); + } + } + + } } //Setup VIM: ex: et ts=4 : diff --git a/_test/tests/inc/pageutils_clean_id.test.php b/_test/tests/inc/pageutils_clean_id.test.php index 478fd2bc4..f67109ba3 100644 --- a/_test/tests/inc/pageutils_clean_id.test.php +++ b/_test/tests/inc/pageutils_clean_id.test.php @@ -43,6 +43,9 @@ class init_clean_id_test extends DokuWikiTest { $tests[] = array('ns._#!ns:page','false','ns._ns:page'); $tests[] = array('ns_:page',false,'ns:page'); $tests[] = array('page...page','false','page...page'); + $tests[] = array('page---page','false','page---page'); + $tests[] = array('page___page','false','page_page'); + $tests[] = array('page_-.page','false','page_-.page'); $tests[] = array(':page',false,'page'); $tests[] = array(':ns:page',false,'ns:page'); $tests[] = array('page:',false,'page'); diff --git a/_test/tests/inc/parser/parser_table.test.php b/_test/tests/inc/parser/parser_table.test.php index 96789c38c..542a307b8 100644 --- a/_test/tests/inc/parser/parser_table.test.php +++ b/_test/tests/inc/parser/parser_table.test.php @@ -270,6 +270,64 @@ def'); ); $this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls); } + + function testCellRowSpanFirstRow() { + $this->P->addMode('table',new Doku_Parser_Mode_Table()); + $this->P->parse(' +abc +|::: ^ d:::^:::| ::: | +| b ^ e | | ::: | +|c ^ ::: | |:::| +def'); + + $calls = array ( + array('document_start',array()), + array('p_open',array()), + array('cdata',array("\n\nabc")), + array('p_close',array()), + array('table_open',array(4, 3, 6)), + array('tablerow_open',array()), + array('tablecell_open',array(1,NULL,1)), + array('cdata',array('')), + array('tablecell_close',array()), + array('tableheader_open',array(1,'right',1)), + array('cdata',array(' d:::')), + array('tableheader_close',array()), + array('tableheader_open',array(1,NULL,1)), + array('cdata',array('')), + array('tableheader_close',array()), + array('tablecell_open',array(1,NULL,3)), + array('cdata',array('')), + array('tablecell_close',array()), + array('tablerow_close',array()), + array('tablerow_open',array()), + array('tablecell_open',array(1,NULL,1)), + array('cdata',array(' b ')), + array('tablecell_close',array()), + array('tableheader_open',array(1,'left',2)), + array('cdata',array(' e ')), + array('tableheader_close',array()), + array('tablecell_open',array(1,NULL,1)), + array('cdata',array(' ')), + array('tablecell_close',array()), + array('tablerow_close',array()), + array('tablerow_open',array()), + array('tablecell_open',array(1,'left',1)), + array('cdata',array('c ')), + array('tablecell_close',array()), + array('tablecell_open',array(1,NULL,1)), + array('cdata',array(' ')), + array('tablecell_close',array()), + array('tablerow_close',array()), + + array('table_close',array(69)), + array('p_open',array()), + array('cdata',array('def')), + array('p_close',array()), + array('document_end',array()), + ); + $this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls); + } function testCellAlignmentFormatting() { $this->P->addMode('table',new Doku_Parser_Mode_Table()); diff --git a/inc/Mailer.class.php b/inc/Mailer.class.php index 0f3321bb9..6a6468ab4 100644 --- a/inc/Mailer.class.php +++ b/inc/Mailer.class.php @@ -41,9 +41,10 @@ class Mailer { global $conf; $server = parse_url(DOKU_URL, PHP_URL_HOST); + if(strpos($server,'.') === false) $server = $server.'.localhost'; $this->partid = md5(uniqid(rand(), true)).'@'.$server; - $this->boundary = '----------'.md5(uniqid(rand(), true)); + $this->boundary = '__________'.md5(uniqid(rand(), true)); $listid = join('.', array_reverse(explode('/', DOKU_BASE))).$server; $listid = strtolower(trim($listid, '.')); @@ -57,6 +58,7 @@ class Mailer { $this->setHeader('X-DokuWiki-Server', $server); $this->setHeader('X-Auto-Response-Suppress', 'OOF'); $this->setHeader('List-Id', $conf['title'].' <'.$listid.'>'); + $this->setHeader('Date', date('r'), false); } /** @@ -417,6 +419,8 @@ class Mailer { $part = 1; // embedded attachments foreach($this->attach as $media) { + $media['name'] = str_replace(':', '_', cleanID($media['name'], true)); + // create content id $cid = 'part'.$part.'.'.$this->partid; @@ -426,13 +430,14 @@ class Mailer { } $mime .= '--'.$this->boundary.MAILHEADER_EOL; - $mime .= 'Content-Type: '.$media['mime'].';'.MAILHEADER_EOL; + $mime .= 'Content-Type: '.$media['mime'].';'.MAILHEADER_EOL. + ' id="'.$cid.'"'.MAILHEADER_EOL; $mime .= 'Content-Transfer-Encoding: base64'.MAILHEADER_EOL; $mime .= "Content-ID: <$cid>".MAILHEADER_EOL; if($media['embed']) { - $mime .= 'Content-Disposition: inline; filename="'.$media['name'].'"'.MAILHEADER_EOL; + $mime .= 'Content-Disposition: inline; filename='.$media['name'].''.MAILHEADER_EOL; } else { - $mime .= 'Content-Disposition: attachment; filename="'.$media['name'].'"'.MAILHEADER_EOL; + $mime .= 'Content-Disposition: attachment; filename='.$media['name'].''.MAILHEADER_EOL; } $mime .= MAILHEADER_EOL; //end of headers $mime .= chunk_split(base64_encode($media['data']), 74, MAILHEADER_EOL); @@ -469,7 +474,7 @@ class Mailer { if(!$this->html && !count($this->attach)) { // we can send a simple single part message $this->headers['Content-Type'] = 'text/plain; charset=UTF-8'; $this->headers['Content-Transfer-Encoding'] = 'base64'; - $body .= chunk_split(base64_encode($this->text), 74, MAILHEADER_EOL); + $body .= chunk_split(base64_encode($this->text), 72, MAILHEADER_EOL); } else { // multi part it is $body .= "This is a multi-part message in MIME format.".MAILHEADER_EOL; @@ -484,10 +489,11 @@ class Mailer { $body .= 'Content-Type: text/plain; charset=UTF-8'.MAILHEADER_EOL; $body .= 'Content-Transfer-Encoding: base64'.MAILHEADER_EOL; $body .= MAILHEADER_EOL; - $body .= chunk_split(base64_encode($this->text), 74, MAILHEADER_EOL); + $body .= chunk_split(base64_encode($this->text), 72, MAILHEADER_EOL); $body .= '--'.$this->boundary.'XX'.MAILHEADER_EOL; $body .= 'Content-Type: multipart/related;'.MAILHEADER_EOL. - ' boundary="'.$this->boundary.'"'.MAILHEADER_EOL; + ' boundary="'.$this->boundary.'";'.MAILHEADER_EOL. + ' type="text/html"'.MAILHEADER_EOL; $body .= MAILHEADER_EOL; } @@ -495,7 +501,7 @@ class Mailer { $body .= 'Content-Type: text/html; charset=UTF-8'.MAILHEADER_EOL; $body .= 'Content-Transfer-Encoding: base64'.MAILHEADER_EOL; $body .= MAILHEADER_EOL; - $body .= chunk_split(base64_encode($this->html), 74, MAILHEADER_EOL); + $body .= chunk_split(base64_encode($this->html), 72, MAILHEADER_EOL); $body .= MAILHEADER_EOL; $body .= $attachments; $body .= '--'.$this->boundary.'--'.MAILHEADER_EOL; diff --git a/inc/SimplePie.php b/inc/SimplePie.php index fd69b4b09..8a9060509 100644 --- a/inc/SimplePie.php +++ b/inc/SimplePie.php @@ -16579,7 +16579,11 @@ class SimplePie_Sanitize if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML)) { - + if (!class_exists('DOMDocument')) + { + $this->registry->call('Misc', 'error', array('DOMDocument not found, unable to use sanitizer', E_USER_WARNING, __FILE__, __LINE__)); + return ''; + } $document = new DOMDocument(); $document->encoding = 'UTF-8'; $data = $this->preprocess($data, $type); diff --git a/inc/common.php b/inc/common.php index 3312141c8..866e0aadd 100644 --- a/inc/common.php +++ b/inc/common.php @@ -1625,7 +1625,8 @@ function set_doku_pref($pref, $val) { } if (!empty($cookieVal)) { - setcookie('DOKU_PREFS', $cookieVal, time()+365*24*3600, DOKU_BASE, '', ($conf['securecookie'] && is_ssl())); + $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; + setcookie('DOKU_PREFS', $cookieVal, time()+365*24*3600, $cookieDir, '', ($conf['securecookie'] && is_ssl())); } } diff --git a/inc/parser/handler.php b/inc/parser/handler.php index b72f051ae..1de981b48 100644 --- a/inc/parser/handler.php +++ b/inc/parser/handler.php @@ -1371,7 +1371,8 @@ class Doku_Handler_Table { if (is_null($spanning_cell)) { // No spanning cell found, so convert this cell to // an empty one to avoid broken tables - $this->tableCells[$key][1][1] = ''; + $this->tableCalls[$key][0] = 'cdata'; + $this->tableCalls[$key][1][0] = ''; continue; } $this->tableCalls[$cellKey[$spanning_cell][$lastCell]][1][2]++; diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index 848afbd4f..fd02c0ce0 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -33,6 +33,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { private $lastsecid = 0; // last section edit id, used by startSectionEdit var $headers = array(); + /** @var array a list of footnotes, list starts at 1! */ var $footnotes = array(); var $lastlevel = 0; var $node = array(0,0,0,0,0); @@ -100,10 +101,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { if ( count ($this->footnotes) > 0 ) { $this->doc .= '<div class="footnotes">'.DOKU_LF; - $id = 0; - foreach ( $this->footnotes as $footnote ) { - $id++; // the number of the current footnote - + foreach ( $this->footnotes as $id => $footnote ) { // check its not a placeholder that indicates actual footnote text is elsewhere if (substr($footnote, 0, 5) != "@@FNT") { @@ -118,8 +116,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { if (count($alt)) { foreach ($alt as $ref) { // set anchor and backlink for the other footnotes - $this->doc .= ', <sup><a href="#fnt__'.($ref+1).'" id="fn__'.($ref+1).'" class="fn_bot">'; - $this->doc .= ($ref+1).')</a></sup> '.DOKU_LF; + $this->doc .= ', <sup><a href="#fnt__'.($ref).'" id="fn__'.($ref).'" class="fn_bot">'; + $this->doc .= ($ref).')</a></sup> '.DOKU_LF; } } @@ -295,6 +293,10 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * @author Andreas Gohr */ function footnote_close() { + /** @var $fnid int takes track of seen footnotes, assures they are unique even across multiple docs FS#2841 */ + static $fnid = 0; + // assign new footnote id (we start at 1) + $fnid++; // recover footnote into the stack and restore old content $footnote = $this->doc; @@ -306,17 +308,14 @@ class Doku_Renderer_xhtml extends Doku_Renderer { if ($i === false) { // its a new footnote, add it to the $footnotes array - $id = count($this->footnotes)+1; - $this->footnotes[count($this->footnotes)] = $footnote; + $this->footnotes[$fnid] = $footnote; } else { - // seen this one before, translate the index to an id and save a placeholder - $i++; - $id = count($this->footnotes)+1; - $this->footnotes[count($this->footnotes)] = "@@FNT".($i); + // seen this one before, save a placeholder + $this->footnotes[$fnid] = "@@FNT".($i); } // output the footnote reference and link - $this->doc .= '<sup><a href="#fn__'.$id.'" id="fnt__'.$id.'" class="fn_top">'.$id.')</a></sup>'; + $this->doc .= '<sup><a href="#fn__'.$fnid.'" id="fnt__'.$fnid.'" class="fn_top">'.$fnid.')</a></sup>'; } function listu_open() { diff --git a/lib/exe/css.php b/lib/exe/css.php index 60e17ae82..afba5fc02 100644 --- a/lib/exe/css.php +++ b/lib/exe/css.php @@ -148,9 +148,6 @@ function css_out(){ // parse less $css = css_parseless($css); - // place all remaining @import statements at the top of the file - $css = css_moveimports($css); - // compress whitespace and comments if($conf['compress']){ $css = css_compress($css); @@ -460,28 +457,6 @@ function css_pluginstyles($mediatype='screen'){ } /** - * Move all @import statements in a combined stylesheet to the top so they - * aren't ignored by the browser. - * - * @author Gabriel Birke <birke@d-scribe.de> - */ -function css_moveimports($css) { - if(!preg_match_all('/@import\s+(?:url\([^)]+\)|"[^"]+")\s*[^;]*;\s*/', $css, $matches, PREG_OFFSET_CAPTURE)) { - return $css; - } - $newCss = ""; - $imports = ""; - $offset = 0; - foreach($matches[0] as $match) { - $newCss .= substr($css, $offset, $match[1] - $offset); - $imports .= $match[0]; - $offset = $match[1] + strlen($match[0]); - } - $newCss .= substr($css, $offset); - return $imports.$newCss; -} - -/** * Very simple CSS optimizer * * @author Andreas Gohr <andi@splitbrain.org> diff --git a/lib/exe/js.php b/lib/exe/js.php index 76238a81b..040b8874d 100644 --- a/lib/exe/js.php +++ b/lib/exe/js.php @@ -86,15 +86,20 @@ function js_out(){ // start output buffering and build the script ob_start(); + $json = new JSON(); // add some global variables print "var DOKU_BASE = '".DOKU_BASE."';"; print "var DOKU_TPL = '".tpl_basedir()."';"; + print "var DOKU_COOKIE_PARAM = " . $json->encode( + array( + 'path' => empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'], + 'secure' => $conf['securecookie'] && is_ssl() + )).";"; // FIXME: Move those to JSINFO print "var DOKU_UHN = ".((int) useHeading('navigation')).";"; print "var DOKU_UHC = ".((int) useHeading('content')).";"; // load JS specific translations - $json = new JSON(); $lang['js']['plugins'] = js_pluginstrings(); $templatestrings = js_templatestrings(); if(!empty($templatestrings)) { diff --git a/lib/plugins/authmysql/lang/en/settings.php b/lib/plugins/authmysql/lang/en/settings.php index 77e4806b9..b95f39701 100644 --- a/lib/plugins/authmysql/lang/en/settings.php +++ b/lib/plugins/authmysql/lang/en/settings.php @@ -19,7 +19,7 @@ $lang['FilterGroup'] = 'SQL clause for filtering users by group membership' $lang['SortOrder'] = 'SQL clause to sort users'; $lang['addUser'] = 'SQL statement to add a new user'; $lang['addGroup'] = 'SQL statement to add a new group'; -$lang['addUserGroup'] = 'SQL statment to add a user to an existing group'; +$lang['addUserGroup'] = 'SQL statement to add a user to an existing group'; $lang['delGroup'] = 'SQL statement to remove a group'; $lang['getUserID'] = 'SQL statement to get the primary key of a user'; $lang['delUser'] = 'SQL statement to delete a user'; @@ -36,4 +36,4 @@ $lang['getGroupID'] = 'SQL statement to get the primary key of a given gro $lang['debug_o_0'] = 'none'; $lang['debug_o_1'] = 'on errors only'; -$lang['debug_o_2'] = 'all SQL queries';
\ No newline at end of file +$lang['debug_o_2'] = 'all SQL queries'; diff --git a/lib/plugins/authpgsql/lang/en/settings.php b/lib/plugins/authpgsql/lang/en/settings.php index e67235cfa..cfb2686cb 100644 --- a/lib/plugins/authpgsql/lang/en/settings.php +++ b/lib/plugins/authpgsql/lang/en/settings.php @@ -18,7 +18,7 @@ $lang['FilterGroup'] = 'SQL clause for filtering users by group membership' $lang['SortOrder'] = 'SQL clause to sort users'; $lang['addUser'] = 'SQL statement to add a new user'; $lang['addGroup'] = 'SQL statement to add a new group'; -$lang['addUserGroup'] = 'SQL statment to add a user to an existing group'; +$lang['addUserGroup'] = 'SQL statement to add a user to an existing group'; $lang['delGroup'] = 'SQL statement to remove a group'; $lang['getUserID'] = 'SQL statement to get the primary key of a user'; $lang['delUser'] = 'SQL statement to delete a user'; diff --git a/lib/scripts/cookie.js b/lib/scripts/cookie.js index 3ad67bfa4..8417d2064 100644 --- a/lib/scripts/cookie.js +++ b/lib/scripts/cookie.js @@ -30,7 +30,7 @@ var DokuCookie = { text.push(encodeURIComponent(key)+'#'+encodeURIComponent(val)); } }); - jQuery.cookie(this.name, text.join('#'), {expires: 365, path: DOKU_BASE}); + jQuery.cookie(this.name, text.join('#'), {expires: 365, path: DOKU_COOKIE_PARAM.path, secure: DOKU_COOKIE_PARAM.secure}); }, /** |