Page MenuHomePhorge

PHP 8.1 fix strpos(NULL, string) called at [<arcanist>/src/xsprintf/PhutilCommandString.php:98]
Closed, ResolvedPublic

Description

As reported by the kind user @ton from T15249, here another bug related to PHP 8.1 and its deprecations:

> arc patch D39921 --trace
 ARGV  /home/ngor/src/we.phorge.it/arcanist/bin/arc patch D39921 --trace
 PCNTL  Unable to install signal handler, pcntl_signal() unavailable. Continuing without signal handling.
>>> [0] (+0) <exec> $ php -f /opt/ngor/src/we.phorge.it/arcanist/scripts/arcanist.php -- patch D39921 --trace
 ARGV  /opt/ngor/src/we.phorge.it/arcanist/scripts/arcanist.php patch D39921 --trace
 LOAD  Loaded "arcanist" from "/opt/ngor/src/we.phorge.it/arcanist/src".
Config: Reading user configuration file "/home/ngor/.arcrc"...
Config: Did not find system configuration at "/etc/arcconfig".
Working Copy: Reading .arcconfig from "/opt/ngor/src/git.freebsd.org/src/.arcconfig".
Working Copy: Path "/opt/ngor/src/git.freebsd.org/src" is part of `git` working copy "/opt/ngor/src/git.freebsd.org/src".
Working Copy: Project root is at "/opt/ngor/src/git.freebsd.org/src".
Config: Did not find local configuration at "/opt/ngor/src/git.freebsd.org/src/.git/arc/config".
>>> [0] (+0) <http> https://reviews.freebsd.org/api/differential.querydiffs
<<< [0] (+219) <http> 219,490 us
>>> [1] (+219) <http> https://reviews.freebsd.org/api/user.whoami
<<< [1] (+305) <http> 85,161 us
>>> [2] (+305) <http> https://reviews.freebsd.org/api/differential.querydiffs
<<< [2] (+930) <http> 624,826 us
>>> [3] (+938) <http> https://reviews.freebsd.org/api/repository.query
<<< [3] (+1,022) <http> 83,898 us
>>> [4] (+1,023) <exec> $ git --version
<<< [4] (+1,030) <exec> 6,678 us
>>> [5] (+1,030) <exec> $ git status --porcelain=2 -z
<<< [5] (+1,313) <exec> 283,060 us
>>> [6] (+1,314) <exec> $ git show -s --format='%H' 8feec73d016f6d87c9dbc35defe1bd3300a0f20f --
<<< [6] (+1,320) <exec> 5,889 us
 INFO  Base commit is not in local repository; trying to fetch.
>>> [7] (+1,321) <exec> $ git fetch --quiet --all
<<< [7] (+5,063) <exec> 3,742,644 us
>>> [8] (+5,064) <exec> $ git show -s --format='%H' 8feec73d016f6d87c9dbc35defe1bd3300a0f20f --
<<< [8] (+5,070) <exec> 6,081 us
>>> [9] (+5,070) <exec> $ git symbolic-ref --quiet HEAD
<<< [9] (+5,075) <exec> 4,291 us
>>> [10] (+5,075) <exec> $ git rev-parse --verify arcpatch-D39921
<<< [10] (+5,078) <exec> 3,146 us
Branch name arcpatch-D39921 already exists; trying a new name.
>>> [11] (+5,079) <exec> $ git rev-parse --verify arcpatch-D39921_1
<<< [11] (+5,083) <exec> 3,992 us
>>> [12] (+5,083) <exec> $ git checkout -b arcpatch-D39921_1
<<< [12] (+5,089) <exec> 6,089 us
>>> [13] (+5,090) <exec> $ git submodule update --init --recursive
<<< [13] (+5,126) <exec> 35,806 us
Created and checked out branch arcpatch-D39921_1.
>>> [14] (+5,126) <http> https://reviews.freebsd.org/api/differential.query
<<< [14] (+5,218) <http> 91,929 us
>>> [15] (+5,219) <http> https://reviews.freebsd.org/api/differential.query
<<< [15] (+5,309) <http> 90,113 us

[2023-05-07 02:52:37] EXCEPTION: (RuntimeException) strpos(): Passing null to parameter #1 ($haystack) of type string is deprecated at [<arcanist>/src/error/PhutilErrorHandler.php:261]
arcanist(head=master, ref.master=d47289622650)
  #0 PhutilErrorHandler::handleError(integer, string, string, integer)
  #1 strpos(NULL, string) called at [<arcanist>/src/xsprintf/PhutilCommandString.php:98]
  #2 PhutilCommandString::escapeLinux(NULL) called at [<arcanist>/src/xsprintf/PhutilCommandString.php:61]
  #3 PhutilCommandString::escapeArgument(NULL, string) called at [<arcanist>/src/xsprintf/csprintf.php:118]
  #4 xsprintf_command(array, string, integer, NULL, integer) called at [<arcanist>/src/xsprintf/xsprintf.php:82]
  #5 xsprintf(string, array, array) called at [<arcanist>/src/xsprintf/PhutilCommandString.php:41]
  #6 PhutilCommandString::renderString(boolean) called at [<arcanist>/src/xsprintf/PhutilCommandString.php:32]
  #7 PhutilCommandString::getMaskedString() called at [<arcanist>/src/xsprintf/PhutilCommandString.php:20]
  #8 PhutilCommandString::__construct(array) called at [<arcanist>/src/xsprintf/csprintf.php:37]
  #9 csprintf(string, string, NULL) called at [<arcanist>/src/future/exec/PhutilExecutableFuture.php:28]
  #10 PhutilExecutableFuture::__construct(string, string, NULL)
  #11 ReflectionClass::newInstanceArgs(array) called at [<arcanist>/src/utils/utils.php:803]
  #12 newv(string, array) called at [<arcanist>/src/repository/api/ArcanistGitAPI.php:23]
  #13 ArcanistGitAPI::buildLocalFuture(array) called at [<arcanist>/src/repository/api/ArcanistRepositoryAPI.php:399]
  #14 ArcanistRepositoryAPI::execxLocal(string, string, NULL) called at [<arcanist>/src/repository/api/ArcanistGitAPI.php:606]
  #15 ArcanistGitAPI::getCanonicalRevisionName(NULL) called at [<arcanist>/src/repository/api/ArcanistGitAPI.php:1146]
  #16 ArcanistGitAPI::hasLocalCommit(NULL) called at [<arcanist>/src/differential/ArcanistDifferentialDependencyGraph.php:45]
  #17 ArcanistDifferentialDependencyGraph::loadEdges(array) called at [<arcanist>/src/utils/AbstractDirectedGraph.php:243]
  #18 AbstractDirectedGraph::loadGraph() called at [<arcanist>/src/workflow/ArcanistPatchWorkflow.php:1139]
  #19 ArcanistPatchWorkflow::buildDependencyGraph(ArcanistBundle) called at [<arcanist>/src/workflow/ArcanistPatchWorkflow.php:934]
  #20 ArcanistPatchWorkflow::applyDependencies(ArcanistBundle) called at [<arcanist>/src/workflow/ArcanistPatchWorkflow.php:470]
  #21 ArcanistPatchWorkflow::run() called at [<arcanist>/src/workflow/ArcanistPatchWorkflow.php:399]
  #22 ArcanistPatchWorkflow::run() called at [<arcanist>/scripts/arcanist.php:427]
<<< [0] (+5,342) <exec> 5,342,036 us

Very probably a solution could be:

src/xsprintf/PhutilCommandString.php
  public static function escapeArgument($value, $mode) {
    if ($mode === self::MODE_DEFAULT) {
      if (phutil_is_windows()) {
        $mode = self::MODE_WINDOWS;
      } else {
        $mode = self::MODE_LINUX;
      }
    }

+    if($value === null) {
+      $value = '';
+    }

    switch ($mode) {
      case self::MODE_LINUX:
        return self::escapeLinux($value);
      case self::MODE_WINDOWS:
        return self::escapeWindows($value);
      case self::MODE_POWERSHELL:
        return self::escapePowershell($value);
      default:
        throw new Exception(pht('Unknown escaping mode!'));
    }
  }

Event Timeline

valerio.bozzolan triaged this task as Normal priority.
valerio.bozzolan created this object in space S1 Public.

Hi @ton can I ask you if, manually patching Arcanist with the indicated diff in the Task description, fixes for you?

Or, probably you will unlock a different exception. In that case feel free to share also that :D

As you can see under T15064 we are hammering a lot Phorge and Arcanist in these days to fix all of these, so I would expect to have this working soon also thanks to these very useful reports.

This seems to have fixed the problem. But let me try a bit more Diffs to be extra sure

arc patch problem is likely fixed. But I encountered similar problem here
https://we.phorge.it/T15351#8287

> arc look remotes
 <!> Arcventure

You follow a wide, straight path to the north and arrive in a grove of fruit
trees after a few minutes of walking. The grass underfoot is thick and small
insects flit through the air.

At the far edge of the grove, you see remotes:

[2023-05-08 00:46:54] EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [<arcanist>/src/error/PhutilErrorHandler.php:261]
arcanist(head=master, ref.master=d47289622650)
  #0 PhutilErrorHandler::handleError(integer, string, string, integer) called at [<arcanist>/src/utils/PhutilUTF8StringTruncator.php:90]
  #1 PhutilUTF8StringTruncator::truncateString(NULL) called at [<arcanist>/src/ref/ArcanistRefView.php:103]
  #2 ArcanistRefView::newLines(integer) called at [<arcanist>/src/ref/ArcanistRefView.php:66]
  #3 ArcanistRefView::newTerminalString() called at [<arcanist>/src/xsprintf/PhutilTerminalString.php:36]
  #4 PhutilTerminalString::escapeStringValue(ArcanistRefView, boolean) called at [<arcanist>/src/xsprintf/tsprintf.php:31]
  #5 xsprintf_terminal(NULL, string, integer, ArcanistRefView, integer) called at [<arcanist>/src/xsprintf/xsprintf.php:82]
  #6 xsprintf(string, NULL, array) called at [<arcanist>/src/xsprintf/tsprintf.php:19]
  #7 tsprintf(string, ArcanistRefView) called at [<arcanist>/src/workflow/ArcanistLookWorkflow.php:200]
  #8 ArcanistLookWorkflow::lookRemotes() called at [<arcanist>/src/workflow/ArcanistLookWorkflow.php:41]
  #9 ArcanistLookWorkflow::runWorkflow(PhutilArgumentParser) called at [<arcanist>/src/workflow/ArcanistWorkflow.php:227]
  #10 ArcanistWorkflow::executeWorkflow(PhutilArgumentParser) called at [<arcanist>/src/toolset/ArcanistPhutilWorkflow.php:21]
  #11 ArcanistPhutilWorkflow::execute(PhutilArgumentParser) called at [<arcanist>/src/parser/argument/PhutilArgumentParser.php:492]
  #12 PhutilArgumentParser::parseWorkflowsFull(array) called at [<arcanist>/src/runtime/ArcanistRuntime.php:171]
  #13 ArcanistRuntime::executeCore(array) called at [<arcanist>/src/runtime/ArcanistRuntime.php:37]
  #14 ArcanistRuntime::execute(array) called at [<arcanist>/support/init/init-arcanist.php:6]
  #15 require_once(string) called at [<arcanist>/bin/arc:10]

Could the fix be as easy?

ton claimed this task.

Note that probably @ton you have resolved, but anybody else nope :D The patch D25205 still needs review and land

@valerio.bozzolan right, I forgot the important bit, sorry :D

Yeah no problem!