Skip to content

Fix byte-string URI userinfo encoding in Neo4j::Driver HTTP adapter #1313

Description

@fglock

Summary

PerlOnJava incorrectly UTF-8-encodes a Perl byte string when serializing HTTP Basic Authentication userinfo in Neo4j::Driver::Net::HTTP::LWP. This causes the upstream Neo4j-Driver test suite to fail on both the JVM and interpreter backends.

CPAN impact

  • Distribution: Neo4j-Driver 0.52
  • Affected module selected by the tester: Neo4j::Driver::ResultColumns
  • Failing test program: t/net-lwp.t
  • Failing subtest: auth variations, test 4, uri with latin1 userid
  • CPAN run: 20260908-215506-1375
  • PerlOnJava result: 1 of 119 subtests failed; 1 of 21 test programs failed

The other failures reported by neither the suite nor the environment are absent: the remaining tests pass or skip normally because no Neo4j server is available.

Observed behavior

The upstream test passes a byte string containing the octets C4 80 as the Basic Auth principal and expects those octets to be percent-escaped directly in the URI:

expected: %C4%80
actual:   %C3%84%C2%80

The actual value treats the two Latin-1 bytes as Unicode characters U+00C4 and U+0080, then encodes each character as UTF-8 before percent escaping. The resulting URI is:

http://%C3%84%C2%80:@net.test/

The expected URI userinfo is:

http://%C4%80:@net.test/

The same test also verifies a genuinely Unicode password (U+0100); that case passes, so the failure specifically distinguishes byte-string and decoded-Unicode semantics.

Oracle and backend comparison

The unchanged upstream t/net-lwp.t passes completely under system Perl:

Files=1, Tests=14
Result: PASS

The focused test fails identically on both PerlOnJava execution backends:

  • JVM backend: fails auth variations test 4
  • Interpreter backend: fails auth variations test 4

This is therefore a shared PerlOnJava scalar/Unicode representation issue, not a compiler-backend difference, missing Neo4j server, timeout, or native dependency problem.

Suspected ownership

Neo4j::Driver::Net::HTTP::LWP deliberately handles the distinction as follows:

  1. It checks utf8::is_utf8 on each authentication component.
  2. It calls utf8::encode only for values marked as decoded Unicode.
  3. It calls URI::Escape::uri_escape to percent-escape the resulting bytes.
  4. It stores the escaped userinfo in a cloned URI.

System Perl preserves the unflagged C4 80 byte string through this path. PerlOnJava instead causes the bytes to be observed/serialized as characters before URI userinfo serialization, producing the extra UTF-8 expansion. The likely ownership is in PerlOnJava byte-string flag/representation handling or the bundled URI userinfo serialization path. The upstream adapter code should not be changed to special-case this input because its current logic matches standard Perl behavior.

Reproduction

Run the upstream test from the Neo4j-Driver 0.52 distribution:

t/net-lwp.t

The failure is:

Failed test 'uri with latin1 userid'
'http://%C3%84%C2%80:@net.test/' doesn't match '(?^i://%C4%80:@)'

Acceptance criteria

  • Add a project-owned regression test for URI userinfo serialization of an unflagged byte string containing octets above 0x7f.
  • Validate the regression test against system Perl before using it as the PerlOnJava oracle.
  • Preserve direct byte escaping: C4 80 must become %C4%80, not UTF-8-expanded %C3%84%C2%80.
  • Preserve decoded-Unicode behavior: U+0100 must continue to serialize as %C4%80.
  • The focused regression passes on both JVM and interpreter backends.
  • Neo4j-Driver 0.52 t/net-lwp.t passes completely on both backends.
  • Avoid regressing ordinary ASCII userinfo, already percent-escaped userinfo, and URI behavior for normal decoded Unicode values.

Related byte/Unicode issues #1182, #1183, and #1189 may involve neighboring representation boundaries, but none currently covers URI userinfo percent-encoding or this reproducible failure.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:unicodeUnicode and encoding behaviorbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions