ホームページ  >  記事  >  バックエンド開発  >  Mybb1.8 データベース コア オペレーション update_query にはデータ損失を引き起こす低レベルのバグがあります

Mybb1.8 データベース コア オペレーション update_query にはデータ損失を引き起こす低レベルのバグがあります

巴扎黑
巴扎黑オリジナル
2016-11-11 15:33:40967ブラウズ

Mybb1.6 を 1.8 にアップグレードする過程で、数え切れないほどの問題に遭遇しました。最近、Mybb1.8 データベースのコア オペレーション update_query のコードに、先頭のゼロが欠落する重大なバグが発見されました。データが保存されたとき、数時間後、問題は私にあるのではなく、mybb のアップグレード コードにあることがわかりました。  

データ テーブル: test 
field 
ID  AUTO_INCREMENT 
name varchar ( 60) not null 
category varchar(5) 

この表では、カテゴリは分類を表し、分類は共通コードで表され、合計最初の 2 桁の 01 ~ 99 は大カテゴリを表し、最後の 3 桁は小カテゴリを表します。 update ステートメントの Ajax を通じてテキストを更新し、background ステートメントの update_query を通じてデータを更新します。レベル 1.6 では正常に動作していましたが、レベル 1.8 ではアップデートが混乱していました。確認したところ、カテゴリ フィールドの前の「0」が抜けていました。この問題は、さまざまな手段を変更することで解決できるものではありません。最後に、Mybb のデータ操作コア ファイルを取り出してバージョン 1.6 と比較したところ、コードに低レベルのバグがあり、エラーが発生していることがわかりました。

下面是1.8版数据更新过程

Php代码

function update_query($table, $array, $where="", $limit="", $no_quote=false)  
{  
    global $mybb;  
  
    if(!is_array($array))  
    {  
        return false;  
    }  
  
    $comma = "";  
    $query = "";  
    $quote = "'";  
  
    if($no_quote == true)  
    {  
        $quote = "";  
    }  
  
    foreach($array as $field => $value)  
    {  
        if(isset($mybb->binary_fields[$table][$field]) && $mybb->binary_fields[$table][$field])  
        {  
            if($value[0] != 'X') // Not escaped?  
            {  
                $value = $this->escape_binary($value);  
            }  
              
            $query .= $comma."`".$field."`={$value}";  
        }  
        else  
        {  
            if(is_numeric($value))  
            {  
                $query .= $comma."`".$field."`={$value}";  
            }  
            else  
            {  
                $query .= $comma."`".$field."`={$quote}{$value}{$quote}";  
            }  
        }  
        $comma = ', ';  
    }  
  
    if(!emptyempty($where))  
    {  
        $query .= " WHERE $where";  
    }  
  
    if(!emptyempty($limit))  
    {  
        $query .= " LIMIT $limit";  
    }  
  
    return $this->write_query("  
        UPDATE {$this->table_prefix}$table  
        SET $query  
    ");  
}



而1.6版本是这样的

Php代码

function update_query($table, $array, $where="", $limit="", $no_quote=false)  
    {  
        if(!is_array($array))  
        {  
            return false;  
        }  
          
        $comma = "";  
        $query = "";  
        $quote = "'";  
          
        if($no_quote == true)  
        {  
            $quote = "";  
        }  
          
        foreach($array as $field => $value)  
        {  
            $query .= $comma."`".$field."`={$quote}{$value}{$quote}";  
            $comma = ', ';  
        }  
          
        if(!emptyempty($where))  
        {  
            $query .= " WHERE $where";  
        }  
          
        if(!emptyempty($limit))  
        {  
            $query .= " LIMIT $limit";  
        }  
  
        return $this->write_query("  
            UPDATE {$this->table_prefix}$table  
            SET $query  
        ");  
    }



发生错误的是这样几句

Php代码

if(is_numeric($value))  
            {  
                $query .= $comma."`".$field."`={$value}";  
            }  
            else  
            {  
                $query .= $comma."`".$field."`={$quote}{$value}{$quote}";  
            }


传过来category的值可能是01002或08003,只要is_numeric($value)为真就是数字类型?!这是什么逻辑。其时mysql能自动处理识别字符型和数字型的差别,升级的1.8版把简单的事情复杂化,错误的逻辑导致bug发生,导致传过来的由数字组成的字符串存入数据库时前面的0丢失。如果前面不为0,就不会出错,这样导致数据一片混乱。

一直以来很欣赏Mybb简洁的代码和漂亮的系统架构,2M代码包括图片CSS等竟然能完成如此多的功能,给予用户良好的扩展能力。没想到翻出这样一个bug,见笑了。1.6至1.8改动很大,发布过于仓促。总体说来,Mybb不失一个漂亮简洁的php论坛。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。