Summary
Template Toolkit filter callbacks receive an UTF-8 byte string with its decoded/UTF-8 flag incorrectly set on both PerlOnJava execution backends. Filters that use Encode::is_utf8 then skip required decoding and can corrupt non-ASCII input.
CPAN impact
Template::Plugin::DumbQuotes 0.01 failed in CPAN tester run 20260827-171032-2227. Its t/01-basic.t passes decoded Unicode input but fails the Encode::encode_utf8 input case: smart quotes become replacement characters instead of their ASCII replacements.
System Perl baseline
With Template Toolkit 3.106 and the target distribution installed in an isolated library, system Perl 5.42.2 passes the upstream suite: 4 files, 9 tests, Result: PASS. Optional POD checks were skipped because their optional test modules were absent.
Focused reproducer
Create a Unicode string, encode it with Encode::encode_utf8, and inject it between Template FILTER directives. Configure a capture filter that returns Encode::is_utf8($_[0]) ? q(flagged) : q(bytes).
System Perl returns bytes. Both PerlOnJava JVM and interpreter backends return flagged. The raw bytes themselves remain unchanged through Template; the incorrect scalar flag is the distinction.
For Template::Plugin::DumbQuotes, that false flag makes its filter bypass Encode::decode_utf8 and subsequently corrupt the UTF-8 byte input during transliteration.
Acceptance criteria
- Add a project-owned regression test, validated on system Perl, for Template filter callbacks receiving Encode::encode_utf8 input.
- Callback input must remain a byte string unless explicitly decoded.
- The focused test passes on JVM and interpreter backends.
- Template::Plugin::DumbQuotes 0.01 t/01-basic.t passes on both backends.
- Preserve decoded-Unicode Template input behavior.
Summary
Template Toolkit filter callbacks receive an UTF-8 byte string with its decoded/UTF-8 flag incorrectly set on both PerlOnJava execution backends. Filters that use Encode::is_utf8 then skip required decoding and can corrupt non-ASCII input.
CPAN impact
Template::Plugin::DumbQuotes 0.01 failed in CPAN tester run 20260827-171032-2227. Its t/01-basic.t passes decoded Unicode input but fails the Encode::encode_utf8 input case: smart quotes become replacement characters instead of their ASCII replacements.
System Perl baseline
With Template Toolkit 3.106 and the target distribution installed in an isolated library, system Perl 5.42.2 passes the upstream suite: 4 files, 9 tests, Result: PASS. Optional POD checks were skipped because their optional test modules were absent.
Focused reproducer
Create a Unicode string, encode it with Encode::encode_utf8, and inject it between Template FILTER directives. Configure a capture filter that returns Encode::is_utf8($_[0]) ? q(flagged) : q(bytes).
System Perl returns bytes. Both PerlOnJava JVM and interpreter backends return flagged. The raw bytes themselves remain unchanged through Template; the incorrect scalar flag is the distinction.
For Template::Plugin::DumbQuotes, that false flag makes its filter bypass Encode::decode_utf8 and subsequently corrupt the UTF-8 byte input during transliteration.
Acceptance criteria