内容

名称

perl5240delta - perl v5.24.0 的新增功能

说明

本文档描述了 5.22.0 版本和 5.24.0 版本之间的差异。

核心增强

后缀解除引用不再是实验性的

使用 postderefpostderef_qq 功能不再会发出警告。以前禁用他们之前使用的 experimental::postderef 警告类别的现有代码将继续工作。postderef 功能不起作用;所有 Perl 代码都可以使用后缀解除引用,无论作用域中有什么功能声明。5.24 功能包现在包括 postderef_qq 功能。

现在支持 Unicode 8.0

有关此版本中内容的详细信息,请参阅 http://www.unicode.org/versions/Unicode8.0.0/

现在 perl 将在关闭就地输出文件失败时发出 croak

到目前为止,未检测到关闭就地编辑的输出文件失败,这意味着输入文件可能会在编辑未成功完成的情况下被覆盖。现在,当无法成功关闭输出文件时,将引发异常。

正则表达式中的新 \b{lb} 边界

lb 代表换行符。它是一个 Unicode 属性,用于确定文本行适合换行的位置(通常是为了在不溢出可用水平空间的情况下输出)。此功能长期以来一直由 Unicode::LineBreak 模块提供,但现在核心 Perl 中有一个轻量级、不可自定义的版本,适用于许多目的。

qr/(?[ ])/ 现在可在 UTF-8 区域设置中工作

扩展方括号字符类 现在在 use locale 生效时将成功编译。已编译的模式将使用标准 Unicode 规则。如果运行时区域设置不是 UTF-8 区域设置,则会发出警告,并且无论如何都会使用标准 Unicode 规则。由于结果实际上不依赖于区域设置,因此不会进行污染。

整数移位 (<<>>) 现在定义得更明确

负移位是反向移位:左移位变为右移位,右移位变为左移位。

使用本机整数(或更多)中的位数移位为零,但当在 use integer 下对负值进行“过移位”时除外,在这种情况下,结果为 -1(算术移位)。

到目前为止,负移位和过移位尚未定义,因为它们依赖于 C 实现碰巧要执行的操作。例如,对于过移位,常见的 C 行为是“模移位”

1 >> 64 == 1 >> (64 % 64) == 1 >> 0 == 1  # Common C behavior.

# And the same for <<, while Perl now produces 0 for both.

现在,无论底层 C 实现如何,这些行为在 Perl 下都定义得很好。但是,请注意,您仍然受到本机整数宽度限制:您需要知道可以向左移动多远。例如,您可以使用

use Config;
my $wordbits = $Config{uvsize} * 8;  # Or $Config{uvsize} << 3.

如果您需要在左移位上使用更多位,则可以使用例如 bigint pragma 或 CPAN 中的 Bit::Vector 模块。

printf 和 sprintf 现在允许重新排序精度参数

也就是说,sprintf '|%.*2$d|', 2, 3 现在返回 |002|。这扩展了现有的重新排序机制(允许对用作格式字段、宽度和矢量分隔符的参数进行重新排序)。

使用 SA_SIGINFOsigaction 回调提供更多字段

SA_SIGINFO 标志传递给 sigaction 时,如果平台支持,现在将 errnostatusuidpidaddrband 字段包含在传递给处理程序的哈希中。

到 Perl 6 的 Hashbang 重定向

以前,如果 perl 找到 hashbang 路径,它会重定向到另一个解释器,除非路径包含“perl”(请参阅 perlrun)。为了提高与 Perl 6 的兼容性,此行为已扩展为在“perl”后跟“6”时也进行重定向。

安全性

在调用 mkstemp(3) 之前设置适当的 umask

在 5.22 中,perl 开始在调用 mkstemp(3) 之前将 umask 设置为 0600,并在之后恢复它。这错误地告知 open(2) 在应用给定模式之前从该模式中剥离所有者读写位,而不是只保留那些位。

mkstemp(3) 中使用模式 0666 的系统(如旧版本的 glibc)会创建一个权限为 0066 的文件,无论当前 umask 如何,都会保留世界读写权限。

通过改用 umask 0177 已经修复了此问题。[perl #127322]

修复 Win32 路径处理中的越界访问

这是 CVE-2015-8608。有关更多信息,请参阅 [GH #15067]

修复 canonpath 中的 taint 丢失

这是 CVE-2015-8607。有关更多信息,请参阅 [GH #15084]

避免在 win32 crypt() 中访问未初始化的内存

添加了验证,该验证将检测盐中的短盐和无效字符。 [GH #15091]

environ 中删除重复的环境变量

以前,如果环境变量在 environ[] 中出现多次,则 %ENV 将包含该名称的最后一个条目,而典型的 getenv() 将返回第一个条目。我们现在确保 %ENV 包含与 getenv 返回的内容相同的内容。

其次,我们从 environ[] 中删除重复项,因此如果在 %ENV 中设置了具有该名称的设置,我们不会向子进程传递不安全的值。

[CVE-2016-2381]

不兼容的更改

autoderef 特性已被删除

实验性 autoderef 特性(允许对标量参数调用 pushpopshiftunshiftsplicekeysvalueseach)已被视为不成功。它现已删除;尝试使用该特性(或禁用它先前触发的 experimental::autoderef 警告)现在会产生异常。

词法 $_ 已被删除

my $_ 在 Perl 5.10 中引入,随后引起了很多混乱,没有明显的解决方案。在 Perl 5.18.0 中,它被设为实验性,理论上它将被删除或以一种不太混乱(但向后不兼容)的方式重新设计。在随后的几年里,没有提出任何替代方案。该特性现已删除,并且无法编译。

qr/\b{wb}/ 现在根据 Perl 预期进行定制

现在更适合作为普通 \b 的直接替换,但为解析自然语言提供了更好的结果。以前它严格遵循当前的 Unicode 规则,要求它在每个空白字符之间匹配。现在它通常不会在空白范围内匹配,表现得像 \b 一样。请参阅 perlrebackslash 中的“\b{wb}”

正则表达式编译错误

一些在运行时出错的正则表达式模式现在根本无法编译。

现在在模式编译时检查使用 \p{}\P{} 正则表达式模式构造的几乎所有 Unicode 属性的有效性,无效的属性将导致程序无法编译。在早期版本中,此检查通常会推迟到运行时。每当错误检查从运行时移到编译时,错误代码就会 100% 被捕获,而之前只有在实际执行违规部分时才会被捕获,对于不可达的代码来说,可能永远不会被捕获。

现在在 use re "strict" 下不允许使用 qr/\N{}/

\N{} 没有意义,但为了向后兼容,它被接受为不执行任何操作,尽管默认情况下会发出弃用警告。但现在在实验性特性 "re 中的 'strict' 模式"下,这是一个致命错误。

现在不允许嵌套声明

不再允许在另一个 myourstate 声明内进行 myourstate 声明。

例如,这些现在是致命的

my ($x, my($y));
our (my $x);

[GH #14799]

[GH #13548]

/\C/ 字符类已被移除。

此正则表达式字符类在 v5.20.0 中已弃用,并且自 v5.22.0 以来一直产生弃用警告。现在它是一个编译时错误。如果您需要检查构成 UTF8 编码字符的各个字节,请首先对字符串(或副本)使用 utf8::encode()

chdir('') 不再 chdir 到主目录

自 perl v5.8 以来,使用 chdir('')chdir(undef) 来 chdir 到主目录已弃用,现在将失败。请改用 chdir()

变量名中的 ASCII 字符现在必须全部可见

到目前为止,在 ASCII 平台上,变量名可以包含非图形 ASCII 控制字符(序数 0 到 31 以及 127,即 C0 控制和 DELETE)是合法的。此用法自 v5.20 起已弃用,并且现在会导致语法错误。这些名称引用的变量是特殊的,由 Perl 保留,供其在现在或将来选择使用。每个此类变量都有另一种拼写方式。它不使用单个非图形控制字符,而是使用以脱字符号开头的两个字符序列,如 $^]${^GLOBAL_PHASE}。详情请参阅 perlvar。在不在 use utf8 下使用变量名中某些非图形非 ASCII 字符仍然是合法的,尽管不明智且已弃用(会引发弃用警告)。任何代码都不应该这样做,因为所有此类变量都由 Perl 保留,而 Perl 目前没有定义任何此类变量(但可以在任何时候不经通知地进行定义)。

$Carp::MaxArgNums 中的一个 off by one 问题已得到修复

$Carp::MaxArgNums 应该是要显示的参数数量。在此版本之前,它相反显示 $Carp::MaxArgNums + 1 个参数,这与文档相反。

现在只允许在 (?[...]) 中的 [...] 中使用空格和制表符。

实验性的扩展方括号字符类可以在其中包含常规方括号字符类。它们与常规方括号字符类不同,因为通常会忽略空格,除非在空格前加上反斜杠进行转义。现在,被忽略的空格仅限于制表符 \t 和空格字符。以前,它可以是任何空格。请参阅 "perlrecharclass 中的“扩展方括号字符类”

弃用

现在弃用使用高于平台的 IV_MAX 的代码点

Unicode 定义范围在 0..0x10FFFF 内的代码点。一些标准曾经将它们定义为最高 2**31 - 1,但 Perl 允许它们达到所用平台上的单词所能容纳的最高值。但是,在某些构造中使用高于平台的 IV_MAX 的代码点会中断,尤其是 tr///、涉及量词的正则表达式模式,以及一些算术和比较操作,例如作为循环的上限。现在,使用此类代码点会引发弃用警告,除非关闭该警告类别。IV_MAX 在 32 位平台上通常为 2**31 -1,在 64 位平台上为 2**63-1。

弃用对包含高于 0xFF 的代码点的字符串执行按位操作

字符串按位运算符将其操作数视为字节字符串,而超出 0xFF 的值在此上下文中毫无意义。若要对编码的字节进行操作,请首先对字符串进行编码。若要对代码点的数字值进行操作,请使用 splitmap ord。将来,此警告将被异常替换。

sysread()syswrite()recv()send() 在 :utf8 句柄上已弃用

sysread()recv()syswrite()send() 运算符在具有 :utf8 层的句柄上已弃用,无论该层是显式的还是隐式的,例如,在 :encoding(UTF-16LE) 层中。

sysread()recv() 目前仅对流使用 :utf8 标志,而忽略实际层。由于 sysread()recv() 不执行 UTF-8 验证,因此最终可能会创建编码无效的标量。

类似地,syswrite()send() 仅使用 :utf8 标志,否则会忽略任何层。如果设置了该标志,则两者都会以 UTF-8 编码写入值,即使该层是某种不同的编码,例如上面的示例。

理想情况下,所有这些运算符都将完全忽略 :utf8 状态,仅使用字节,但这会导致在不知不觉中中断现有代码。为了避免这种情况,未来版本的 perl 将在对具有 :utf8 层的句柄调用 sysread()recv()syswrite()send() 时引发异常。

性能增强

模块和实用程序

已更新的模块和实用程序

文档

现有文档的更改

perlapi

perlcall

perlfunc

perlguts

perllocale

perlmodlib

perlop

perlpolicy

perlreftut

perlrebackslash

perlsub

perlsyn

perltie

perlunicode

perlvar

perlxs

诊断

以下内容已添加到诊断输出中,包括警告和致命错误消息。有关诊断消息的完整列表,请参阅 perldiag

新诊断

新错误

新警告

对现有诊断的更改

配置和编译

测试

平台支持

特定于平台的说明

AmigaOS
  • AmigaOS 端口已重新集成到主树中,基于 Perl 5.22.1。

Cygwin
  • 测试对异常的 cygdrive 前缀更加健壮。 [GH #15076]

EBCDIC
UTF-EBCDIC 扩展

UTF-EBCDIC 类似于 UTF-8,但适用于 EBCDIC 平台。现在已对其进行了扩展,以便它可以在具有 64 位字的平台上表示高达 2 ** 64 - 1 的代码点。这使其与 UTF-8 保持一致。此增强需要对 2 ** 30 到 2 ** 31 -1 范围内的代码点的表示进行不兼容的更改(后者是以前可表示的最大代码点)。这意味着使用以前版本的 perl 写出的包含其中一个代码点的文件无法在不进行转换的情况下被包含此更改的 perl 读入。我们不相信存在此类文件,但如果您确实有此类文件,请向 [email protected] 提交工单,我们将为您编写一个转换脚本。

针对 UTF-EBCDIC 字符串修复了 EBCDIC cmp()sort()

直到现在,比较两个都编码为 UTF-8(或更确切地说,UTF-EBCDIC)的字符串时,工作方式不正确。由于 sort() 使用 cmp(),因此这也修复了该问题。

针对 \N{}use utf8 范围修复了 EBCDIC tr///y///

Perl v5.22 引入了可移植范围的概念,用于正则表达式模式。无论在哪个平台上运行,可移植范围都匹配相同的字符集。此概念现在已扩展到 tr///。请参阅 tr///

use utf8 下,这些操作也存在一些问题,现在已修复

FreeBSD
  • 如果可用,请使用 FreeBSD 中的 fdclose() 函数。 [GH #15082]

IRIX
  • 在某些情况下,IRIX stdio fgetc()fread() 将 errno 设置为 ENOENT,这与 IRIX 或 POSIX 文档都没有意义。现在在这种情况下会清除 Errno。 [GH #14557]

  • 已修复乘以无穷大时出现的问题。 [GH #14993]

MacOS X
  • 到目前为止,perl 的 OS X 版本指定了 10.3(Panther,2003)的链接目标,但未指定编译器目标。从现在开始,在 OS X 10.6 或更高版本(Snow Leopard,2008)上构建的 perl 默认捕获当前 OS X 版本,并在编译器和链接器标志中将其指定为显式构建目标,从而保留二进制兼容性,以便以后构建的扩展不受 OS X、SDK 或编译器和链接器版本更改的影响。要覆盖在构建中使用的并保留在标志中的默认值,请在配置和构建 perl 之前指定 export MACOSX_DEPLOYMENT_TARGET=10.N,其中 10.N 是您希望定位的 OS X 版本。在 OS X 10.5 或更早版本中,当这些系统为当前系统时,行为不会发生变化;链接目标仍然是 OS X 10.3,并且没有显式的编译器目标。

  • 在 OS X 上从终端构建或测试时,启用 -DDEBUGGING 和线程的构建将失败,并出现“panic: free from wrong pool”错误。这是由于 perl 对环境的内部管理与使用 libc setenv() 函数更新环境的 atfork 处理程序冲突造成的。

    Perl 现在使用 setenv()/unsetenv() 在 OS X 上更新环境。 [GH #14955]

Solaris
  • 所有 Solaris 变体现在都构建一个共享的 libperl

    Solaris 和 OpenIndiana 等变体现在总是使用共享 Perl 库构建(Configure -Duseshrplib)。OpenIndiana 构建需要这样做,但这也是 Oracle/Sun Perl 构建多年来的设置。

Tru64
  • 解决当原型被列为 PERL_STATIC_INLINE 时 Tru64 拒绝,但测试使用 -DPERL_NO_INLINE_FUNCTIONS 构建的问题。

VMS
  • 在 VMS 上,math.h 中的数学函数原型现在可以在 C++ 下可见。现在使用 C++ 构建 POSIX 扩展将不再崩溃。

  • VMS 自 v7.0(1996 年发布)以来一直有 setenv/unsetenvPerl_vmssetenv 现在始终使用 setenv/unsetenv

  • Perl 现在通过扫描指定进程组中的进程来实现自己的 killpg,这可能与 Unix 进程组的含义不完全相同,但允许我们向父(或主)进程及其所有子进程发送信号。在 perl 级别,这意味着我们现在可以发送负 pid,如下所示

    kill SIGKILL, -$pid;

    向与 $pid 相同组中的所有进程发出信号。

  • 对于基于 CRTL environ 数组的那些 %ENV 元素,我们在设置它们时始终保留大小写,但在首次将键大写后才进行查找,这导致小写或混合大小写的条目丢失。通过使从 environ 数组派生的 %ENV 元素在查找时区分大小写以及在存储时保留大小写,已更正此问题。

  • 环境查找 PERL5LIBPERLLIB 以前只考虑逻辑名称,但现在考虑 %ENV 的所有来源,如 PERL_ENV_TABLES 所确定,并在 "perlvms 中的 %ENV" 中记录。

  • 现在支持的最低 VMS 版本为 2003 年发布的 v7.3-2。此更改的一个副作用是,VAX 不再受支持,因为 OpenVMS VAX 的终端版本是 2001 年的 v7.3。

Win32
  • 已向 Makefile 中添加了一个新的构建选项 USE_NO_REGISTRY。此选项默认关闭,这意味着默认情况下执行 Windows 注册表查找。此选项阻止 Perl 在注册表中查找任何内容。有关在注册表中查找哪些值,请参阅 perlwin32。在 C 中,此选项的名称为 WIN32_NO_REGISTRY

  • Perl 使用 HKEY_CURRENT_USER\Software\PerlHKEY_LOCAL_MACHINE\Software\Perl 查找特定值(包括以 PERL 开头的 %ENV 变量)的行为已更改。以前,即使不存在,也会在 perl 进程的整个生命周期内始终检查 2 个键的条目。出于性能原因,现在,如果根键(即 HKEY_CURRENT_USER\Software\PerlHKEY_LOCAL_MACHINE\Software\Perl)在进程启动时不存在,则不会再次检查 %ENV 覆盖条目,直到 perl 进程生命周期的剩余时间。这更接近于 Unix 行为,即环境在启动时被复制或继承,并且在父进程或其他进程中更改变量或编辑 .bashrc 不会更改其他现有正在运行进程中的环境变量。

  • 从 Perl 代码或从 Perl 的 C 代码内部执行的每个 -Xstat 调用都删除了一个 glob 提取。被查找的 glob 是一个特殊变量 ${^WIN32_SLOPPY_STAT}。这使得 -Xstat 稍快一些。

  • 在 miniperl 进程启动期间,在构建过程中,与进程启动 .plbuildcustomize.pl 文件相关的 4 到 8 个 IO 调用已从打开和执行第一个 1 或 2 个 .pl 文件的代码中删除。

  • 使用 Microsoft Visual C++ 2003 及更早版本进行构建不再会产生“内部编译器错误”消息。[perl #126045]

  • Visual C++ 2013 构建现在将在 XP 及更高版本上执行。以前它们只能在 Vista 及更高版本上执行。

  • 你现在可以使用 GNU Make 和 GCC 构建 perl。[perl #123440]

  • truncate($filename, $size) 现在可用于大小超过 4GB 的文件。[perl #125347]

  • 已将并行构建添加到 dmake makefile.mk makefile。支持所有 Win32 编译器。

  • 使用 64 位 GCC 但使用 32 位 gmake 构建 64 位 perl 将导致生成的 perl 的 $Config{archname} 无效。[perl #127584]

  • Winsock 函数设置的错误现在直接放入 $^E,并且相关 WSAE* 错误代码现在从 ErrnoPOSIX 模块导出,以便对此进行测试。

    自 Perl 5.20.0 以来,将错误(转换为 POSIX 样式 E* 错误代码)放入 $! 的先前行为存在缺陷,因为同名的 Winsock 和 POSIX 错误常量不等效,自 Perl 5.8.0 以来,不幸地以某种方式建立了它们之间的关系。

    新行为为检查可移植软件中的 Winsock 错误提供了更健壮的解决方案,而不会意外匹配针对其他操作系统且对 Winsock 可能有不同含义的 POSIX 测试。

    出于向后兼容性的考虑,当前保留了所有缺陷的旧行为,但鼓励用户更改任何针对 Winsock 错误测试 $!E* 常量的代码,改为针对 WSAE* 常量测试 $^E。在适当的弃用期之后,可能会删除旧行为,在 Winsock 函数调用后保持 $! 不变,以避免对检查哪个错误变量造成任何可能的混淆。

ppc64el
浮点数

ppc64el(Debian 为小端 PowerPC 命名)的浮点数格式现在可以正确检测。

内部更改

选定的错误修复

致谢

Perl 5.24.0 代表了自 Perl 5.24.0 以来大约 11 个月的开发时间,包含来自 75 位作者的 1,800 个文件中的大约 360,000 行更改。

不包括自动生成的文件、文档和发布工具,大约有 250,000 行更改到 1,200 个 .pm、.t、.c 和 .h 文件。

由于活跃的用户和开发人员社区,Perl 在其第三个十年中继续蓬勃发展。已知以下人员为 Perl 5.24.0 的改进做出了贡献

Aaron Crane、Aaron Priven、Abigail、Achim Gratz、Alexander D'Archangel、Alex Vandiver、Andreas König、Andy Broad、Andy Dougherty、Aristotle Pagaltzis、Chase Whitener、Chas. Owens、Chris 'BinGOs' Williams、Craig A. Berry、Dagfinn Ilmari Mannsåker、Dan Collins、Daniel Dragan、David Golden、David Mitchell、Doug Bell、Dr.Ruud、Ed Avis、Ed J、Father Chrysostomos、Herbert Breunung、H.Merijn Brand、Hugo van der Sanden、Ivan Pozdeev、James E Keenan、Jan Dubois、Jarkko Hietaniemi、Jerry D. Hedden、Jim Cromie、John Peacock、John SJ Anderson、Karen Etheridge、Karl Williamson、kmx、Leon Timmermans、Ludovic E. R. Tolhurst-Cleaver、Lukas Mai、Martijn Lievaart、Matthew Horsfall、Mattia Barbon、Max Maischein、Mohammed El-Afifi、Nicholas Clark、Nicolas R.、Niko Tyni、Peter John Acklam、Peter Martini、Peter Rabbitson、Pip Cet、Rafael Garcia-Suarez、Reini Urban、Ricardo Signes、Sawyer X、Shlomi Fish、Sisyphus、Stanislaw Pusep、Steffen Müller、Stevan Little、Steve Hay、Sullivan Beck、Thomas Sibley、Todd Rinaldo、Tom Hukins、Tony Cook、Unicode Consortium、Victor Adam、Vincent Pit、Vladimir Timofeev、Yves Orton、Zachary Storer、Zefram。

上面的列表几乎肯定是不完整的,因为它是从版本控制历史记录中自动生成的。特别是,它不包括向 Perl 错误跟踪器报告问题的(非常感谢的)贡献者的姓名。

此版本中包含的许多更改源自 Perl 核心包含的 CPAN 模块。我们感谢整个 CPAN 社区帮助 Perl 蓬勃发展。

有关 Perl 所有历史贡献者的更完整列表,请参阅 Perl 源代码发行版中的 AUTHORS 文件。

报告错误

如果您发现您认为是错误的内容,您可以查看最近发布到 comp.lang.perl.misc 新闻组和 https://rt.perl.org/ 上的 perl 错误数据库中的文章。Perl 主页 https://www.perl5.cn/ 上也可能有信息。

如果您认为您有一个未报告的错误,请运行发行版中包含的 perlbug 程序。务必将您的错误精简为一个微小但足够的测试用例。您的错误报告以及 perl -V 的输出将被发送到 [email protected],供 Perl 移植团队分析。

如果您报告的错误具有安全影响,不适合发送到公开存档的邮件列表,请参阅 perlsec 中的“安全漏洞联系信息”,了解如何报告该问题的详细信息。

另请参阅

Changes 文件,了解如何查看已更改内容的详尽详细信息。

INSTALL 文件,了解如何构建 Perl。

README 文件,了解一般内容。

ArtisticCopying 文件,了解版权信息。