diff --git a/.gitignore b/.gitignore
index 6ed4df6..54562f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,8 @@ runtime/
**/.idea/workspace.xml
**/.idea/tasks.xml
-**/.idea/dataSources*
\ No newline at end of file
+**/.idea/dataSources*
+
+config.php
+
+www/dtest.php
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index c66df00..f5f15f4 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -1,7 +1,13 @@
diff --git a/www/data/css/styles.css b/www/data/css/styles.css index 61cd5e7..fd3e460 100644 --- a/www/data/css/styles.css +++ b/www/data/css/styles.css @@ -1,3 +1,4 @@ +@charset "UTF-8"; /* 400px */ body { background-color: #EEEEEE; @@ -782,12 +783,6 @@ html, body { text-align: left; } -.boxedcontent.alertbox { - background-color: #F52; - font-weight: bold; - text-align: center; -} - .egg_col_x5_0 { fill: #eeeeee; } @@ -858,7 +853,7 @@ html, body { min-width: 300px; } -.consistency_result_ok, .consistency_result_warn, .consistency_result_err { +.consistency_result { min-width: 400px; color: #222222; border: 1px solid #888; @@ -866,6 +861,10 @@ html, body { margin: 1px 0; } +.consistency_result:after { + content: " "; +} + .consistency_result_ok { background: #00FF00; } @@ -878,6 +877,15 @@ html, body { background: #FF0000; } +.consistency_result_intermed { + background: #EEEEEE; +} + +.consistency_result_running { + background: #DDDDDD; + border: 1px solid #000; +} + .admincontent .boxedcontent hr { width: 95%; height: 1px; @@ -887,6 +895,58 @@ html, body { background: -webkit-radial-gradient(circle, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0) 100%); } +.admindberr { + color: #BB2222; +} + +.boxedcontent.alertbox { + background-color: #FF4444; + color: #222222; + border: 1px solid #AA4444; + font-weight: bold; + text-align: center; +} +.boxedcontent.alertbox .bc_data { + padding-top: 2px; + padding-bottom: 2px; +} + +.boxedcontent.warnbox { + background-color: #FFA726; + color: #333333; + border: 1px solid #444444; + font-weight: bold; + text-align: center; +} +.boxedcontent.warnbox .bc_data { + padding-top: 2px; + padding-bottom: 2px; +} + +.boxedcontent.graybox { + background-color: #888888; + color: #222222; + border: 1px solid #444444; + font-weight: bold; + text-align: center; +} +.boxedcontent.graybox .bc_data { + padding-top: 2px; + padding-bottom: 2px; +} + +.boxedcontent.successbox { + background-color: #168B00; + color: #222222; + border: 1px solid #444444; + font-weight: bold; + text-align: center; +} +.boxedcontent.successbox .bc_data { + padding-top: 2px; + padding-bottom: 2px; +} + /* 400px */ #loginform div { display: flex; @@ -1900,6 +1960,7 @@ html, body { /* 400px */ .ev_master { align-self: center; + width: 100%; } @media (min-width: 851px) { .ev_master { @@ -1918,6 +1979,17 @@ html, body { text-align: center; font-size: 25pt; } +.ev_master .ev_statusmore { + color: #333333; + background-color: #BBBBBB; + text-align: left; + padding: 4px; + font-family: Consolas, Monaco, "Courier New", Menlo, monospace; + font-size: small; + overflow-x: auto; + white-space: nowrap; + width: 100%; +} @media (max-width: 767px) { .ev_master .ev_code { font-size: 75pt; diff --git a/www/data/css/styles.min.css b/www/data/css/styles.min.css index e2e9758..5ee24b8 100644 --- a/www/data/css/styles.min.css +++ b/www/data/css/styles.min.css @@ -1,4 +1,4 @@ -body{background-color:#eee;color:#333;font-family:"Times New Roman",serif} +@charset "UTF-8";body{background-color:#eee;color:#333;font-family:"Times New Roman",serif} #content{padding-top:64px;display:flex;justify-content:center;line-height:1.4;flex-direction:column;align-items:center} .content-responsive{margin-left:auto;margin-right:auto} @media(max-width:767px){.content-responsive{width:95%;width:calc(100% - 20px);margin-left:auto;margin-right:auto}} @@ -152,7 +152,6 @@ html,body{margin:0;padding:0;height:100%} .about_circles{display:flex;flex-direction:column} .about_circles a{margin:5px 0} .about_circles .iconbutton_light span{text-align:left} -.boxedcontent.alertbox{background-color:#F52;font-weight:bold;text-align:center} .egg_col_x5_0{fill:#eee} .egg_col_x5_1{fill:#6bcdff} .egg_col_x5_2{fill:#00a1f3} @@ -168,11 +167,23 @@ html,body{margin:0;padding:0;height:100%} .kvl_100 div span:first-child{min-width:100px} .kvl_200 div span:first-child{min-width:200px} .kvl_300 div span:first-child{min-width:300px} -.consistency_result_ok,.consistency_result_warn,.consistency_result_err{min-width:400px;color:#222;border:1px solid #888;padding:0 5px;margin:1px 0} +.consistency_result{min-width:400px;color:#222;border:1px solid #888;padding:0 5px;margin:1px 0} +.consistency_result:after{content:" "} .consistency_result_ok{background:#0f0} .consistency_result_warn{background:#ff0} .consistency_result_err{background:red} +.consistency_result_intermed{background:#eee} +.consistency_result_running{background:#ddd;border:1px solid #000} .admincontent .boxedcontent hr{width:95%;height:1px;border:0;color:#FFFFFF00;background:-moz-radial-gradient(circle,rgba(0,0,0,0.1),rgba(0,0,0,0));background:-webkit-radial-gradient(circle,rgba(0,0,0,0.1) 0,rgba(0,0,0,0) 100%)} +.admindberr{color:#b22} +.boxedcontent.alertbox{background-color:#f44;color:#222;border:1px solid #a44;font-weight:bold;text-align:center} +.boxedcontent.alertbox .bc_data{padding-top:2px;padding-bottom:2px} +.boxedcontent.warnbox{background-color:#ffa726;color:#333;border:1px solid #444;font-weight:bold;text-align:center} +.boxedcontent.warnbox .bc_data{padding-top:2px;padding-bottom:2px} +.boxedcontent.graybox{background-color:#888;color:#222;border:1px solid #444;font-weight:bold;text-align:center} +.boxedcontent.graybox .bc_data{padding-top:2px;padding-bottom:2px} +.boxedcontent.successbox{background-color:#168b00;color:#222;border:1px solid #444;font-weight:bold;text-align:center} +.boxedcontent.successbox .bc_data{padding-top:2px;padding-bottom:2px} #loginform div{display:flex;flex-direction:column} #loginform div button{margin:10px 0;padding:0} .loginerror{display:flex;background:#f44;color:#222;border:1px solid #a44;border-radius:2px;font-weight:bold;padding:0 5px;margin:5px 0 20px 0} @@ -360,10 +371,11 @@ html,body{margin:0;padding:0;height:100%} .wle_date{border-bottom:1px solid transparent;padding:2px;font-size:.8em;font-style:italic} .wle_title{font-weight:bold;font-size:1.2em;text-align:left;margin:2px 0 2px 10px} @media(max-width:767px){.wle_title{font-size:1.25em}} -.ev_master{align-self:center} +.ev_master{align-self:center;width:100%} @media(min-width:851px){.ev_master{padding-bottom:80px}} .ev_master .ev_code{color:#333;text-align:center;font-size:150pt;font-weight:500;font-family:Consolas,Monaco,"Courier New",Menlo,monospace} .ev_master .ev_msg{color:#888;text-align:center;font-size:25pt} +.ev_master .ev_statusmore{color:#333;background-color:#bbb;text-align:left;padding:4px;font-family:Consolas,Monaco,"Courier New",Menlo,monospace;font-size:small;overflow-x:auto;white-space:nowrap;width:100%} @media(max-width:767px){ .ev_master .ev_code{font-size:75pt} .ev_master .ev_msg{font-size:15pt} diff --git a/www/data/css/styles_about.scss b/www/data/css/styles_about.scss index 24a1bdb..6c6acbc 100644 --- a/www/data/css/styles_about.scss +++ b/www/data/css/styles_about.scss @@ -112,12 +112,6 @@ } -.boxedcontent.alertbox { - background-color: #F52; - font-weight: bold; - text-align: center; -} - @if $CFG_EGG_THEME == 'standard' { // ==== STANDARD ==== diff --git a/www/data/css/styles_admin.scss b/www/data/css/styles_admin.scss index 43495f4..cdc741b 100644 --- a/www/data/css/styles_admin.scss +++ b/www/data/css/styles_admin.scss @@ -41,7 +41,7 @@ .kvl_200 div span:first-child { min-width: 200px; } .kvl_300 div span:first-child { min-width: 300px; } -.consistency_result_ok, .consistency_result_warn, .consistency_result_err { +.consistency_result { min-width: 400px; color: $COL_ADMIN_STATUS_FG; border: $COL_ADMIN_STATUS_BORDER; @@ -49,9 +49,13 @@ margin: 1px 0; } -.consistency_result_ok { background: $COL_ADMIN_OK; } -.consistency_result_warn { background: $COL_ADMIN_WARN; } -.consistency_result_err { background: $COL_ADMIN_ERROR; } +.consistency_result:after { content: '\00a0' } + +.consistency_result_ok { background: $COL_ADMIN_OK; } +.consistency_result_warn { background: $COL_ADMIN_WARN; } +.consistency_result_err { background: $COL_ADMIN_ERROR; } +.consistency_result_intermed { background: $COL_ADMIN_INTERMED; } +.consistency_result_running { background: $COL_ADMIN_RUNNING; border: $COL_ADMIN_STATUS_BORDER_ACTIVE; } .admincontent .boxedcontent hr { @@ -61,4 +65,54 @@ color: $COL_TRANSPARENT; background: -moz-radial-gradient( circle, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.0)); background: -webkit-radial-gradient(circle, rgba(0, 0, 0, 0.1) 0%,rgba(0, 0, 0, 0.0) 100%); -} \ No newline at end of file +} + +.admindberr { color: $COL_ADMIN_STATUS_DB_ERROR; } + +.boxedcontent.alertbox { + background-color: $COL_TOAST_ERROR_BG; + color: $COL_TOAST_ERROR_FG; + border: $COL_TOAST_ERROR_BORDER; + font-weight: bold; + text-align: center; + .bc_data { + padding-top: 2px; + padding-bottom: 2px; + } +} + +.boxedcontent.warnbox { + background-color: $COL_TOAST_WARN_BG; + color: $COL_TOAST_WARN_FG; + border: $COL_TOAST_WARN_BORDER; + font-weight: bold; + text-align: center; + .bc_data { + padding-top: 2px; + padding-bottom: 2px; + } +} + +.boxedcontent.graybox { + background-color: $COL_TOAST_GRAY_BG; + color: $COL_TOAST_GRAY_FG; + border: $COL_TOAST_GRAY_BORDER; + font-weight: bold; + text-align: center; + .bc_data { + padding-top: 2px; + padding-bottom: 2px; + } +} + +.boxedcontent.successbox { + background-color: $COL_TOAST_SUCCESS_BG; + color: $COL_TOAST_SUCCESS_FG; + border: $COL_TOAST_SUCCESS_BORDER; + font-weight: bold; + text-align: center; + .bc_data { + padding-top: 2px; + padding-bottom: 2px; + } +} diff --git a/www/data/css/styles_config.scss b/www/data/css/styles_config.scss index 21e7ffd..8276b5e 100644 --- a/www/data/css/styles_config.scss +++ b/www/data/css/styles_config.scss @@ -115,9 +115,21 @@ $COL_FOOTER_FG: #CCCCCC; // ------------------------------------ -$COL_TOAST_ERROR_FG: #222222; -$COL_TOAST_ERROR_BG: #FF4444; -$COL_TOAST_ERROR_BORDER: 1px solid #AA4444; +$COL_TOAST_ERROR_FG: #222222; +$COL_TOAST_ERROR_BG: #FF4444; +$COL_TOAST_ERROR_BORDER: 1px solid #AA4444; + +$COL_TOAST_WARN_FG: #333333; +$COL_TOAST_WARN_BG: #FFA726; +$COL_TOAST_WARN_BORDER: $LAYER1_BORDER; + +$COL_TOAST_GRAY_FG: #222222; +$COL_TOAST_GRAY_BG: #888888; +$COL_TOAST_GRAY_BORDER: $LAYER1_BORDER; + +$COL_TOAST_SUCCESS_FG: #222222; +$COL_TOAST_SUCCESS_BG: #168B00; +$COL_TOAST_SUCCESS_BORDER: $LAYER1_BORDER; // ------------------------------------ @@ -149,12 +161,17 @@ $AOC_DESCRIPTION_BG: #333333; // ------------------------------------ -$COL_ADMIN_OK: #00FF00; -$COL_ADMIN_WARN: #FFFF00; -$COL_ADMIN_ERROR: #FF0000; +$COL_ADMIN_OK: #00FF00; +$COL_ADMIN_WARN: #FFFF00; +$COL_ADMIN_ERROR: #FF0000; +$COL_ADMIN_INTERMED: #EEEEEE; +$COL_ADMIN_RUNNING: #DDDDDD; $COL_ADMIN_STATUS_FG: #222222; $COL_ADMIN_STATUS_BORDER: 1px solid #888; +$COL_ADMIN_STATUS_BORDER_ACTIVE: 1px solid #000; + +$COL_ADMIN_STATUS_DB_ERROR: #BB2222; // ------------------------------------ ------------------------------------ diff --git a/www/data/css/styles_errorview.scss b/www/data/css/styles_errorview.scss index cf45298..38cb153 100644 --- a/www/data/css/styles_errorview.scss +++ b/www/data/css/styles_errorview.scss @@ -3,6 +3,7 @@ .ev_master { align-self: center; + width: 100%; @include rdmedia_range(2,4) {padding-bottom: 80px;} @@ -20,6 +21,20 @@ font-size: 25pt; } + .ev_statusmore { + color: $LAYER1_FG; + background-color: $LAYER1_BG_DARKER; + text-align: left; + padding: 4px; + font-family: $FONT_CODE; + font-size: small; + + overflow-x: auto; + white-space: nowrap; + + width: 100%; + } + @include rdmedia(0) { .ev_code { font-size: 75pt; } .ev_msg { font-size: 15pt; } diff --git a/www/data/javascript/admin.js b/www/data/javascript/admin.js index 0a54c76..47c5fdd 100644 --- a/www/data/javascript/admin.js +++ b/www/data/javascript/admin.js @@ -69,4 +69,51 @@ function startAjaxReplace(target, url) }, async: true }); -} \ No newline at end of file +} + +function refreshConsistencyDisplay(skip) +{ + let i = 0; + for (let apibutton of $('.consistence_ajax_handler').toArray()) + { + if (i++ !== skip) continue; + + const filter = $(apibutton).data('filter'); + + $(apibutton).removeClass('consistency_result_intermed'); + $(apibutton).addClass('consistency_result_running'); + + $.ajax('/api/site::selftest?filter=' + filter) + .done((data, status, xhr) => + { + let json = JSON.parse(data); + $(apibutton).removeClass('consistency_result_intermed'); + $(apibutton).removeClass('consistency_result_running'); + + if (json.result === 0) $(apibutton).addClass('consistency_result_ok'); + if (json.result === 1) $(apibutton).addClass('consistency_result_warn'); + if (json.result === 2) $(apibutton).addClass('consistency_result_err'); + + $(apibutton).text(json.message); + $(apibutton).attr('title', json.long); + + setTimeout(() => refreshConsistencyDisplay(skip+1), 10); + }) + .fail((xhr, status, err) => + { + $(apibutton).removeClass('consistency_result_intermed'); + $(apibutton).removeClass('consistency_result_running'); + + $(apibutton).addClass('consistency_result_err'); + $(apibutton).text(err); + + setTimeout(() => refreshConsistencyDisplay(skip+1), 10); + }); + + } +} + +$(function() +{ + setTimeout(() => refreshConsistencyDisplay(0), 200); +}); \ No newline at end of file diff --git a/www/extern/Parsedown.php b/www/extern/Parsedown.php index 757666e..1b9d6d5 100644 --- a/www/extern/Parsedown.php +++ b/www/extern/Parsedown.php @@ -17,7 +17,7 @@ class Parsedown { # ~ - const version = '1.6.0'; + const version = '1.7.4'; # ~ @@ -75,6 +75,32 @@ class Parsedown protected $urlsLinked = true; + function setSafeMode($safeMode) + { + $this->safeMode = (bool) $safeMode; + + return $this; + } + + protected $safeMode; + + protected $safeLinksWhitelist = array( + 'http://', + 'https://', + 'ftp://', + 'ftps://', + 'mailto:', + 'data:image/png;base64,', + 'data:image/gif;base64,', + 'data:image/jpeg;base64,', + 'irc:', + 'ircs:', + 'git:', + 'ssh:', + 'news:', + 'steam:', + ); + # # Lines # @@ -342,8 +368,6 @@ class Parsedown { $text = $Block['element']['text']['text']; - $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); - $Block['element']['text']['text'] = $text; return $Block; @@ -354,7 +378,7 @@ class Parsedown protected function blockComment($Line) { - if ($this->markupEscaped) + if ($this->markupEscaped or $this->safeMode) { return; } @@ -396,7 +420,7 @@ class Parsedown protected function blockFencedCode($Line) { - if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches)) + if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([^`]+)?[ ]*$/', $Line['text'], $matches)) { $Element = array( 'name' => 'code', @@ -405,7 +429,21 @@ class Parsedown if (isset($matches[1])) { - $class = 'language-'.$matches[1]; + /** + * https://www.w3.org/TR/2011/WD-html5-20110525/elements.html#classes + * Every HTML element may have a class attribute specified. + * The attribute, if specified, must have a value that is a set + * of space-separated tokens representing the various classes + * that the element belongs to. + * [...] + * The space characters, for the purposes of this specification, + * are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), + * U+000A LINE FEED (LF), U+000C FORM FEED (FF), and + * U+000D CARRIAGE RETURN (CR). + */ + $language = substr($matches[1], 0, strcspn($matches[1], " \t\n\f\r")); + + $class = 'language-'.$language; $Element['attributes'] = array( 'class' => $class, @@ -457,8 +495,6 @@ class Parsedown { $text = $Block['element']['text']['text']; - $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); - $Block['element']['text']['text'] = $text; return $Block; @@ -515,10 +551,10 @@ class Parsedown ), ); - if($name === 'ol') + if($name === 'ol') { $listStart = stristr($matches[0], '.', true); - + if($listStart !== '1') { $Block['element']['attributes'] = array('start' => $listStart); @@ -547,6 +583,8 @@ class Parsedown { $Block['li']['text'] []= ''; + $Block['loose'] = true; + unset($Block['interrupted']); } @@ -595,6 +633,22 @@ class Parsedown } } + protected function blockListComplete(array $Block) + { + if (isset($Block['loose'])) + { + foreach ($Block['element']['text'] as &$li) + { + if (end($li['text']) !== '') + { + $li['text'] []= ''; + } + } + } + + return $Block; + } + # # Quote @@ -678,7 +732,7 @@ class Parsedown protected function blockMarkup($Line) { - if ($this->markupEscaped) + if ($this->markupEscaped or $this->safeMode) { return; } @@ -997,7 +1051,7 @@ class Parsedown # ~ # - public function line($text) + public function line($text, $nonNestables=array()) { $markup = ''; @@ -1013,6 +1067,13 @@ class Parsedown foreach ($this->InlineTypes[$marker] as $inlineType) { + # check to see if the current inline type is nestable in the current context + + if ( ! empty($nonNestables) and in_array($inlineType, $nonNestables)) + { + continue; + } + $Inline = $this->{'inline'.$inlineType}($Excerpt); if ( ! isset($Inline)) @@ -1034,6 +1095,13 @@ class Parsedown $Inline['position'] = $markerPosition; } + # cause the new element to 'inherit' our non nestables + + foreach ($nonNestables as $non_nestable) + { + $Inline['element']['nonNestables'][] = $non_nestable; + } + # the text that comes before the inline $unmarkedText = substr($text, 0, $Inline['position']); @@ -1074,7 +1142,6 @@ class Parsedown if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(? 'a', 'handler' => 'line', + 'nonNestables' => array('Url', 'Link'), 'text' => null, 'attributes' => array( 'href' => null, @@ -1253,8 +1321,6 @@ class Parsedown $Element['attributes']['title'] = $Definition['title']; } - $Element['attributes']['href'] = str_replace(array('&', '<'), array('&', '<'), $Element['attributes']['href']); - return array( 'extent' => $extent, 'element' => $Element, @@ -1263,7 +1329,7 @@ class Parsedown protected function inlineMarkup($Excerpt) { - if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false) + if ($this->markupEscaped or $this->safeMode or strpos($Excerpt['text'], '>') === false) { return; } @@ -1343,14 +1409,16 @@ class Parsedown if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) { + $url = $matches[0][0]; + $Inline = array( 'extent' => strlen($matches[0][0]), 'position' => $matches[0][1], 'element' => array( 'name' => 'a', - 'text' => $matches[0][0], + 'text' => $url, 'attributes' => array( - 'href' => $matches[0][0], + 'href' => $url, ), ), ); @@ -1363,7 +1431,7 @@ class Parsedown { if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches)) { - $url = str_replace(array('&', '<'), array('&', '<'), $matches[1]); + $url = $matches[1]; return array( 'extent' => strlen($matches[0]), @@ -1401,6 +1469,11 @@ class Parsedown protected function element(array $Element) { + if ($this->safeMode) + { + $Element = $this->sanitiseElement($Element); + } + $markup = '<'.$Element['name']; if (isset($Element['attributes'])) @@ -1412,21 +1485,45 @@ class Parsedown continue; } - $markup .= ' '.$name.'="'.$value.'"'; + $markup .= ' '.$name.'="'.self::escape($value).'"'; } } + $permitRawHtml = false; + if (isset($Element['text'])) + { + $text = $Element['text']; + } + // very strongly consider an alternative if you're writing an + // extension + elseif (isset($Element['rawHtml'])) + { + $text = $Element['rawHtml']; + $allowRawHtmlInSafeMode = isset($Element['allowRawHtmlInSafeMode']) && $Element['allowRawHtmlInSafeMode']; + $permitRawHtml = !$this->safeMode || $allowRawHtmlInSafeMode; + } + + if (isset($text)) { $markup .= '>'; + if (!isset($Element['nonNestables'])) + { + $Element['nonNestables'] = array(); + } + if (isset($Element['handler'])) { - $markup .= $this->{$Element['handler']}($Element['text']); + $markup .= $this->{$Element['handler']}($text, $Element['nonNestables']); + } + elseif (!$permitRawHtml) + { + $markup .= self::escape($text, true); } else { - $markup .= $Element['text']; + $markup .= $text; } $markup .= ''.$Element['name'].'>'; @@ -1485,10 +1582,77 @@ class Parsedown return $markup; } + protected function sanitiseElement(array $Element) + { + static $goodAttribute = '/^[a-zA-Z0-9][a-zA-Z0-9-_]*+$/'; + static $safeUrlNameToAtt = array( + 'a' => 'href', + 'img' => 'src', + ); + + if (isset($safeUrlNameToAtt[$Element['name']])) + { + $Element = $this->filterUnsafeUrlInAttribute($Element, $safeUrlNameToAtt[$Element['name']]); + } + + if ( ! empty($Element['attributes'])) + { + foreach ($Element['attributes'] as $att => $val) + { + # filter out badly parsed attribute + if ( ! preg_match($goodAttribute, $att)) + { + unset($Element['attributes'][$att]); + } + # dump onevent attribute + elseif (self::striAtStart($att, 'on')) + { + unset($Element['attributes'][$att]); + } + } + } + + return $Element; + } + + protected function filterUnsafeUrlInAttribute(array $Element, $attribute) + { + foreach ($this->safeLinksWhitelist as $scheme) + { + if (self::striAtStart($Element['attributes'][$attribute], $scheme)) + { + return $Element; + } + } + + $Element['attributes'][$attribute] = str_replace(':', '%3A', $Element['attributes'][$attribute]); + + return $Element; + } + # # Static Methods # + protected static function escape($text, $allowQuotes = false) + { + return htmlspecialchars($text, $allowQuotes ? ENT_NOQUOTES : ENT_QUOTES, 'UTF-8'); + } + + protected static function striAtStart($string, $needle) + { + $len = strlen($needle); + + if ($len > strlen($string)) + { + return false; + } + else + { + return strtolower(substr($string, 0, $len)) === strtolower($needle); + } + } + static function instance($name = 'default') { if (isset(self::$instances[$name])) diff --git a/www/extern/ParsedownExtra.php b/www/extern/ParsedownExtra.php index be6966d..632ba84 100644 --- a/www/extern/ParsedownExtra.php +++ b/www/extern/ParsedownExtra.php @@ -17,13 +17,13 @@ class ParsedownExtra extends Parsedown { # ~ - const version = '0.7.0'; + const version = '0.8.1'; # ~ function __construct() { - if (parent::version < '1.5.0') + if (version_compare(parent::version, '1.7.4') < 0) { throw new Exception('ParsedownExtra requires a later version of Parsedown'); } @@ -206,6 +206,10 @@ class ParsedownExtra extends Parsedown { $Block = parent::blockHeader($Line); + if (! isset($Block)) { + return null; + } + if (preg_match('/[ #]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE)) { $attributeString = $matches[1][0]; @@ -238,6 +242,10 @@ class ParsedownExtra extends Parsedown { $Block = parent::blockSetextHeader($Line, $Block); + if (! isset($Block)) { + return null; + } + if (preg_match('/[ ]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE)) { $attributeString = $matches[1][0]; @@ -302,6 +310,10 @@ class ParsedownExtra extends Parsedown { $Link = parent::inlineLink($Excerpt); + if (! isset($Link)) { + return null; + } + $remainder = substr($Excerpt['text'], $Link['extent']); if (preg_match('/^[ ]*{('.$this->regexAttribute.'+)}/', $remainder, $matches)) @@ -420,7 +432,7 @@ class ParsedownExtra extends Parsedown $Element['text'][1]['text'] []= array( 'name' => 'li', 'attributes' => array('id' => 'fn:'.$definitionId), - 'text' => "\n".$text."\n", + 'rawHtml' => "\n".$text."\n", ); } diff --git a/www/extern/egg/EGGDatabase.php b/www/extern/egg/EGGDatabase.php index 67ec66d..613d172 100644 --- a/www/extern/egg/EGGDatabase.php +++ b/www/extern/egg/EGGDatabase.php @@ -69,9 +69,7 @@ class EGGDatabase public function sql_query_assoc(string $query) { - $r = $this->pdo->query($query)->fetchAll(PDO::FETCH_ASSOC); - - return $r; + return $this->pdo->query($query)->fetchAll(PDO::FETCH_ASSOC); } public function sql_query_assoc_prep(string $query, array $params) @@ -84,9 +82,7 @@ class EGGDatabase } $stmt->execute(); - $r = $stmt->fetchAll(PDO::FETCH_ASSOC); - - return $r; + return $stmt->fetchAll(PDO::FETCH_ASSOC); } public function sql_exec_prep(string $query, array $params) diff --git a/www/extern/egg/RemoteSource.php b/www/extern/egg/RemoteSource.php index 558320d..bd58fa8 100644 --- a/www/extern/egg/RemoteSource.php +++ b/www/extern/egg/RemoteSource.php @@ -227,7 +227,7 @@ abstract class StandardGitConnection implements IRemoteSource $target = $branch->Head; $next_sha = [ $branch->HeadFromAPI ]; - $visited = [ $branch->HeadFromAPI ]; + $visited = [ ]; $json = $this->queryCommits($repo->Name, $branch->Name, $next_sha[0]); @@ -257,6 +257,7 @@ abstract class StandardGitConnection implements IRemoteSource if (count($newcommits) === 0) { $this->logger->proclog("Found no new commits for: [" . $this->name . "|" . $repo->Name . "|" . $branch->Name . "] (HEAD at {" . substr($branch->HeadFromAPI, 0, 8) . "})"); + if ($branch->HeadFromAPI !== $branch->Head) $db->setBranchHead($branch, $branch->HeadFromAPI); return []; } @@ -295,7 +296,11 @@ abstract class StandardGitConnection implements IRemoteSource $db->deleteAllCommits($branch); - if (count($newcommits) === 0) return []; + if (count($newcommits) === 0) + { + if ($branch->HeadFromAPI !== $branch->Head) $db->setBranchHead($branch, $branch->HeadFromAPI); + return []; + } $db->insertNewCommits($this->name, $repo, $branch, $newcommits); $db->setBranchHead($branch, $branch->HeadFromAPI); diff --git a/www/fragments/blogview_aoc_list.php b/www/fragments/blogview_aoc_list.php index ad487af..b5a0eb9 100644 --- a/www/fragments/blogview_aoc_list.php +++ b/www/fragments/blogview_aoc_list.php @@ -1,8 +1,17 @@ + + |
Welcome to my Mikescher.com
+This is my personal homepage, I use it to upload programs I have written, web serials I have style-setted and sometimes for a little bit of blogging.
+Its mostly just a collection of stuff I wanted to put only, but I guess thats the core of most personal homepages
-Welcome to my Mikescher.com
-This is my personal homepage, I use it to upload programs I have written, web serials I have style-setted and sometimes for a little bit of blogging.
-Its mostly just a collection of stuff I wanted to put only, but I guess thats the core of most personal homepages
+
- These are some books I read but that do not have an official print version.
- So I type-setted them myself (mostly in LyX) and printed them online.
- I do not own the rights of any of these books.
- The LyX files and generated PDF's are public and everyone who wants can print them on his own.
-
+ These are some books I read but that do not have an official print version.
+ So I type-setted them myself (mostly in LyX) and printed them online.
+ I do not own the rights of any of these books.
+ The LyX files and generated PDF's are public and everyone who wants can print them on his own.
+