#1989·typecho

分页参数page过大导致数据库查询错误

Author: CinderliaCreated Jun 17, 2026Updated Jul 11, 2026
Labelsbug
  • 问题描述

将page参数设置成一个非常大的值,比如说page=9223372036854775807时,页面会返回一个数据库错误

Image

而当page=922337203685477580时,则不会报错

Image
  • 问题分析

参数获取位置:var/Widget/Users/Admin.php 第57行

php
$this->currentPage = $this->request->filter('int')->get('page', 1);

分页计算位置:var/Typecho/Db/Query.php 第326-332行

php
public function page($page, $pageSize): Query
{
    $pageSize = intval($pageSize);
    $this->sqlPreBuild['limit'] = $pageSize;
    $this->sqlPreBuild['offset'] = (max(intval($page), 1) - 1) * $pageSize;
    return $this;
}

当 page 参数值极大时(如 99999999999999999999),intval($page) 会返回 PHP 整数最大值(64位系统为 9223372036854775807),计算出的 OFFSET 值会溢出: offset = (9223372036854775807 - 1) * 20 = 184467440737095516120

MySQL 无法处理如此巨大的 OFFSET 值,导致查询错误。

  • 修复建议

在 page() 方法中添加限制

php
public function page($page, $pageSize): Query
{
    $page = intval($page);
    
    // 限制最大页数,防止 OFFSET 溢出
    $maxPage = 1000000;
    if ($page > $maxPage || $page < 1) {
        $page = 1;
    }
    
    $pageSize = intval($pageSize);
    $this->sqlPreBuild['limit'] = $pageSize;
    $this->sqlPreBuild['offset'] = ($page - 1) * $pageSize;
    return $this;
}