<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/taint.detail.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'zh',
  ),
  'this' => 
  array (
    0 => 'taint.detail.basic.php',
    1 => '污点标记如何传播',
    2 => '污点标记如何传播',
  ),
  'up' => 
  array (
    0 => 'taint.detail.php',
    1 => '传播规则与被检查的汇点',
  ),
  'prev' => 
  array (
    0 => 'taint.detail.php',
    1 => '传播规则与被检查的汇点',
  ),
  'next' => 
  array (
    0 => 'taint.detail.sinks.php',
    1 => 'taint 在哪里发出警告',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'zh',
    'path' => 'reference/taint/detail.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="taint.detail.basic" class="section">
  <h2 class="title">污点标记如何传播</h2>
  <p class="simpara">
   污点标记是存储于字符串本身上的一个比特位，而不是存储于持有它的
   变量上。对被污染的字符串进行赋值、传参或其它形式的共享，标记都会
   保留。字符串拼接和插值同样会传播标记：
  </p>
  <p class="para">
   <table class="doctable table">
    <caption><strong>会传播污点标记的运算符</strong></caption>
    
     <tbody class="tbody">
      <tr>
       <td><code class="literal">=</code>（赋值，包括 <code class="literal">list()</code> / <code class="literal">数组解构</code>）</td>
      </tr>

      <tr>
       <td><code class="literal">.</code>（拼接）</td>
      </tr>

      <tr>
       <td><code class="literal">.=</code>（拼接赋值）</td>
      </tr>

      <tr>
       <td><code class="literal">&quot;{$var}&quot;</code>（字符串插值，包括 <code class="literal">ROPE</code> 快速路径）</td>
      </tr>

     </tbody>
    
   </table>

  </p>
  <p class="simpara">
   此外，taint 还理解一组固定的字符串函数：只要相关的字符串参数被污染，
   返回的字符串也会被标记为已污染。常规调用和 PHP 8.4+ 的 frameless
   快速路径调用都在覆盖范围内。
  </p>
  <p class="para">
   <table class="doctable table">
    <caption><strong>会传播污点标记的函数</strong></caption>
    
     <tbody class="tbody">
      <tr>
       <td><span class="function"><a href="function.trim.php" class="function">trim()</a></span>, <span class="function"><a href="function.rtrim.php" class="function">rtrim()</a></span>, <span class="function"><a href="function.ltrim.php" class="function">ltrim()</a></span></td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.substr.php" class="function">substr()</a></span>, <span class="function"><a href="function.strstr.php" class="function">strstr()</a></span></td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.str-replace.php" class="function">str_replace()</a></span>, <span class="function"><a href="function.str-ireplace.php" class="function">str_ireplace()</a></span></td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.str-pad.php" class="function">str_pad()</a></span>, <span class="function"><a href="function.strtolower.php" class="function">strtolower()</a></span>, <span class="function"><a href="function.strtoupper.php" class="function">strtoupper()</a></span>, <span class="function"><a href="function.strval.php" class="function">strval()</a></span></td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.explode.php" class="function">explode()</a></span>（结果数组中的每一个元素）</td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.implode.php" class="function">implode()</a></span>/<span class="function"><a href="function.join.php" class="function">join()</a></span>（分隔符被污染时，结果同样会被污染）</td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.sprintf.php" class="function">sprintf()</a></span>, <span class="function"><a href="function.vsprintf.php" class="function">vsprintf()</a></span>（只有 <code class="literal">%s</code> 说明符会携带标记；<code class="literal">sprintf(&quot;%d&quot;, $t)</code> 返回的是干净字符串）</td>
      </tr>

      <tr>
       <td><span class="function"><a href="function.dirname.php" class="function">dirname()</a></span>, <span class="function"><a href="function.basename.php" class="function">basename()</a></span>, <span class="function"><a href="function.pathinfo.php" class="function">pathinfo()</a></span></td>
      </tr>

     </tbody>
    
   </table>

  </p>
  <p class="simpara">
   任何 taint 没有显式理解的函数都会返回一个新的、不带标记的字符串 ——
   包括 <span class="function"><a href="function.htmlspecialchars.php" class="function">htmlspecialchars()</a></span>、<span class="function"><a href="function.htmlentities.php" class="function">htmlentities()</a></span>
   或 <span class="function"><a href="mysqli.real-escape-string.php" class="function">mysqli_real_escape_string()</a></span> 这类转义函数。
   这是有意为之：taint 宁可多报，也不会去判断某个值在特定输出场景下
   是否<q class="quote">安全</q>。对于已经自行校验过的值，请用
   <span class="function"><a href="function.untaint.php" class="function">untaint()</a></span> 清除标记。
  </p>
 </div><?php manual_footer($setup); ?>