CI自動過濾掉百分比符號%後兩位的問題解決_PHP教程

來源:互聯網
上載者:User
在 CodeIgniter 做的網站裡,想輸入一段代碼:

$var = sprintf("%04d", 2);

但是發現入庫後,代碼變成了

$var = sprintf("d", 2);

在網上環境,本地環境都測試過,最終確認是 CodeIgniter 系統的問題。下面談一下問題解決的過程與思維方法:

1. 是 config.php 的 permitted_uri_chars 嗎?

$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';

在 stackoverflow 上找到幾個差不多的問題,有答案說改 config.php 的 permitted_uri_chars 就行了。

Ahem... after looking at your sample string again. Here is why you get "The URI you submitted has disallowed characters".

Short explanation: Add the ampersand & to the allowed characters list

$config['permitted_uri_chars'] = 'a-z 0-9~%.:_+&-';

試過了,沒效果,於是就尋找應用了 $config['permitted_uri_chars'] 的代碼。

2. 是 core/Input.php 的 _clean_input_keys() 函數問題嗎?

function _clean_input_keys($str)   {   $config = &get_config('config');   if ( ! preg_match("/^[".$config['permitted_uri_chars']."]+$/i", rawurlencode($str)))   {   exit('Disallowed Key Characters.');   }   // Clean UTF-8 if supportedif (UTF8_ENABLED === TRUE){$str = $this->uni->clean_string($str);}return $str;   } 

這個函數使用了 $config['permitted_uri_chars'] 直接過濾 post 過來的資料,很大原因就是元兇了。我把它單獨出來,經過測試發現,post $var = sprintf("%04d", 2); 過來,結果還是 $var = sprintf("%04d", 2); ,%04並未被過濾,看來還得細細地找。

3. 是 xss 的防禦機制嗎?

stackoverflow 有個人說他完美解決了這個問題,是 xss clean 的原因。

:) God damn URLDECODE, I have looked at the code in URI.php but the xss clean is doing the job so I missed it. Thank you now everything is perfect. – RaduM

於是我找到了 core/security.php 下的 xss_clean() 函數。把函數體代碼全部注釋掉,發現輸入還是會把 %04 過濾掉,顯然也不是 xss 的問題。

4. 問題出在 _clean_input_data() 函數

重新回到 Input.php,發現 _clean_input_data 與 _clean_input_keys 有聯絡。

$new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);

於是把 _clean_input_data() 的函數體注釋掉,竟然輸入沒被過濾了。繼續縮小範圍,發現是這段代碼惹得禍:

// Remove control characters// 就是這個會把%0x過濾掉$str = remove_invisible_characters($str);

5. 元兇找到了 remove_invisible_characters() 函數

那麼 remove_invisible_characters() 這個函數是什麼呢?

這個函數在 core/Common.php中,我把它揪出來:

function remove_invisible_characters($str, $url_encoded = TRUE){$non_displayables = array();// every control character except newline (dec 10)// carriage return (dec 13), and horizontal tab (dec 09)if ($url_encoded){$non_displayables[] = '/%0[0-8bcef]/';// url encoded 00-08, 11, 12, 14, 15$non_displayables[] = '/%1[0-9a-f]/';// url encoded 16-31}$non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';// 00-08, 11, 12, 14-31, 127do{$str = preg_replace($non_displayables, '', $str, -1, $count);}while ($count);return $str;}

看這麼幾行代碼:

if ($url_encoded){$non_displayables[] = '/%0[0-8bcef]/';// url encoded 00-08, 11, 12, 14, 15$non_displayables[] = '/%1[0-9a-f]/';// url encoded 16-31}

明確了吧,他會把%0與%1開頭的3個字元過濾掉。直接把這個注釋掉,問題解決。

記錄這個問題解決的思維全過程。

http://www.bkjia.com/PHPjc/752355.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/752355.htmlTechArticle在 CodeIgniter 做的網站裡,想輸入一段代碼: $var = sprintf("%04d", 2); 但是發現入庫後,代碼變成了 $var = sprintf("d", 2); 在網上環境,本地環境都...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.