Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

PHP Notice: Undefined offset: 27498 in /usr/local/lib/php/pear/PHPCPD/TextUI/Command.php on line 260 #14

Closed
CloCkWeRX opened this Issue · 16 comments

10 participants

@CloCkWeRX

Version 1.3.1; who knows what steps to reproduce.

In some cases, the phpcpd textui can produce e_notices:
PHP Notice: Undefined offset: 27498 in /usr/local/lib/php/pear/PHPCPD/TextUI/Command.php on line 260

@sebastianbergmann

Can you try with phpcpd 1.3.2, please? Thanks!

@CloCkWeRX

Unfortunately I couldn't tell which of the several hundred pear packages this was triggered on, so no :(

However looking at the source, for 1.3.2 it's line 264, getCommonPath()

You are only setting up $_files[$i][0] = DIRECTORY_SEPARATOR; when there's nothing already set, but code below checks more than that depth:
if ($_files[$i][$j] != $_files[$i+1][$j]) {
// snip
}
$j++;

Reproduce script (changing the method to public temporarily):
require_once 'PHPCPD/TextUI/Command.php';

$files = array('/foo/bar.php', '/foo/bar.php');
print_r(PHPCPD_TextUI_Command::getCommonPath($files));

Expected: No e_notices, No endless iteration

Actual:
while (true) { ... } happens forever, e_notices get emitted.

Perhaps add in
if (!isset($_files[$i+1][$j]) {
$done = true;
}

@ssaki

Hi

Error reproduced with phpcpd 1.3.2.
It seems that if directory contains only one php file scan fails.

reproduced with

1) SVN working copy, src/ contains only the test_commit.php file and the .svn dir

phpcpd src/test_commit.php is OK
phpcpd src/ fails with


phpcpd 1.3.2 by Sebastian Bergmann.

PHP Notice:  Undefined offset: 8 in /usr/share/php/PHPCPD/TextUI/Command.php on line 264
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpcpd:0
PHP   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:51
PHP   3. PHPCPD_TextUI_Command::getCommonPath($files = array (0 => '/opt/cruisecontrol-bin-2.8.4/projects/yasf/source/src/test_commit.php', 1 => '/opt/cruisecontrol-bin-2.8.4/projects/yasf/source/src/test_commit.php')) /usr/share/php/PHPCPD/TextUI/Command.php:219
PHP Notice:  Undefined offset: 8 in /usr/share/php/PHPCPD/TextUI/Command.php on line 264
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpcpd:0
PHP   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:51
PHP   3. PHPCPD_TextUI_Command::getCommonPath($files = array (0 => '/opt/cruisecontrol-bin-2.8.4/projects/yasf/source/src/test_commit.php', 1 => '/opt/cruisecontrol-bin-2.8.4/projects/yasf/source/src/test_commit.php')) /usr/share/php/PHPCPD/TextUI/Command.php:219
PHP Notice:  Undefined offset: 8 in /usr/share/php/PHPCPD/TextUI/Command.php on line 271
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpcpd:0
PHP   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:51
PHP   3. PHPCPD_TextUI_Command::getCommonPath($files = array (0 => '/opt/cruisecontrol-bin-2.8.4/projects/yasf/source/src/test_commit.php', 1 => '/opt/cruisecontrol-bin-2.8.4/projects/yasf/source/src/test_commit.php')) /usr/share/php/PHPCPD/TextUI/Command.php:219
PHP Notice:  Undefined offset: 9 in /usr/share/php/PHPCPD/TextUI/Command.php on line 264
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpcpd:0
PHP   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:51
PHP   3. PHPCPD_TextUI_Command::getCommonPath($files = array (0 => '/opt/cruisecontrol-bin-2.8.4/projects/yasf/source/src/test_commit.php', 1 => '/opt/cruisecontrol-bin-2.8.4/projects/yasf/source/src/test_commit.php')) /usr/share/php/PHPCPD/TextUI/Command.php:219
PHP Notice:  Undefined offset: 9 in /usr/share/php/PHPCPD/TextUI/Command.php on line 264
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpcpd:0
PHP   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:51
PHP   3. PHPCPD_TextUI_Command::getCommonPath($files = array (0 => '/opt/cruisecontrol-bin-2.8.4/projects/yasf/source/src/test_commit.php', 1 => '/opt/cruisecontrol-bin-2.8.4/projects/yasf/source/src/test_commit.php')) /usr/share/php/PHPCPD/TextUI/Command.php:219

Best regards
Alex

@sebastianbergmann

I cannot reproduce this:

sb@thinkpad /tmp % ls -la src
total 20
drwxr-xr-x  3 sb   sb   4096 2010-10-08 21:29 .
drwxrwxrwt 16 root root 4096 2010-10-08 21:28 ..
-rw-r--r--  1 sb   sb   5448 2010-10-08 21:29 Math.php
drwxr-xr-x  2 sb   sb   4096 2010-10-08 21:29 .svn

sb@thinkpad /tmp % phpcpd src
phpcpd @package_version@ by Sebastian Bergmann.

Found 1 exact clones with 28 duplicated lines in 1 files:

  - Math.php:86-114
    Math.php:150-178

13.33% duplicated lines out of 210 total lines of code.

Time: 0 seconds, Memory: 2.75Mb

Does the patch below fix the issue for you?

diff --git a/PHPCPD/TextUI/Command.php b/PHPCPD/TextUI/Command.php
index 27a130d..86b4d8c 100644
--- a/PHPCPD/TextUI/Command.php
+++ b/PHPCPD/TextUI/Command.php
@@ -261,7 +261,8 @@ class PHPCPD_TextUI_Command

         while (!$done) {
             for ($i = 0; $i < $count; $i++) {
-                if ($_files[$i][$j] != $_files[$i+1][$j]) {
+                if (!isset($_files[$i+1][$j]) ||
+                    $_files[$i][$j] != $_files[$i+1][$j]) {
                     $done = TRUE;
                     break;
                 }
@CloCkWeRX

Yes; that suppresses the E_NOTICE and prevents to looping forever in the cut down reproduce script.

In the long term, I don't suppose you'd consider refactoring this class away from static methods, or splitting the responsibility of getCommonPath off?

When you look at it, main() is just weaving together a bunch of components, showError(), displayHelp(), printVersionString() are just rendering to stdout a bit.

It's only getCommonPath() does analysis on PHPCPD_Detector results - I'd consider shifting it to PHPCPD_Detector, and making it public / non static / testable.

@ssaki

I also confirm that the patch fixes the issue

Best regards
Alex

@alab1001101

Encountered this issue as well, my fix was:
/**
* Returns the common path of a set of files.
*
* @param array $files
* @return string
*/
protected static function getCommonPath(array $files)
{
$count = count($files);

    if ($count == 1) {
        return dirname($files[0]) . DIRECTORY_SEPARATOR;
    }

    $_files = array();

    foreach ($files as $file) {
        $count = array_push($_files, explode(DIRECTORY_SEPARATOR, $file));

        $_file =& end($_files);
        if (empty($_file[0])) {
            $_file[0] = DIRECTORY_SEPARATOR;
        }
    }

    $common = '';
    $done   = FALSE;
    $j      = 0;
    $count--; 

    while (!$done) {
        for ($i = 0; $i < $count; $i++) {
            if ($_files[$i][$j] != $_files[$i+1][$j]) {
                $done = TRUE;
                break;
            }
        }

        if (!$done) {
            $common .= $_files[0][$j];

            if ($j > 0) {
                $common .= DIRECTORY_SEPARATOR;
            }
        }

        $j++;
    }

    return $common;
}
@dreddyseb

(Perhaps) same problem for me with 1.3.2, but at a different line :

PHP Notice: Undefined offset: 39 in /PHPCPD/TextUI/Command.php on line 250

PHP Stack trace:

PHP 1. {main}() phpcpd:0

PHP 2. PHPCPD_TextUI_Command::main() phpcpd:50

PHP 3. PHPCPD_TextUI_Command::getCommonPath() /PHPCPD/TextUI/Command.php:219

the patch above didn't fix it.

@ludofleury

Yah same problem as dreddyseb

@dtmax

2 dreddyseb:

I fixed this problem this way:

lines 249-250 of /PHPCPD/TextUI/Command.php
WAS:
for ($i = 0; $i < $count; $i++) {
$_files[$i] = explode(DIRECTORY_SEPARATOR, $files[$i]);
FIX:
for ($i = 0, $keys = array_keys($files); $i < $count; $i++) {
$_files[$i] = explode(DIRECTORY_SEPARATOR, $files[$keys[$i]]);

@dreddyseb

thx a lot dtmax
this works great
maybe sebastian can check if this fix is valid, and if so, integrate it in the source

@DSB

Here is my fix that is working for me:

$_files = array();
$i = 0;
foreach ($files as $file) {
    $_files[$i] = explode(DIRECTORY_SEPARATOR, $file);
    if (empty($_files[$i][0])) {
        $_files[$i][0] = DIRECTORY_SEPARATOR;
    }
    $i++;
}
@cweiske

I can confirm the issue with phpcpd 1.3.2:

phpcpd --log-pmd tests/logs/cpd.xml /home/christian.weiske/foo/bar/baz 2>&1
phpcpd 1.3.2 by Sebastian Bergmann.

PHP Notice:  Undefined offset: 1 in /usr/share/php/PHPCPD/TextUI/Command.php on line 250
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpcpd:0
PHP   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:51
PHP   3. PHPCPD_TextUI_Command::getCommonPath() /usr/share/php/PHPCPD/TextUI/Command.php:219

Notice: Undefined offset: 1 in /usr/share/php/PHPCPD/TextUI/Command.php on line 250

Call Stack:
    0.0002     325752   1. {main}() /usr/bin/phpcpd:0
    0.0403     676700   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:51
    1.8893    1352588   3. PHPCPD_TextUI_Command::getCommonPath() /usr/share/php/PHPCPD/TextUI/Command.php:219

PHP Notice:  Undefined offset: 1 in /usr/share/php/PHPCPD/TextUI/Command.php on line 264
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpcpd:0
PHP   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:51
PHP   3. PHPCPD_TextUI_Command::getCommonPath() /usr/share/php/PHPCPD/TextUI/Command.php:219
@lencioni

I am also having this problem. It seems to be using an array that has a gap in its keys. Here's the message I get:

phpcpd 1.3.2 by Sebastian Bergmann.

PHP Notice:  Undefined offset: 1 in /usr/share/pear/PHPCPD/TextUI/Command.php on line 250
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpcpd:0
PHP   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:50
PHP   3. PHPCPD_TextUI_Command::getCommonPath($files = array (0 => '/path/to/a/file.php', 2 => '/path/to/a/file.php', 3 => '/path/to/a/file.php', 4 => '/path/to/a/file.php', 5 => '/path/to/a/file.php', 6 => '/path/to/a/file.php', 7 => '/path/to/a/file.php', 8 => '/path/to/a/file.php', 9 => '/path/to/a/file.php', 10 => '/path/to/a/file.php', 11 => '/path/to/a/file.php', 12 => '/path/to/a/file.php', 13 => '/path/to/a/file.php', 14 => '/path/to/a/file.php', 15 => '/path/to/a/file.php', 16 => '/path/to/a/file.php', 17 => '/path/to/a/file.php', 18 => '/path/to/a/file.php')) /usr/share/pear/PHPCPD/TextUI/Command.php:219

Notice: Undefined offset: 1 in /usr/share/pear/PHPCPD/TextUI/Command.php on line 250

Call Stack:
    0.0015     912048   1. {main}() /usr/bin/phpcpd:0
    0.0047    1424856   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:50
    0.7496    2370128   3. PHPCPD_TextUI_Command::getCommonPath($files = array (0 => '/path/to/a/file.php', 2 => '/path/to/a/file.php', 3 => '/path/to/a/file.php', 4 => '/path/to/a/file.php', 5 => '/path/to/a/file.php', 6 => '/path/to/a/file.php', 7 => '/path/to/a/file.php', 8 => '/path/to/a/file.php', 9 => '/path/to/a/file.php', 10 => '/path/to/a/file.php', 11 => '/path/to/a/file.php', 12 => '/path/to/a/file.php', 13 => '/path/to/a/file.php', 14 => '/path/to/a/file.php', 15 => '/path/to/a/file.php', 16 => '/path/to/a/file.php', 17 => '/path/to/a/file.php', 18 => '/path/to/a/file.php')) /usr/share/pear/PHPCPD/TextUI/Command.php:219

Dump $_POST
PHP Notice:  Undefined offset: 1 in /usr/share/pear/PHPCPD/TextUI/Command.php on line 264
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpcpd:0
PHP   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:50
PHP   3. PHPCPD_TextUI_Command::getCommonPath($files = array (0 => '/path/to/a/file.php', 2 => '/path/to/a/file.php', 3 => '/path/to/a/file.php', 4 => '/path/to/a/file.php', 5 => '/path/to/a/file.php', 6 => '/path/to/a/file.php', 7 => '/path/to/a/file.php', 8 => '/path/to/a/file.php', 9 => '/path/to/a/file.php', 10 => '/path/to/a/file.php', 11 => '/path/to/a/file.php', 12 => '/path/to/a/file.php', 13 => '/path/to/a/file.php', 14 => '/path/to/a/file.php', 15 => '/path/to/a/file.php', 16 => '/path/to/a/file.php', 17 => '/path/to/a/file.php', 18 => '/path/to/a/file.php')) /usr/share/pear/PHPCPD/TextUI/Command.php:219

Notice: Undefined offset: 1 in /usr/share/pear/PHPCPD/TextUI/Command.php on line 264

Call Stack:
    0.0015     912048   1. {main}() /usr/bin/phpcpd:0
    0.0047    1424856   2. PHPCPD_TextUI_Command::main() /usr/bin/phpcpd:50
    0.7496    2370128   3. PHPCPD_TextUI_Command::getCommonPath($files = array (0 => '/path/to/a/file.php', 2 => '/path/to/a/file.php', 3 => '/path/to/a/file.php', 4 => '/path/to/a/file.php', 5 => '/path/to/a/file.php', 6 => '/path/to/a/file.php', 7 => '/path/to/a/file.php', 8 => '/path/to/a/file.php', 9 => '/path/to/a/file.php', 10 => '/path/to/a/file.php', 11 => '/path/to/a/file.php', 12 => '/path/to/a/file.php', 13 => '/path/to/a/file.php', 14 => '/path/to/a/file.php', 15 => '/path/to/a/file.php', 16 => '/path/to/a/file.php', 17 => '/path/to/a/file.php', 18 => '/path/to/a/file.php')) /usr/share/pear/PHPCPD/TextUI/Command.php:219

DSB's fix worked for me. Here's the patch if it helps anyone:

--- Command.php.orig    2011-10-03 15:34:42.710254572 -0500
+++ Command.php 2011-10-03 15:36:12.849260974 -0500
@@ -245,13 +245,13 @@
         }

         $_files = array();
-
-        for ($i = 0; $i < $count; $i++) {
-            $_files[$i] = explode(DIRECTORY_SEPARATOR, $files[$i]);
-
+        $i = 0;
+        foreach ($files as $file) {
+            $_files[$i] = explode(DIRECTORY_SEPARATOR, $file);
             if (empty($_files[$i][0])) {
                 $_files[$i][0] = DIRECTORY_SEPARATOR;
             }
+            $i++;
         }

         $common = '';
@sebastianbergmann

The issue needs to be fixed in File_Iterator, not each and every tool that uses it. Hopefully will get to this tomorrow.

@sebastianbergmann

This should already be fixed in the latest RCs of phpcpd and File_Iterator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.