Uploaded image for project: 'phpBB'
  1. phpBB
  2. PHPBB-17732

Automatic updater silently skips files with real merge conflicts

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • None
    • 4.0.0-a2, 3.3.19
    • Installation system
    • None

      Since 3.3.5-RC1 (PR #6216, PHPBB-16570) the automatic updater no longer reports real merge conflicts. A modified file that conflicts with the update is left out of the update: it is not updated, not listed as a conflict and not in the "modified files" archive, and the updater reports that it finished successfully.
       
      In phpBB/phpbb/install/module/update_filesystem/task/diff_files.php (around line 188, 3.3.x and master):
       

      if (!$empty && in_array($filename, $merge_conflicts))
      {
      $merge_conflicts[] = $filename;
      }
      else
      {
      $file_is_merged = true;
      }
      

       
      There are two problems:

      1. On a first run $merge_conflicts is empty, so in_array() is always false. Every real conflict goes into the else branch, is treated as merged, and is then removed from update_with_diff.
      2. Even with !in_array(), the "did the user already merge it" check compares the board file with merged_orig_output(), which uses the board (final1) side for every conflict. When all of phpBB's changes to a file conflict, that output is identical to the board file, so $empty is true on a first run and the conflict is skipped as well.
         
        Steps to reproduce (3.3.18 -> 3.3.19; the same code is in 4.0.0-a2)
      3. Install phpBB 3.3.18.
      4. Change a line in memberlist.php that 3.3.19 also changes.
      5. Run the 3.3.18 -> 3.3.19 automatic update package ("Update filesystem and database"), in the browser or with install/phpbbcli.php update.
         
        Expected: memberlist.php is listed as a merge conflict.
        Actual: no conflict is listed and the updater finishes successfully, but memberlist.php is still the 3.3.18 version. The board silently misses that file's changes, which can include security fixes.
         
        Suggested fix: only treat a conflicted file as merged by the user on a later run, when it is already in the conflict list:
         

        if ($empty && in_array($filename, $merge_conflicts))
        {
        $file_is_merged = true;
        }
        else if (!in_array($filename, $merge_conflicts))
        {
        $merge_conflicts[] = $filename;
        }
        

         
        A PR with this fix and a unit test that runs the real diff_files task (pure conflict, conflict plus other changes, conflict kept by the user on a later run, clean merge, file already equal to the new version) will follow.
         
        PR #6887 (PHPBB-17560) re-indented these lines but kept the condition; its test copies the logic and has no conflicting case, so it did not catch this.

            Unassigned Unassigned
            dmzx dmzx
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: