Home / Alt manpages / perl5160delta(1)

  • perl5160delta(1)
  • User command
  • linux

Audit Perl 5.16 Compatibility Before You Upgrade

You will finish with a small compatibility check for Perl code that crosses the 5.14 to 5.16 boundary, including feature declarations, Unicode handling, XS extensions and changed runtime behaviour. This is an audit guide, not an instruction to replace the Perl installed by your distribution. Allow 20 to 30 minutes for a small application, plus time to run its own test suite.

The local reference is perl5160delta(1) from the perl-doc package. Its header describes Perl 5.16.0, while the installed interpreter used for the checks here is Perl 5.38.2. That distinction matters: the examples confirm syntax and behaviour available in the current interpreter, but the change list is specifically the 5.14 to 5.16 release boundary.

1. Record the interpreter you are testing

Start by recording the executable and version. Run this as an ordinary user:

$ command -v perl
/usr/bin/perl
$ perl -v | sed -n '1,4p'

This is perl 5, version 38, subversion 2 (v5.38.2) built for x86_64-linux-gnu-thread-multi

Do not treat a passing test under 5.38 as proof that a 5.16 deployment will behave identically. Use the version that your application will actually run, and keep the release notes beside the test results.

Checkpoint

Write down the full perl -v output and the path from command -v. If several Perls are installed, an apparently successful check can simply be testing the wrong one.

2. Make the feature boundary explicit

Perl 5.16 changed version declarations so that use v5.16 disables previously enabled features before applying the new bundle. A later declaration can therefore remove features rather than add to the earlier declaration. Test the code in a clean process, because feature state is lexical and an interactive shell can obscure where it came from:

$ perl -e 'use v5.16; print "version declaration accepted\n"'
version declaration accepted
$ perl -e 'use v5.16; use feature "fc"; print fc("Straße"), "\n"'
straße

The second command exercises the new Unicode foldcase function. Foldcase is intended for better case-insensitive comparison than a simple lowercase operation. It is not a request to normalise text, transliterate it or change how a file is encoded.

Review every module that declares a Perl version or calls use feature. Pay special attention to code that expects an earlier feature bundle to remain active after a later version declaration. If you need the old default feature set, the 5.16 release adds the :default bundle; if you really need no features, use no feature ':all'.

3. Check eval and substr call sites

Perl 5.16 makes string evaluation more consistent. With the new unicode_eval feature, eval $string treats its input as Unicode. The matching evalbytes function evaluates a byte string. Test code that evaluates generated source, especially code that receives data from a file or a network:

$ perl -e 'use v5.16; use feature "unicode_eval", "evalbytes"; eval "print qq(unicode\n)"; evalbytes("print qq(bytes\n)")'
unicode
bytes

Do not use either form as a substitute for input validation. Evaluating untrusted source remains code execution. The practical upgrade task is to decide whether each existing call expects characters or bytes, then add tests for non-ASCII input and for the error path reported by $@.

Also audit lvalue substr. In 5.16, the offsets in a returned lvalue are retained until that lvalue is read or modified. A negative offset can therefore refer to a different position if the original string changes length first. That is an incompatible behaviour change, so search for assignments through a substr lvalue and test them after the source string is changed.

use v5.16;
my $text = 'abcdef';
my $part = substr $text, -2, 1;
$text = 'longer text';
$part = 'X';
print "$text\n";

The exact replacement depends on the intended semantics. If the position should be fixed when the call is made, calculate and copy the value before changing the source string. Do not assume that a successful compile preserves the old result.

4. Review Unicode and locale assumptions

The release notes cover almost Unicode 6.1 support, new property aliases, Script_Extensions, Unicode symbol names and improved mixing of locales with Unicode. Existing tests that compare property names or character categories deserve a second look. Unicode 6.1 also changed some character properties and the behaviour of \X for some Thai and Lao characters.

For new code, use Perl's documented Unicode APIs rather than reading files below the interpreter's lib/unicore directory. The release notes deprecate direct database-file access and point callers towards Unicode::UCD. This is particularly relevant to deployment checks: a path that exists in one Perl installation is not a stable interface for another.

Keep the locale boundary visible. The 5.16 release adds use locale ':not_characters', which leaves locale handling in place except for character-set assumptions. Test this only where the application genuinely combines locale-sensitive operations with UTF-8 data. A locale setting is process state, so record LC_ALL, LC_CTYPE and LANG with the test result.

5. Audit XS and security-sensitive code

If the application has XS modules, this is the highest-value part of the review. The old is_utf8_char(), utf8_to_uvchr() and utf8_to_uvuni() APIs can read beyond the end of malformed input because their interfaces do not carry enough buffer-length information. Perl 5.16 adds buffer-aware alternatives, including is_utf8_char_buf(), utf8_to_uvchr_buf() and utf8_to_uvuni_buf().

Search extension source, generated bindings and vendored modules:

$ rg -n 'is_utf8_char|utf8_to_uvchr|utf8_to_uvuni' path/to/project path/to/local/modules

Replace an old call only after checking the function's arguments and return handling against the installed Perl headers and API documentation. Then build with warnings enabled and run malformed UTF-8 tests. Do not silence the deprecation warning or treat a clean build as proof that length handling is correct.

The same release fixes a File::Glob::bsd_glob() memory error when an unsupported GLOB_ALTDIRFUNC flag came from external input. Do not pass flags from configuration or a request directly into globbing APIs without checking the supported values. This is a code-review boundary, not a command-line switch to enable.

6. Exercise incompatible changes before deployment

Read the release notes' incompatible-changes section against your code, rather than scanning only the headline features. Useful searches include special blocks such as BEGIN and END, regexp objects under no overloading, removed XS typemap entries, deprecated Unicode properties, PID and UID variables, and code that relies on old quotemeta behaviour.

$ rg -n 'BEGIN|CHECK|INIT|UNITCHECK|END|no overloading|quotemeta|GLOB_ALTDIRFUNC|is_utf8_' lib bin t xs
$ prove -lr t

Use your project's normal test command if it is not prove. Do not run tests as root to hide permission failures. No step in this guide needs elevated privileges, and changing the system Perl or rebuilding it is outside the safe scope of a compatibility audit.

Done means

  • The exact Perl executable and version used for testing are recorded.
  • Version declarations and feature bundles have an intentional, tested boundary.
  • String eval, evalbytes and lvalue substr call sites have tests for their actual data model.
  • Unicode property, locale and lib/unicore assumptions have been reviewed.
  • XS code no longer relies blindly on length-unsafe UTF-8 APIs.
  • The full application test suite passes without changing privileges or the system interpreter.