php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74623 Infinite loop in type inference when using HTMLPurifier
Submitted: 2017-05-21 11:45 UTC Modified: 2017-06-07 22:53 UTC
Votes:8
Avg. Score:4.6 ± 0.5
Reproduced:7 of 8 (87.5%)
Same Version:7 (100.0%)
Same OS:4 (57.1%)
From: lkebin at gmail dot com Assigned:
Status: Closed Package: opcache
PHP Version: 7.1.5 OS: CentOS 6.9
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: lkebin at gmail dot com
New email:
PHP Version: OS:

 

 [2017-05-21 11:45 UTC] lkebin at gmail dot com
Description:
------------
When the php run the code which invoke HTMLPurifier, The php-fpm or php cli processes CPU usage 100%, The php-fpm will occur Nginx response 504 (time out). When I run `php HTMLPurifier.standalone.php`, the process CPU usage to 100% and can not be exit normally. I need force kill it.

The problem occur php 7.1.5/7.1.4 (I tested versions on my virtual machine). Also I tested php 7.0.19, No problem with it.


I compiled the official released version:

./configure --enable-debug
make

Changed opcache.enable_cli=1 in the php.ini-development, and loaded opcache.so file from php-src/modules/ directory.

Run the script

./sapi/cli/php -c ~/HTMLPurifier.standalone.php


The gdb backtrace 

---- gdb backtrace ----

(gdb) bt
#0  0x00007ffff63b2495 in raise (sig=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff63b3c75 in abort () at abort.c:92
#2  0x00007ffff63ab60e in __assert_fail_base (
    fmt=<value optimized out>, assertion=0x7fffef950328 "0",
    file=0x7fffef950268 "/root/download/php-7.1.5/ext/opcache/Optimizer/zend_inference.c", line=<value optimized out>,
    function=<value optimized out>) at assert.c:96
#3  0x00007ffff63ab6d0 in __assert_fail (assertion=0x7fffef950328 "0",
    file=0x7fffef950268 "/root/download/php-7.1.5/ext/opcache/Optimizer/zend_inference.c", line=1902,
    function=0x7fffef950cb0 "check_type_narrowing") at assert.c:105
#4  0x00007fffef92a210 in check_type_narrowing (
    op_array=0x7fffe74f06f8, ssa=0x7fffe7216700,
    worklist=0x7fffffffa700, var=37, old_type=402653444,
    new_type=411040760)
    at /root/download/php-7.1.5/ext/opcache/Optimizer/zend_inference.c:1902
#5  0x00007fffef939041 in zend_update_type_info (
    op_array=0x7fffe74f06f8, ssa=0x7fffe7216700, script=0x7ffff5a7a000,
    worklist=0x7fffffffa700, i=44)
    at /root/download/php-7.1.5/ext/opcache/Optimizer/zend_inference.c:3113
#6  0x00007fffef93b810 in zend_infer_types_ex (op_array=0x7fffe74f06f8,
    script=0x7ffff5a7a000, ssa=0x7fffe7216700, worklist=0x7fffffffa700)
    at /root/download/php-7.1.5/ext/opcache/Optimizer/zend_inference.c:3332
#7  0x00007fffef93d743 in zend_infer_types (op_array=0x7fffe74f06f8,
    script=0x7ffff5a7a000, ssa=0x7fffe7216700)
    at /root/download/php-7.1.5/ext/opcache/Optimizer/zend_inference.c:3811
#8  0x00007fffef93dbae in zend_ssa_inference (arena=0x7fffffffa860,
    op_array=0x7fffe74f06f8, script=0x7ffff5a7a000, ssa=0x7fffe7216700)
    at /root/download/php-7.1.5/ext/opcache/Optimizer/zend_inference.c:3876
#9  0x00007fffef914839 in zend_dfa_analyze_op_array (
---Type <return> to continue, or q <return> to quit---
    op_array=0x7fffe74f06f8, ctx=0x7fffffffa860, ssa=0x7fffe7216700,
    flags=0x7fffe72166fc)
    at /root/download/php-7.1.5/ext/opcache/Optimizer/dfa_pass.c:106
#10 0x00007fffef8feae5 in zend_optimize_script (script=0x7ffff5a7a000,
    optimization_level=2147467263, debug_level=0)
    at /root/download/php-7.1.5/ext/opcache/Optimizer/zend_optimizer.c:993
#11 0x00007fffef8dab79 in cache_script_in_shared_memory (
    new_persistent_script=0x7ffff5a7a000,
    key=0x1126d90 "/root/HTMLPurifier.standalone.php", key_length=33,
    from_shared_memory=0x7fffffffaaa0)
    at /root/download/php-7.1.5/ext/opcache/ZendAccelerator.c:1273
#12 0x00007fffef8dc5ad in persistent_compile_file (
    file_handle=0x7fffffffe030, type=8)
    at /root/download/php-7.1.5/ext/opcache/ZendAccelerator.c:1865
#13 0x000000000087b325 in zend_execute_scripts (type=8, retval=0x0,
    file_count=3) at /root/download/php-7.1.5/Zend/zend.c:1470
#14 0x00000000007e54a6 in php_execute_script (
    primary_file=0x7fffffffe030)
    at /root/download/php-7.1.5/main/main.c:2537
#15 0x000000000096f87a in do_cli (argc=4, argv=0x1126cf0)
    at /root/download/php-7.1.5/sapi/cli/php_cli.c:993
#16 0x00000000009707b9 in main (argc=4, argv=0x1126cf0)
    at /root/download/php-7.1.5/sapi/cli/php_cli.c:1381

Test script:
---------------
https://gist.github.com/lkebin/e25594cfd493e984054686a7cd2ec4b8

Expected result:
----------------
From php cli to run the test script should be empty output and exit 0


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-05-22 03:08 UTC] lkebin at gmail dot com
Run the script should be 

./sapi/cli/php -c ./php.ini-development ~/HTMLPurifier.standalone.php
 [2017-06-03 01:02 UTC] ezyang@php.net
Xiphin reports that the following patch to HTML Purifier solves the problem. Maybe this will help diagnose the opcode problem: https://github.com/ezyang/htmlpurifier/pull/137
 [2017-06-03 01:38 UTC] Xiphin at qq dot com
https://gist.github.com/lkebin/e25594cfd493e984054686a7cd2ec4b8
You can fix it by follow:
line 14727: change "$current_li = false;" to "$current_li = null;"
line 14748: change "if ($current_li === false) {" to "if ($current_li === null) {"
 [2017-06-07 22:39 UTC] phpbugs at ackermann dot ca
Hello,

just run into this bug. The boil down version is a file with the following content. Opening or including the file results in 100% CPU load.

<?php

function crash($arr) {
    $current_item = false;

    foreach($arr as $item) {
        $current_item = $item;
        $current_item->a[] = '';
    }

}
 [2017-06-07 22:45 UTC] phpbugs at ackermann dot ca
Wrong test code posted before. This one should do it.

<?php

function crash($arr) {
    $current_item = false;

    foreach($arr as $item) {
        if($item->name === 'string') {
            $current_item = $item;
        } else {
            $current_item->a[] = '';
        }
    }

}
 [2017-06-07 22:54 UTC] nikic@php.net
-Summary: Invoke HTMLPurifier occur CPU 100% +Summary: Infinite loop in type inference when using HTMLPurifier -Status: Open +Status: Verified
 [2017-06-23 15:34 UTC] nikic@php.net
Automatic comment on behalf of nikita.ppv@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=5b5a92b8b6d96b8fbd8557645801ae99310cab2b
Log: Fixed bug #74623
 [2017-06-23 15:35 UTC] nikic@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 07 23:01:29 2024 UTC