Apache / PHP на Windows вылетает с регулярным выражением - PullRequest
6 голосов
/ 11 августа 2010

Я обнаружил, что следующий код PHP дает сбой при запуске на сервере Windows Apache:

<?php

$test = "0,4,447,11329,316,415,142,5262,6001,9527,11259,11236,1140,9770,9177,9043,11090,268,5270,9907,9196,10226,".
        "9399,1476,9368,6929,1659,11074,10869,8774,739,11344,10482,6399,8910,8997,11198,137,10148,10371,5128,767,2483,".
        "211,9973,10726,9299,778,11157,9497,275,9418,11141,241,5288,11324,776,10960,9289,7944,222,10686,11428,9723,".
        "10615,11399,9869,9083,10180,10043,9957,9387,9215,8869,9667,10174,10902,6607,9282,1259,395,10411,152,9344,8949,".
        "10923,8976,11042,11519,10704,10979,216,10044,9201,1721,5831,881,9721,1757,11054,1335,6151,9526,9081,111,498,".
        "2960,438,5313,206,318,10820,8192,6039,9161,11012,1717,1360,10757,4314,11280,9647,9346,10546,11006,9553,10365,".
        "6148,10565,4532,2776,4124,8853,6145,478,4539,540,9981,726,7186,11122,324,10524,1139,7900,9581,6869,1724,10851,".
        "10059,10018,11032,1290,3818,782,796,917,8740,6935,11439,10799,10948,249,2068,8778,6289,295,2766,9425,791,309,".
        "4753,10418,771,260,10835,10441,6434,10164,10475,10842,9013,11224,2247,8972,2141,2078,2152,475,9077,6291,10285,".
        "8067,753,6660,10889,431,2503,6007,9180,810,11447,2461,3689,7104,10150,10921,895,10598,747,10570,305,4497,11055,".
        "11496,10938,10722,8761,10086,11482,6780,6685,6918,10286,10659,9996,4074,9118,907,5192,283,2230,8884,6966,".
        "8820,8132,3598,9599,6796,11257,7049,5992,8637,4168,9017,7950,7165,10721,10037,1071,8044,759,11429,6380,".
        "10239,1593,9455,9704,10357,6737,2958,4051,9754,6564,11407,8716,7485,1528,6857,7406,9579,7259,1609,7820,".
        "4448,10289,1123,7005,8123,9316,914,9655,5280,9710,7822,510,10795,10476,8706,6160,8248,6978,9300,10643,".
        "7106,10250,519,7860,4733,904,8773,4714,8695,8633,6105,3312,11548,9580,10389,4886,4587,513,8485,4606,".
        "6471,581,526,637,3523,3772,3153,9336,9120,7633,3755,10087,524,10015,8563,556,1230,570,3652,569"
        .",8473,10209,3886,573,5363,4715,3865,9452,1218,7066,575,577,4724,7655"
        ;

$hest = preg_match('/^\d+(?:,\d+)+$/', $test);
var_dump($hest);
?>

Интересно, что код работает, если строка немного короче - если я закомментирую последнийчасть (строка) строки, код выполняется и работает, как и ожидалось.

Однако, поскольку код представлен здесь, код вызывает сбой Apache и респаун - ошибка не регистрируется.Если я попытаюсь запустить код напрямую через PHP, он будет работать, как и ожидалось, поэтому проблема как-то связана с Apache.

Я экспериментировал с параметром «pcre.recursion_limit» и обнаружил, что если я уменьшу его до689 он не умирает, но вместо этого вызов preg_match () завершается ошибкой с PREG_RECURSION_LIMIT_ERROR.Для более высоких значений pcre.recursion_limit Apache умирает.

Apache 2.2.11 PHP 5.3.0

Я также проверял это на сервере Debian, где я НЕ вижу ошибку, и с другимиверсии PHP и Apache для Windows, где ошибка возникает, как описано выше, поэтому кажется, что это может быть связано с Windows.

Кто-нибудь видел это раньше?Мне бы очень хотелось что-то вроде подсказки!

ОБНОВЛЕНИЕ: Я из-за «ошибки» в Apache для Windows - ну, на самом деле, это не ошибка, но кажется, что Apacheскомпилирован с небольшим размером стека, и это вызывает эту ошибку в PCRE, когда PHP использует его.Смотри http://bugs.php.net/bug.php?id=47689

Ответы [ 4 ]

3 голосов
/ 11 августа 2010

Всегда хорошая идея уменьшить «pcre.recursion_limit», потому что высокое значение по умолчанию может повредить стек процесса (см. http://php.net/manual/en/pcre.configuration.php) - это именно то, что происходит с вашей установкой mod_php. Так как preg functions don 'выдает ошибку при достижении пределов рекурсии / возврата, может быть полезно иметь обертку типа

function match($re, $text) {
    preg_match($re, $text, $m);
    if(preg_last_error())
         trigger_error("preg: " . preg_last_error());
    return $m;
 }

По крайней мере, это позволяет вам знать, когда что-то идет не так.

Кроме тогопопробуйте упростить ваши шаблоны, когда это возможно, например, /^\d[\d,]*\d$/ делает то же самое, что и выше, но с нулевой рекурсией.

1 голос
/ 27 апреля 2019

Большое спасибо за этот пост. Это решило мою проблему.

Конфигурация для стека Apache в Windows является причиной. Быстрый способ увеличить размер стека Apache - использовать директиву ThreadStackSize в конфигурации Apache (http://httpd.apache.org/docs/2.2/mod/mpm_common.html#ThreadStackSize)

Это может выглядеть так:

<IfModule mpm_winnt_module>
   ThreadStackSize 8*1024*1024
</IfModule>

Устанавливает размер стека равным 8 МБ, так же, как значение по умолчанию в Linux.

(Спасибо за https://bugs.php.net/bug.php?id=47689)

1 голос
/ 01 марта 2013

Увеличьте стек Apache, и проблема исчезнет, ​​или используйте конфигурацию httpd для ее увеличения.

Большинство сборок Apache имеют слишком маленький размер стека, в то время как у нас есть нормальная сборка для PHP. Это объясняет, почему одни и те же выражения будут работать в CLI, а не в Apache (стек для каждого процесса, а процесс принадлежит / определяется Apache).

0 голосов
/ 11 августа 2010

Сбой обычно означает, что вы столкнулись с ошибкой PHP. Это происходит сейчас и потом. Если вы не можете обновить установку PHP, вам придется переписать свой код. В любом случае, высокий уровень рекурсии предполагает, что вам не следует использовать регулярные выражения или, по крайней мере, сначала нужно разбить входную строку на более мелкие части.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...