Skip to content

fix(Laravel): fix incorrect URL path construction in httpTarget()#607

Merged
ChrisLightfootWild merged 2 commits into
open-telemetry:mainfrom
zigzagdev:fix/operatoring-precedence-root-cause
Jun 10, 2026
Merged

fix(Laravel): fix incorrect URL path construction in httpTarget()#607
ChrisLightfootWild merged 2 commits into
open-telemetry:mainfrom
zigzagdev:fix/operatoring-precedence-root-cause

Conversation

@zigzagdev

@zigzagdev zigzagdev commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Content

  • Fixed a PHP operator precedence bug in httpTarget() where . (concatenation) has higher precedence than === (strict equality). This caused incorrect path construction when appending query strings.
  • Ensured correct leading slash handling by replacing $request->path() (which strips the leading slash in Laravel) with a robust combination of $request->getBaseUrl() . $request->getPathInfo().
  • Added integration tests covering both root and non-root paths, with and without query strings.

Cause

The original code was evaluated incorrectly due to operator precedence:

$question = $request->getBaseUrl() . $request->getPathInfo() === '/' ? '/?' : '?';
return $query ? $request->path() . $question . $query : $request->path();

This caused the following incorrect behaviors:

  • GET /?foo=bar → URL_PATH = //?foo=bar (double slash)
  • GET /hello?foo=bar → URL_PATH = foo?foo=bar (missing leading slash)

Fixed code:

$path = $request->getBaseUrl() . $request->getPathInfo();

return $query ? $path . '?' . $query : $path;

Test Results

screen shot 2026-06-09 20 13 09

zigzagdev added 2 commits June 9, 2026 20:09
The original code had two bugs caused by PHP operator precedence:

1. The string concatenation operator (.) has higher precedence than the
   strict equality operator (===), so the expression:

     $request->getBaseUrl() . $request->getPathInfo() === '/' ? '/?' : '?'

   was evaluated as:

     ($request->getBaseUrl() . $request->getPathInfo()) === '/' ? '/?' : '?'

   This made $question equal to '/?' only when the full concatenated path
   was exactly '/', not just when getPathInfo() returned '/'.

2. The return statement used $request->path(), which in Laravel strips the
   leading slash for non-root paths (e.g. '/hello' becomes 'foo'), and for
   the root path '/' combined with the '/?' separator would produce '//?' .

These bugs resulted in:
- Root path with query:     '/' + '/?' + query => '//?query'  (double slash)
- Non-root path with query: 'foo' + '?' + query => 'foo?query' (missing leading slash)

Fix by using getBaseUrl() . getPathInfo() consistently as the base path
and appending the query string with a plain '?', which correctly produces:
- Root path with query:     '/?query'
- Non-root path with query: '/hello?query'
The httpTarget() method in the Kernel hook was previously untested,
which allowed the operator precedence bug to go undetected.

Add four integration tests that verify the URL_PATH span attribute
is correctly set for each path pattern:

- test_url_path_root: GET / => URL_PATH = '/'
- test_url_path_non_root: GET /hello => URL_PATH = '/hello'
- test_url_path_root_with_query_string: GET /?foo=bar => URL_PATH = '/?foo=bar'
- test_url_path_with_query_string: GET /hello?foo=bar => URL_PATH = '/hello?foo=bar'

Before the fix, test_url_path_root_with_query_string would have produced
'//?foo=bar' (double slash) and test_url_path_with_query_string would have
produced 'foo?foo=bar' (missing leading slash).
@zigzagdev
zigzagdev requested a review from a team as a code owner June 9, 2026 11:19
@linux-foundation-easycla

linux-foundation-easycla Bot commented Jun 9, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

@zigzagdev
zigzagdev marked this pull request as draft June 9, 2026 11:22
@zigzagdev
zigzagdev marked this pull request as ready for review June 9, 2026 11:28
@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.09%. Comparing base (51e3a1c) to head (b2a9223).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##               main     #607   +/-   ##
=========================================
  Coverage     81.09%   81.09%           
  Complexity     1521     1521           
=========================================
  Files            93       93           
  Lines          5431     5431           
=========================================
  Hits           4404     4404           
  Misses         1027     1027           
Flag Coverage Δ
Context/Swoole 0.00% <ø> (ø)
Exporter/Instana 49.80% <ø> (ø)
Instrumentation/AwsSdk 82.14% <ø> (ø)
Instrumentation/CakePHP 20.42% <ø> (ø)
Instrumentation/CodeIgniter 79.31% <ø> (ø)
Instrumentation/Curl 86.88% <ø> (ø)
Instrumentation/Doctrine 92.82% <ø> (ø)
Instrumentation/ExtAmqp 88.80% <ø> (ø)
Instrumentation/Guzzle 76.25% <ø> (ø)
Instrumentation/HttpAsyncClient 78.94% <ø> (ø)
Instrumentation/HttpConfig 28.76% <ø> (ø)
Instrumentation/IO 0.00% <ø> (ø)
Instrumentation/MongoDB 76.84% <ø> (ø)
Instrumentation/MySqli 93.39% <ø> (ø)
Instrumentation/OpenAIPHP 86.71% <ø> (ø)
Instrumentation/PostgreSql 91.36% <ø> (ø)
Instrumentation/Psr14 77.41% <ø> (ø)
Instrumentation/Psr15 89.74% <ø> (ø)
Instrumentation/Psr16 97.43% <ø> (ø)
Instrumentation/Psr18 79.41% <ø> (ø)
Instrumentation/Psr6 97.56% <ø> (ø)
Instrumentation/Session 94.28% <ø> (ø)
Instrumentation/Slim 84.21% <ø> (ø)
Propagation/CloudTrace 90.69% <ø> (ø)
Propagation/Instana 98.07% <ø> (ø)
Propagation/ServerTiming 94.73% <ø> (ø)
Propagation/TraceResponse 94.73% <ø> (ø)
ResourceDetectors/Azure 91.66% <ø> (ø)
ResourceDetectors/DigitalOcean 100.00% <ø> (ø)
Sampler/Xray 78.38% <ø> (ø)
Shims/OpenTracing 92.99% <ø> (ø)
SqlCommenter 95.58% <ø> (ø)
Utils/Test 87.79% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 51e3a1c...b2a9223. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ChrisLightfootWild ChrisLightfootWild left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix @zigzagdev 👍

@ChrisLightfootWild
ChrisLightfootWild merged commit 31ba9f7 into open-telemetry:main Jun 10, 2026
128 of 175 checks passed
@zigzagdev
zigzagdev deleted the fix/operatoring-precedence-root-cause branch June 10, 2026 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants