Page MenuHomePhorge

Bug: Unhandled Exception ("Exception") - Diff Parse Exception: Expected '\ No newline at end of file'.
Open, Needs TriagePublic

Description

When browsing my repository hosted inside Phorge, I see the following exception showing up:

Diff Parse Exception: Expected '\ No newline at end of file'.

            342    
            343    [… diff content]
            344    [… diff content]
            345    [… diff content]
            346    [… diff content]
   >>>      347   \ Nincs új sor a fájl végén

Backtrace:

arcanist(head=master, ref.master=8426ebc053b3), phorge(head=master, ref.master=0a17287e08cd)
  #0 <#2> ArcanistDiffParser::didFailParse(string) called at [<arcanist>/src/parser/ArcanistDiffParser.php:959]
  #1 <#2> ArcanistDiffParser::parseChangeset(ArcanistDiffChange) called at [<arcanist>/src/parser/ArcanistDiffParser.php:350]
  #2 <#2> ArcanistDiffParser::parseDiff(string) called at [<phorge>/src/infrastructure/diff/PhabricatorDifferenceEngine.php:143]
  #3 <#2> PhabricatorDifferenceEngine::generateChangesetFromFileContent(string, string) called at [<phorge>/src/applications/differential/parser/DifferentialChangesetParser.php:1481]
  #4 <#2> DifferentialChangesetParser::realignDiff(DifferentialChangeset, DifferentialHunkParser) called at [<phorge>/src/applications/differential/parser/DifferentialChangesetParser.php:637]
  #5 <#2> DifferentialChangesetParser::process() called at [<phorge>/src/applications/differential/parser/DifferentialChangesetParser.php:624]
  #6 <#2> DifferentialChangesetParser::tryCacheStuff() called at [<phorge>/src/applications/differential/parser/DifferentialChangesetParser.php:791]
  #7 <#2> DifferentialChangesetParser::render(NULL, NULL, array) called at [<phorge>/src/applications/differential/parser/DifferentialChangesetParser.php:76]
  #8 <#2> DifferentialChangesetParser::renderChangeset() called at [<phorge>/src/applications/differential/parser/DifferentialChangesetParser.php:1902]
  #9 <#2> DifferentialChangesetParser::newChangesetResponse() called at [<phorge>/src/applications/diffusion/controller/DiffusionDiffController.php:141]
  #10 <#2> DiffusionDiffController::handleRequest(AphrontRequest) called at [<phorge>/src/aphront/configuration/AphrontApplicationConfiguration.php:284]
  #11 phlog(Exception) called at [<phorge>/src/aphront/handler/PhabricatorDefaultRequestExceptionHandler.php:41]
  #12 PhabricatorDefaultRequestExceptionHandler::handleRequestThrowable(AphrontRequest, Exception) called at [<phorge>/src/aphront/configuration/AphrontApplicationConfiguration.php:751]
  #13 AphrontApplicationConfiguration::handleThrowable(Exception) called at [<phorge>/src/aphront/configuration/AphrontApplicationConfiguration.php:296]
  #14 AphrontApplicationConfiguration::processRequest(AphrontRequest, PhutilDeferredLog, AphrontPHPHTTPSink, MultimeterControl) called at [<phorge>/src/aphront/configuration/AphrontApplicationConfiguration.php:204]
  #15 AphrontApplicationConfiguration::runHTTPRequest(AphrontPHPHTTPSink) called at [<phorge>/webroot/index.php:35]

My locale is Hungarian and at the end it says exactly "No newline at end of file" just in another language.

Reproducer:

echo A > a.txt
echo -n A > b.txt
diff a.txt b.txt
LC_ALL=C diff a.txt b.txt 
--- a.txt       2023-06-30 16:57:35.309109363 +0200
+++ b.txt       2023-06-30 16:57:40.837179111 +0200
@@ -1 +1 @@
-A
+A
\ No newline at end of file
LC_ALL=hu_HU.UTF-8 diff a.txt b.txt 
--- a.txt       2023-06-30 16:57:35.309109363 +0200
+++ b.txt       2023-06-30 16:57:40.837179111 +0200
@@ -1 +1 @@
-A
+A
\ Nincs új sor a fájl végén

Event Timeline

Where exactly are you seeing this error? what page exactly?

It is on Diffusion > My repository > Selected commit SHA diff page. E.g. https://<domain>/R1:abdcdefgh

(I'm able to reproduce. Had to apt-get install language-pack-hu for that...)

I think these two are related here:

I'm going to dig deeper to see if I have the E issue (using the php devserver) and if adding it back fixes the exception.

  • the setlocal isn't supposed to make a difference (it only applies the command string itself - ie if a file is named 🧆.txt.
  • Setting E is more likely to cause this problem then to solve it...

The execution (PhabricatorDifferenceEngine.php, line 96) goes through this code in ExecFuture:

if ($this->hasEnv()) {
  $env = $this->getEnv();
} else {
  $env = null;
}

where hasEnv() is false. getEnv() (PhutilExecutableFuture) also checks if hasEnv(), and if it's false it creates one using $_ENV (which is empty if no E) and 2 more important phorge-specific envvars.

Since hasEnv() is false here, $env is null, which tells proc_open to use "same environment as the current PHP process". if E is missing, this is basically empty, and the thing will use the system's default locale (POSIX for me).

I think the best solution would be to (1) add LC_ALL=en_us to the getEnv default environment and (2) always get the default env, even if no env was explicitly configured.