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:
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:
- It checks
utf8::is_utf8 on each authentication component.
- It calls
utf8::encode only for values marked as decoded Unicode.
- It calls
URI::Escape::uri_escape to percent-escape the resulting bytes.
- 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:
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.
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 upstreamNeo4j-Drivertest suite to fail on both the JVM and interpreter backends.CPAN impact
Neo4j-Driver0.52Neo4j::Driver::ResultColumnst/net-lwp.tauth variations, test 4,uri with latin1 userid20260908-215506-1375The 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 80as the Basic Auth principal and expects those octets to be percent-escaped directly in the URI: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:
The expected URI userinfo is:
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.tpasses completely under system Perl:The focused test fails identically on both PerlOnJava execution backends:
auth variationstest 4auth variationstest 4This 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::LWPdeliberately handles the distinction as follows:utf8::is_utf8on each authentication component.utf8::encodeonly for values marked as decoded Unicode.URI::Escape::uri_escapeto percent-escape the resulting bytes.System Perl preserves the unflagged
C4 80byte 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 bundledURIuserinfo 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-Driver0.52 distribution:The failure is:
Acceptance criteria
C4 80must become%C4%80, not UTF-8-expanded%C3%84%C2%80.%C4%80.Neo4j-Driver0.52t/net-lwp.tpasses completely on both backends.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.