12 Commits

Author SHA1 Message Date
沈唁
4be93f2741 Fix missing mysqli_connect_errno (#1346) 2022-03-28 12:11:24 +08:00
joyqi
6100695d87 fix db exception 2022-03-25 15:31:57 +08:00
fen
0bdf8721e1 add ignore 2022-03-25 12:08:22 +08:00
沈唁
ce7af58367 Optimize code (#1342) 2022-03-24 17:46:03 +08:00
joyqi
1b673e06ff fix typecho/Dockerfile#9 2022-03-22 14:24:14 +08:00
joyqi
0edb48fae0 fix #1335, close #1337 2022-03-16 21:05:22 +08:00
沈唁
17fcb2f08b Fix undefined Typecho\Db\Adapter_Exception (#1334) 2022-03-15 16:09:32 +08:00
joyqi
5f943d48b5 fix #1329 2022-02-25 21:16:12 +08:00
joyqi
b23277267a fix #1328 2022-02-24 23:21:35 +08:00
沈唁
b0d78a81dc Fix #1326 (#1327) 2022-02-21 21:51:13 +08:00
沈唁
f34d14280d Fix compatibility with PHP 8.1 (#1324)
* Fix compatibility with PHP 8.1

PHP Deprecated:  htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in typecho/var/Widget/Archive.php on line 1292

* Fix login

* Fix write

* Fix manage

* Fix PHP Deprecated
2022-02-15 11:10:47 +08:00
沈唁
13dc5e87dd Fix #1322 (#1323)
Great work!
2022-02-15 11:10:15 +08:00
19 changed files with 55 additions and 39 deletions

1
.gitignore vendored
View File

@@ -24,6 +24,7 @@
*.sublime*
.sass-cache
config.rb
prepros.config
/config.inc.php
/usr/uploads/
/usr/*.db

View File

@@ -4,7 +4,7 @@ include 'common.php';
if ($user->hasLogin()) {
$response->redirect($options->adminUrl);
}
$rememberName = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_name'));
$rememberName = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_name', ''));
\Typecho\Cookie::delete('__typecho_remember_name');
$bodyClass = 'body-100';
@@ -25,7 +25,7 @@ include 'header.php';
</p>
<p class="submit">
<button type="submit" class="btn btn-l w-100 primary"><?php _e('登录'); ?></button>
<input type="hidden" name="referer" value="<?php echo htmlspecialchars($request->get('referer')); ?>" />
<input type="hidden" name="referer" value="<?php echo htmlspecialchars($request->get('referer') ?? ''); ?>" />
</p>
<p>
<label for="remember">

View File

@@ -69,7 +69,7 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Ty
(isset($request->status) ? 'status=' . htmlspecialchars($request->get('status')) : '') .
(isset($request->cid) ? (isset($request->status) ? '&' : '') . 'cid=' . htmlspecialchars($request->get('cid')) : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords ?? ''); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<?php if(isset($request->status)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('status')); ?>" name="status" />
<?php endif; ?>

View File

@@ -36,7 +36,7 @@ $attachments = \Widget\Contents\Attachment\Admin::alloc();
<a href="<?php $options->adminUrl('manage-medias.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo htmlspecialchars($request->keywords); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
value="<?php echo htmlspecialchars($request->keywords ?? ''); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>

View File

@@ -39,7 +39,7 @@ $pages = \Widget\Contents\Page\Admin::alloc();
<a href="<?php $options->adminUrl('manage-pages.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords"/>
value="<?php echo htmlspecialchars($request->keywords ?? ''); ?>" name="keywords"/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>

View File

@@ -31,7 +31,7 @@ $users = \Widget\Users\Admin::alloc();
<a href="<?php $options->adminUrl('manage-users.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords"/>
value="<?php echo htmlspecialchars($request->keywords ?? ''); ?>" name="keywords"/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>

View File

@@ -34,7 +34,7 @@ include 'menu.php';
if ($page->have()) {
$permalink = str_replace('{cid}', $page->cid, $permalink);
}
$input = '<input type="text" id="slug" name="slug" autocomplete="off" value="' . htmlspecialchars($page->slug) . '" class="mono" />';
$input = '<input type="text" id="slug" name="slug" autocomplete="off" value="' . htmlspecialchars($page->slug ?? '') . '" class="mono" />';
?>
<p class="mono url-slug">
<label for="slug" class="sr-only"><?php _e('网址缩略名'); ?></label>
@@ -43,7 +43,7 @@ include 'menu.php';
<p>
<label for="text" class="sr-only"><?php _e('页面内容'); ?></label>
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text"
name="text" class="w-100 mono"><?php echo htmlspecialchars($page->text); ?></textarea>
name="text" class="w-100 mono"><?php echo htmlspecialchars($page->text ?? ''); ?></textarea>
</p>
<?php include 'custom-fields.php'; ?>

View File

@@ -38,7 +38,7 @@ include 'menu.php';
$post->cid, $post->category, $post->year, $post->month, $post->day
], $permalink);
}
$input = '<input type="text" id="slug" name="slug" autocomplete="off" value="' . htmlspecialchars($post->slug) . '" class="mono" />';
$input = '<input type="text" id="slug" name="slug" autocomplete="off" value="' . htmlspecialchars($post->slug ?? '') . '" class="mono" />';
?>
<p class="mono url-slug">
<label for="slug" class="sr-only"><?php _e('网址缩略名'); ?></label>
@@ -47,7 +47,7 @@ include 'menu.php';
<p>
<label for="text" class="sr-only"><?php _e('文章内容'); ?></label>
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text"
name="text" class="w-100 mono"><?php echo htmlspecialchars($post->text); ?></textarea>
name="text" class="w-100 mono"><?php echo htmlspecialchars($post->text ?? ''); ?></textarea>
</p>
<?php include 'custom-fields.php'; ?>
@@ -134,7 +134,7 @@ include 'menu.php';
<option
value="hidden"<?php if ($post->status == 'hidden'): ?> selected<?php endif; ?>><?php _e('隐藏'); ?></option>
<option
value="password"<?php if (strlen($post->password) > 0): ?> selected<?php endif; ?>><?php _e('密码保护'); ?></option>
value="password"<?php if (strlen($post->password ?? '') > 0): ?> selected<?php endif; ?>><?php _e('密码保护'); ?></option>
<option
value="private"<?php if ($post->status == 'private'): ?> selected<?php endif; ?>><?php _e('私密'); ?></option>
<?php endif; ?>
@@ -142,7 +142,7 @@ include 'menu.php';
value="waiting"<?php if (!$user->pass('editor', true) || $post->status == 'waiting'): ?> selected<?php endif; ?>><?php _e('待审核'); ?></option>
</select>
</p>
<p id="post-password"<?php if (strlen($post->password) == 0): ?> class="hidden"<?php endif; ?>>
<p id="post-password"<?php if (strlen($post->password ?? '') == 0): ?> class="hidden"<?php endif; ?>>
<label for="protect-pwd" class="sr-only">内容密码</label>
<input type="text" name="password" id="protect-pwd" class="text-s"
value="<?php $post->password(); ?>" size="16"

View File

@@ -1021,6 +1021,9 @@ function install_step_2_perform()
case 'SQLite':
$error = (new \Typecho\Validate())
->addRule('dbFile', 'required', _t('确认您的配置'))
->addRule('dbFile', function (string $path) {
return !!preg_match("/^(\/[_a-z0-9-]+)*[a-z0-9]+\.[a-z0-9]{2,}$/i", $path);
}, _t('确认您的配置'))
->run($config);
break;
default:
@@ -1041,6 +1044,10 @@ function install_step_2_perform()
$dbConfig['port'] = intval($dbConfig['port']);
}
if (isset($dbConfig['file']) && preg_match("/^[a-z0-9]+\.[a-z0-9]{2,}$/i", $dbConfig['file'])) {
$dbConfig['file'] = __DIR__ . '/usr/' . $dbConfig['file'];
}
// check config file
if ($config['dbNext'] == 'config' && !install_check('config')) {
$code = install_config_file($config['dbAdapter'], $config['dbPrefix'], $dbConfig, true);
@@ -1051,10 +1058,10 @@ function install_step_2_perform()
$installDb = new \Typecho\Db($config['dbAdapter'], $config['dbPrefix']);
$installDb->addServer($dbConfig, \Typecho\Db::READ | \Typecho\Db::WRITE);
$installDb->query('SELECT 1=1');
} catch (\Typecho\Db\Adapter_Exception $e) {
} catch (\Typecho\Db\Adapter\ConnectionException $e) {
install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装'));
} catch (\Typecho\Db\Exception $e) {
install_raise_error(_t('安装程序捕捉到以下错误: " %s ". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
install_raise_error(_t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
}
$code = install_config_file($config['dbAdapter'], $config['dbPrefix'], $dbConfig);
@@ -1084,12 +1091,14 @@ function install_step_2_perform()
try {
foreach ($tables as $table) {
if ($type == 'Mysql') {
$installDb->query("DROP TABLE IF EXISTS `{$table}`");
} elseif ($type == 'Pgsql') {
$installDb->query("DROP TABLE {$table}");
} elseif ($type == 'SQLite') {
$installDb->query("DROP TABLE {$table}");
switch ($type) {
case 'Mysql':
$installDb->query("DROP TABLE IF EXISTS `{$table}`");
break;
case 'Pgsql':
case 'SQLite':
$installDb->query("DROP TABLE {$table}");
break;
}
}
} catch (\Typecho\Db\Exception $e) {

View File

@@ -230,10 +230,10 @@ namespace Typecho {
//覆盖原始错误信息
$message = 'Database Server Error';
if ($exception instanceof \Typecho\Db\Adapter\SQLException) {
if ($exception instanceof \Typecho\Db\Adapter\ConnectionException) {
$code = 503;
$message = 'Error establishing a database connection';
} elseif ($exception instanceof \Typecho\Db\Query\Exception) {
} elseif ($exception instanceof \Typecho\Db\Adapter\SQLException) {
$message = 'Database Query Error';
}
}

View File

@@ -102,6 +102,7 @@ class Config implements \Iterator, \ArrayAccess
* @access public
* @return mixed
*/
#[\ReturnTypeWillChange]
public function current()
{
return current($this->currentConfig);
@@ -124,6 +125,7 @@ class Config implements \Iterator, \ArrayAccess
* @access public
* @return mixed
*/
#[\ReturnTypeWillChange]
public function key()
{
return key($this->currentConfig);
@@ -222,6 +224,7 @@ class Config implements \Iterator, \ArrayAccess
* @param mixed $offset
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return $this->currentConfig[$offset] ?? null;

View File

@@ -64,7 +64,7 @@ class Mysqli implements Adapter
}
/** 数据库异常 */
throw new ConnectionException("Couldn't connect to database.");
throw new ConnectionException("Couldn't connect to database.", mysqli_connect_errno());
}
/**

View File

@@ -305,7 +305,7 @@ class Request
return $this->pathInfo;
}
//参考Zend Framework对pahtinfo的处理, 更好的兼容性
//参考Zend Framework对pathinfo的处理, 更好的兼容性
$pathInfo = null;
//处理requestUri

View File

@@ -209,7 +209,7 @@ class Response
$timeout = 1;
}
setrawcookie($key, rawurlencode($value), $timeout, $path, $domain);
setrawcookie($key, rawurlencode($value), $timeout, $path, $domain ?? '');
}
}

View File

@@ -221,7 +221,7 @@ class Validate
* @access public
*
* @param string $key 数值键值
* @param string|array $rule 规则名称
* @param string|callable $rule 规则名称
* @param string $message 错误字符串
*
* @return $this
@@ -271,12 +271,12 @@ class Validate
foreach ($rules as $key => $rule) {
$this->key = $key;
$data[$key] = (is_array($data[$key]) ? 0 == count($data[$key])
: 0 == strlen($data[$key])) ? null : $data[$key];
: 0 == strlen($data[$key] ?? '')) ? null : $data[$key];
foreach ($rule as $params) {
$method = $params[0];
if ('required' != $method && 'confirm' != $method && 0 == strlen($data[$key])) {
if ('required' != $method && 'confirm' != $method && 0 == strlen($data[$key] ?? '')) {
continue;
}
@@ -284,7 +284,7 @@ class Validate
$params[1] = $data[$key];
$params = array_slice($params, 1);
if (!call_user_func_array(is_array($method) ? $method : [$this, $method], $params)) {
if (!call_user_func_array(is_callable($method) ? $method : [$this, $method], $params)) {
$result[$key] = $message;
break;
}
@@ -319,11 +319,9 @@ class Validate
*
* @access public
*
* @param string|null $str 待处理的字符串
*
* @return boolean
*/
public function required(?string $str): bool
public function required(): bool
{
return !empty($this->data[$this->key]);
}

View File

@@ -190,19 +190,24 @@ abstract class Widget
/**
* alloc widget instance with alias
*
* @param string $alias
* @param string|null $alias
* @param mixed $params
* @param mixed $request
* @param bool|callable $disableSandboxOrCallback
* @return $this
*/
public static function allocWithAlias(
string $alias,
?string $alias,
$params = null,
$request = null,
$disableSandboxOrCallback = true
): Widget {
return self::widget(static::class . '@' . $alias, $params, $request, $disableSandboxOrCallback);
return self::widget(
static::class . (isset($alias) ? '@' . $alias : ''),
$params,
$request,
$disableSandboxOrCallback
);
}
/**

View File

@@ -1289,7 +1289,7 @@ class Archive extends Contents
if ($return) {
return $value;
} else {
echo htmlspecialchars($value);
echo htmlspecialchars($value ?? '');
}
}
@@ -1498,7 +1498,7 @@ class Archive extends Contents
'date' => $this->created,
'link' => $this->permalink,
'author' => $this->author,
'excerpt' => $this->description,
'excerpt' => $this->___description(),
'comments' => $this->commentsNum,
'commentsFeedUrl' => $feedUrl,
'suffix' => $suffix

View File

@@ -275,7 +275,7 @@ class Edit extends Comments implements ActionInterface
}
/** 评论插件接口 */
self::pluginHandle()->edit($comment, $this);
$comment = self::pluginHandle()->edit($comment, $this);
/** 更新评论 */
$this->update($comment, $this->db->sql()->where('coid = ?', $coid));

View File

@@ -268,7 +268,7 @@ class User extends Users
} else {
//防止循环重定向
$this->response->redirect(defined('__TYPECHO_ADMIN__') ? $this->options->loginUrl .
(0 === strpos($this->request->getReferer(), $this->options->loginUrl) ? '' :
(0 === strpos($this->request->getReferer() ?? '', $this->options->loginUrl) ? '' :
'?referer=' . urlencode($this->request->makeUriByRequest())) : $this->options->siteUrl, false);
}
}