Perl 5.32.0 변경 사항

Perl 5.32.0 변경 사항 (perl5320delta)

이 문서는 Perl 5.30.0 릴리스와 5.32.0 릴리스 사이의 차이를 설명해요.

5.28.0 같은 더 오래된 릴리스에서 업그레이드하는 경우, 5.28.0과 5.30.0 사이의 차이를 설명하는 perl5300delta를 먼저 읽어 보세요.

출처: perldoc - perl5320delta

핵심 개선 사항 (Core Enhancements)

isa 연산자

객체가 특정 클래스(또는 그 파생 클래스)의 인스턴스인지 검사하는 새로운 실험적 infix 연산자 isa가 추가되었어요.

if( $obj isa Package::Name ) { ... }

자세한 내용은 perlop의 "Class Instance Operator"를 참고하세요.

Unicode 13.0 지원

자세한 내용은 https://www.unicode.org/versions/Unicode13.0.0/을 참고하세요.

연쇄 비교(chained comparison) 지원

같은 우선순위의 일부 비교 연산자는 결합성에 따라 서로 *연쇄(chain)*될 수 있어요. (다른 우선순위의 연산자와는 절대 연쇄되지 않아요.)

if ( $x < $y <= $z ) {...}

위 코드는 다음처럼 정확히 동작해요.

if ( $x < $y && $y <= $z ) {...}

($y가 보이는 그대로 단순 스칼라라고 가정해요.) 자세한 내용은 perlop의 "Operator Precedence and Associativity"를 참고하세요.

새 Unicode 프로퍼티 Identifier_StatusIdentifier_Type 지원

Unicode가 정규식 요구사항을 개정하면서(https://www.unicode.org/reports/tr18/tr18-21.html) 더 많은 프로퍼티를 노출하기 원해요. 이 두 프로퍼티는 보안 목적으로 입력을 검사할 때 사용돼요. 사용법은 https://www.unicode.org/reports/tr39/를 참고하세요.

qr/\p{Name=...}/ 또는 qr!\p{na=/(SMILING|GRINNING) FACE/}! 작성 가능

이제 정규식 패턴에서 \N{...}의 대안으로 Unicode Name 프로퍼티를 사용할 수 있어요. 두 방법의 비교는 perlunicode의 "Comparison of \N{...} and \p{name=...}"를 참고하세요. 위 두 번째 예시처럼 와일드카드 하위 패턴도 이 프로퍼티에서 쓸 수 있어요. (perlunicode의 "Wildcards in Property Values" 참고)

POSIX::mblen(), mbtowc, wctomb 개선

이 함수들이 이제 shift state 로케일에서 동작하고, C99 이상 컴파일러 + 로케일 스레드 안전 플랫폼에서 스레드 안전해졌어요. 길이 파라미터는 이제 선택사항이에요. 이 함수들은 항상 현재 C 언어 로케일 아래에서 실행돼요. 대부분의 로케일은 무상태(stateless)지만, 아주 드물게 사용되는 ISO 2022 같은 일부는 호출 사이에 상태를 유지해요. 이전에는 매 호출마다 상태를 지웠지만, 이제는 해당 파라미터가 undef일 때만 상태를 리셋하지 않아요.

스레드 perl에서는 사용 가능할 때 C99 함수인 mbrlen(3), mbrtowc(3), wcrtomb(3)을 평범한 함수 대신 사용해요. mblenmbtowc의 문자열 길이 파라미터는 이제 선택 사항이에요 (소스 문자열에서 파싱되는 길이를 실제 길이보다 짧게 제한하고 싶을 때만 유용해요).

Alpha 단언(assertion)은 더 이상 실험적이지 않음

perlre(*pla:pattern), (*plb:pattern), (*nla:pattern), (*nlb:pattern) 참고. 이제 사용 시 경고가 발생하지 않아요. experimental::alpha_assertions 경고 카테고리를 끈 기존 코드는 변경 없이 계속 동작해요. 카테고리를 켜는 것은 아무 효과가 없어요.

스크립트 실행(script runs)은 더 이상 실험적이지 않음

perlre의 "Script Runs" 참고. 사용 시 더 이상 경고가 발생하지 않아요. experimental::script_run 카테고리를 끈 기존 코드는 변경 없이 동작해요.

Feature 검사가 더 빨라짐

이전에는 feature bundle 밖에서 feature를 설정하면 파서의 feature 검사에 해시 조회가 필요했어요. 이제 비트 마스크 검사로 최적화됐어요. [GH #17229]

Perl은 이제 GitHub에서 개발됨

https://github.com/Perl/perl5에서 개발해요. 비보안 버그는 GitHub로 보고하고, 보안 이슈는 perlsec에 문서화된 대로 계속 보고하세요.

컴파일된 패턴을 최적화 전에 덤프 가능

정규식 컴파일러의 버그를 추적하는 데 주로 유용해요. -DDEBUGGING perl에서 -Drv를 지정하거나, use re qw(Debug DUMP_PRE_OPTIMIZE) 또는 use re qw(Debug COMPILE EXTRA) 스코프 안에서 패턴을 컴파일하면 덤프가 발생해요.

보안 (Security)

[CVE-2020-10543] 조작된 정규식으로 인한 버퍼 오버플로

중첩 정규식 수량자(quantifier)의 저장 공간 계산에서 부호 있는 size_t 정수 오버플로가 힙 버퍼 오버플로를 일으킬 수 있었어요. 64비트 시스템에서는 충족되기 어려운 요구사항이에요. 발견: The Tarantula Team, VinCSS의 ManhND.

[CVE-2020-10878] 조작된 정규식으로 생성된 잘못된 바이트코드를 통한 정수 오버플로

정규식 엔진의 명령어 사이 오프셋 계산에서 정수 오버플로가 컴파일된 정규식의 중간 언어 상태를 손상시킬 수 있었어요. 발견: Hugo van der Sanden, Slaven Rezic.

[CVE-2020-12723] 조작된 정규식으로 인한 버퍼 오버플로

S_study_chunk()에 대한 재귀 호출이 컴파일된 정규식의 중간 언어 상태를 손상시킬 수 있었어요. 발견: Sergey Aleynikov.

추가 참고

Perl로 작성된 애플리케이션은 공격자가 제공한 정규식을 실행하는 경우에만 위 결함에 취약해요. 이런 방식으로 정규식을 실행하는 것은 정규식 엔진이 이 용법에서 서비스 거부 공격을 보호하지 않기 때문에 위험한 것으로 알려져 있어요.

비호환 변경 (Incompatible Changes)

특정 패턴 매칭 기능이 Unicode 프로퍼티 값 와일드카드 하위 패턴 컴파일에서 금지됨

이 기능들은 부적절하거나 이 작업을 수행하는 알고리즘을 방해해요. 전체 목록은 perlunicode의 "Wildcards in Property Values"에 있어요.

사용되지 않는 함수 POSIX::mbstowcsPOSIX::wcstombs 제거

이 함수들은 결함 있는 인터페이스 명세 때문에 실제로 동작할 수 없었어요. 수년 동안 사용 가능하다고 주장됐지만 아무도 불평하지 않은 것을 보면 수요가 분명히 없으므로 이른바 "지원"이 이제 제거됐어요.

(?[...]) 버그 수정으로 일부 패턴이 더 이상 컴파일되지 않을 수 있음

"Selected Bug Fixes" 참고. 이전에 사용되던 휴리스틱이 (프로그래머가 의도한 효과가 아닐지라도) 오류여야 할 일부 구조를 컴파일하게 했을 수 있어요. 알려진 경우는 없지만 일부 잘못된 구조가 더 이상 컴파일되지 않을 수 있어요.

\p{user-defined} 프로퍼티가 이제 항상 공식 Unicode 프로퍼티를 덮어씀

이전에는 사용자 정의 프로퍼티가 그것을 포함하는 정규식 패턴 컴파일보다 먼저 선언된 경우에만 같은 이름의 공식 Unicode 프로퍼티 대신 그 정의를 사용했어요. 이제 항상 공식 프로퍼티를 덮어써요. Unicode가 당신이 오랫동안 써온 이름과 우연히 같은 이름의 새 프로퍼티를 포함한 새 버전을 출시하면, 프로그램이 깨질 수 있는 문제를 고친 것이에요. [GH #17205]

상수에서 수정 가능한 변수(modifiable variables) 더 이상 허용되지 않음

my $var;
$sub = sub () { $var };

$var가 다른 곳에서 어떤 수정 가능한 컨텍스트로 참조되는 이 코드는 이제 sub 정의 시 예외를 발생시켜요. 이 오류는 sub 정의에 return을 추가하면 피할 수 있어요.

$sub = sub () { return $var };

Perl 5.22부터 폐기(deprecated)됐어요. [GH #17020]

0xFF 초과 코드 포인트가 있는 문자열에 vec 사용 금지

이런 문자열은 내부적으로 UTF-8로 표현되는데, vec는 비트 지향 연산이라 그 문자열들에서 예상치 못한 결과를 줄 가능성이 높아요. 5.28.0에서 폐기됐어요.

문자열 비트 연산자에서 0xFF 초과 코드 포인트 사용 금지

이전 폐기 주기 이후 일부 사용은 이미 불법이었어요. 나머지 사용은 5.28.0에서 폐기된 후 이제 금지됐어요. (perldeprecation 참고)

Sys::Hostname::hostname()가 인자를 받지 않음

5.28.0에서 폐기됐고 이제 치명적이에요.

범위 연산자에서 평범한 "0" 문자열이 이제 숫자로 취급됨

이전에는 "0" .. "-1" 범위가 "0"부터 "99"까지의 숫자 문자열을 만들었어요. 이제 0 .. -1처럼 빈 리스트를 만들어요. 또한 "0" .. "9"가 이제 문자열 대신 정수 리스트를 만들어요. 이는 "0"으로 시작하는 문자열을 특별 취급한 결과였어요. [GH #16770]

\K가 look-ahead와 look-behind 단언에서 금지됨

예상치 못한 동작을 일으키고 원하는 동작을 정의할 수 없었기 때문에 금지됐어요. [GH #14638]

성능 개선 (Performance Enhancements)

  • my_strnlen이 자체 strnlen 구현이 없는 시스템에서 빨라졌어요.
  • grok_bin_oct_hex(따라서 grok_bin, grok_oct, grok_hex)가 빨라졌어요.
  • grok_number_flags가 빨라졌어요.
  • sort {$a <=> $b} 또는 sort {$b <=> $a} 같은 경우 sort가 눈에 띄게 빨라졌어요. [GH #17608]

모듈과 프래그마 (Modules and Pragmata)

업데이트된 모듈과 프래그마

업그레이드된 정보는 버전 링크를 참고하면 되는데, 주요 항목만 정리하면:

  • feature가 1.54에서 1.58로 업그레이드. 기본적으로 켜져 있지만 indirect object 문법을 끌 수 있는 새 indirect feature가 추가됐어요.
  • IO가 1.40에서 1.43으로. IO::Socket이 더 이상 0 프로토콜 값을 캐시하지 않아요.
  • Storable이 3.15에서 3.21로. 2GB 초과 vstring magic 문자열이 이제 금지되고, 정규식 객체가 retrieve 시 객체 id 계산에서 잘못 집계되던 문제가 고쳐졌어요. [GH #17037]
  • Time::HiRes가 1.9760에서 1.9764로. 5.6 이전 perl 및 클래식 MacOS 지원 같은 오래된 코드가 제거됐어요. [GH #17096]

그 외 다수 모듈이 버전 업그레이드됐어요 (Archive::Tar, autodie, B, B::Deparse, Benchmark, CPAN, Encode, ExtUtils::MakeMaker, JSON::PP, Math::BigInt, Net::Ping, POSIX, Safe, Socket, Test::Simple, threads, Tie::File, Unicode::Normalize, warnings 등).

제거된 모듈과 프래그마

  • Pod::Parser가 코어 배포에서 제거됐지만 CPAN에서 계속 다운로드할 수 있어요. [GH #13194]

문서화 (Documentation)

문서를 이 릴리스의 변경 사항을 반영하도록 업데이트하려고 노력했어요. 놓친 부분이 있다면 GitHub 이슈를 열어 주세요.

주요 문서 변경 요약:

  • perldebguts: BOUND/NBOUND 정의를 단순화하고, ANYOFHs regnode를 추가 (매칭 코드 포인트 모두에서 여러 개의 선행 바이트가 같을 때 사용).
  • perlapi: sv_2pvbyte, sv_setpvn, PL_phase, grok_bin/grok_oct/grok_hex 문서 갱신/명확화.
  • perldiag: 실험적 isa 연산자 문서 추가.
  • perlfunc: caller, __FILE__, __LINE__, return(do BLOCK에서 return 불가 언급), open 갱신.
  • perlguts: perl 자체 malloc 사용 권장 제거, embed.fnc 문서 제거, UTF8f 문서 갱신.
  • perlipc: 3-arg open과 렉시컬 변수 선호하도록 현대화.
  • perlop: isa 연산자가 실험적임을 명시.
  • perlxs: 단순 라이브러리 바인딩에 FFI::Platypus/FFI::Raw 같은 CPAN 모듈로 libffi 사용 권장.
  • 링크 갱신: 이제 없어진 search.cpan.org 링크가 metacpan.org으로, URL이 http://에서 https://로 바뀜.

진단 (Diagnostics)

새 진단

새 오류:

  • "Expecting interpolated extended charclass in regex; marked by <-- HERE in m/%s/" — 여러 기존 오류 메시지를 대체.
  • "No digits found for %s literal" — (F) 0x 뒤에 16진수 숫자가 없거나 0b 뒤에 2진수 숫자가 없음.

새 경고:

  • "Code point 0x%X is not Unicode, and not portable" — 실제로 새 메시지는 아니지만 portable 경고 카테고리가 켜지면 이제 출력됨. 정규식 패턴 컴파일 중 발생 시 패턴에서 정확히 어디에서 발생했는지 표시하는 추가 텍스트가 끝에 붙어요.
  • "Non-hex character '%c' terminates \x early. Resolved as "%s"" — 훨씬 덜 구체적이고 잘못된 정보를 주던 경고를 대체. 이미 존재하던 \o{} 경고와 유사해요.

기존 진단 변경

  • "Character following "\c" must be printable ASCII", "Use "%s" instead of "%s"", "Sequence "\c{" invalid", ""\c%c" is more clearly written simply as "%s"", "Non-octal character '%c' terminates \o early. Resolved as "%s"" — 정규식 패턴 컴파일 중 발생 시 정확한 위치를 표시하는 추가 텍스트가 끝에 추가됨.
  • "'%s' resolved to '\o{%s}%d'" — 5.32부터 더 이상 생성되지 않고 대신 "Non-octal character..." 메시지 사용.
  • "Can't use global %s in %s" — 오해를 부르던 "Can't use global $_ in "my"" 같은 메시지가 이제 "Can't use global $_ in subroutine signature"로 표시.
  • "Constants from lexical variables potentially modified elsewhere are no longer permitted" — 이전 폐기 메시지를 대체. 분류가 D(폐기)에서 F(치명)로 변경.
  • \N{} here is restricted to one character가 이전의 \N{} in inverted character class or as a range end-point is restricted to one character와 같은 상황에서 출력됨.

유틸리티 변경 (Utility Changes)

  • perlbug: 버그 트래커 홈페이지 URL이 GitHub를 가리키도록 변경.
  • streamzip: IO::Compress::Base 업그레이드의 일부로 포함된 새 유틸리티. stdin에서 데이터를 읽어 zip 컨테이너로 압축하고, 기본적으로 스트리밍된 zip 파일을 stdout에 씀.

구성과 컴파일 (Configuration and Compilation)

  • clang++를 위한 여러 probe 수정, lchown에 컴파일+실행 테스트 사용.
  • 인라인 속성 및 문자 데이터 정렬 검사.
  • Configure가 gcc-10을 이제 올바르게 처리 (이전에는 gcc-1로 해석해 -fpcc-struct-return을 켬).
  • d_u32align probe 제거 (전 플랫폼에서 define 기본값).
  • malloc_usable_size에 대한 새 probe 추가.
  • autodoc.pl: perlintern/perlapi를 재생성하는 도구가 대폭 개편.
  • Bison 3.1~3.4 지원.

테스트 (Testing)

  • POSIX::mbtowc, POSIX::wctomb의 다양한 버그 수정 (다른 스레드와의 경쟁 회피, 잘못된 결과/세그폴트 수정).
  • EBCDIC에서 제어 문자와 Unicode를 포함한 스칼라 테스트 출력 수정.
  • 여러 테스트 파일 속도 개선 및 EBCDIC 건너뛰기.

플랫폼 지원 (Platform Support)

중단된 플랫폼

  • Windows CE: 빌드 지원 제거.

플랫폼별 참고

  • Linux: ccclang이면 ccplibpth를 채움. [GH #17043]
  • NetBSD 8.0: g++ 컴파일 수정. [GH #17381]
  • Windows: ccflags/optimize 구성 분리, Visual C++ 6.0 지원 제거, 로케일 테스트 크래시 수정, MYMALLOC(PERL_MALLOC) 빌드 수정.
  • Solaris: Oracle Developer Studio 컴파일러 탐지, gethostby* 타입 탐지.
  • VMS: C99 패치 키트 탐지, -Duse64bitint가 기본값.
  • z/OS: 5.32가 z/OS 2.4에서 테스트됨. -DNO_LOCALE_MESSAGES, -DNO_LOCALE 플래그 필요. 일부 CPAN 모듈은 EBCDIC에서 자체 테스트 실패.

내부 변경 (Internal Changes)

  • savepvn의 len 파라미터가 I32에서 Size_t로 변경.
  • lexer(Perl_yylex() in toke.c)가 이전 4100줄 단일 함수에서 수십 개의 작은 static 함수로 분리.
  • OS 레벨 시그널 핸들러 시그니처 수정 (3개 파라미터 → 1개).
  • tr/// 처리 코드 대폭 개정 (특히 255 초과 코드 포인트 문자 처리 시 다양한 버그 수정).
  • UTF-8 처리 XS 매크로 UTF8_CHK_SKIP 추가 (utf8_skip보다 안전, UTF8_SAFE_SKIP만큼은 아님; NUL 문자를 지나 읽지 않음). Devel::PPPort 3.55+에 백포트.
  • PL_curstackinfo->si_cxsubix 필드 추가.
  • 다양한 UTF-8 문자 분류/대소문자 변경 매크로가 이제 버퍼 끝 너머 읽기를 방지하기 위해 추가 파라미터 요구.
  • 새 파서 함수 parse_subsignature()로 키워드 플러그인이 use feature 'signatures' 활성 상태에서 서브루틴 시그니처 파싱 가능.
  • OP 구조 할당 시 메모리 관리 오버헤드가 64비트 시스템에서 OP당 8바이트 감소.
  • eval_pv()가 예외를 문자열화하지 않음.
  • PERL_DESTRUCT_LEVEL 환경 변수가 모든 perl 빌드에서 확인됨.
  • API eval_sv()G_RETHROW 플래그 수용.
  • perl_parse()BEGIN/UNITCHECK/CHECK 블록에서 exit(0) 호출 시 0이 아닌 값을 반환.
  • 컴파일 중 op 트리를 재귀적으로 순회하던 대부분 함수가 비재귀화되어 깊은 중첩 op 트리의 스택 오버플로 SEGV를 피함.

주요 버그 수정 (Selected Bug Fixes)

  • require%INC에서 특수 내장 &PL_sv_undef만 이전 require 실패로 취급하던 것을 수정.
  • (?{...}) eval 그룹이 더 이상 의도치 않게 "EVAL without pos change exceeded limit in regex"를 발생시키지 않음. [GH #17490]
  • (?[...]) 확장 대괄호 문자 클래스가 이전에 컴파일된 클래스를 다른 곳에 삽입할 때 일부 경우 잘못된 오류를 발생시키지 않음.
  • 정규식 엔진의 assertion 실패 수정, B::UNOP_AUX::aux_list() 이후 coredump 수정.
  • IO 로딩이 이제 스레드 안전.
  • \p{user-defined}가 공식 Unicode를 덮어씀. [GH #17025]
  • %+, %- 구현이 코어로 이동.
  • grok_inf_nan의 버퍼 초과 읽기 수정. [GH #17370]
  • LC_MESSAGES 관련 glibc 버그 우회. [GH #17081]
  • %n 포맷의 printf()/sprintf() panic/캐시 길이 버그 수정.
  • 토크나이저 대폭 리팩토링.
  • multiconcat 연산자로 최적화된 bareword 상수에 use strict "subs" 적용. [GH #17254]
  • 정규식 패턴 메모리 누수 수정. [GH #17218]
  • 문자열을 숫자로 변환할 때 "0x"/"0b" 시작 문자열을 16진/2진으로 취급하지 않음 (5.30.0에서 우연히 도입된 동작 되돌림). [GH #17062]
  • Unicode 리터럴 포함 정규식 매칭 시 SV 누수 수정.
  • $@ = 100; die;가 100을 예외로 올바르게 전파. [GH #17098]
  • 읽기 전용 $@ 중 예외 발생 시 무한 재귀/스택 오버플로 수정 (불가능하면 $@를 복사본으로 교체).
  • 필요한 권한이 있으면 $) 설정이 이제 보조 그룹 id를 올바르게 설정. [GH #17031]
  • 파이프 close()가 신호 핸들러가 죽는 동안 이중 close 시도를 방지. [GH #13929]
  • sprintf("%.*a", -10000, $x) 버퍼 오버플로 수정. [GH #16942]
  • scalar()이 참조에서 컴파일 중 잘못된 assertion 실패 → 수정. [GH #16969]
  • %{^CAPTURE_ALL}이 이제 문서대로 %-의 별칭. [GH #16105]
  • %{^CAPTURE}@{^CAPTURE} 먼저 언급 시 동작하지 않던 문제 수정. [GH #17045]
  • 2GB 초과 부동소수점 포맷 폭 정수 오버플로 수정 (int 범위로 제한).
  • sub-parse에서 print $fh ...가 더 이상 문법 오류를 내지 않고, s/.../ ${time} /e@x {"a"} 관련 경고가 올바르게 발생.
  • 불완전한 16진/2진 리터럴(0x, 0b)이 다음 토큰의 일부로 취급되던 것에서 치명적 오류가 되도록 변경. [GH #17010]
  • sub-parse에서 불필요한 )가 파서를 혼동시키던 문제 수정 (인공 토큰으로 감쌈). [GH #15814]
  • \&foo = \&bar; 같은 sub 참조 할당이 조용히 아무것도 안 하던 문제 수정.
  • sv_gets()가 신호 핸들러가 대상 SV를 수정하면 더 잘 복구. [GH #16960]
  • readline @foo가 이제 스칼라 컨텍스트에서 @foo를 평가. [GH #16929]
  • eval_pv()croak_on_error가 거짓 overload 값이어도 throw.
  • INIT 블록과 프로그램이 BEGIN/UNITCHECK/CHECK에서 exit(0) 호출 시 더 이상 실행되지 않음. [GH #1537]
  • open my $fh, ">>+", undef가 이제 임시 파일을 append 모드로 엶. [GH #17058]
  • OP_MULTIDEREF를 포함하는 op에서 uninitialized 값 경고 소스 검색 시 SEGV 수정. [GH #17088]

부고 (Obituary)

Jeff Goff (JGOFF 또는 DrForr)가 2020년 3월 13일에 세상을 떠났어요. Perl과 Raku 커뮤니티의 핵심 멤버이자 우리 모두의 친애하는 친구였으며, 수많은 이벤트에 참석·발표하고 여러 프로젝트에 기여했어요.

감사 (Acknowledgements)

Perl 5.32.0은 5.30.0 이후 약 13개월의 개발로, 89명의 저자가 1,800개 파일에 약 220,000줄의 변경을 포함해요. 자동 생성 파일·문서·릴리스 도구를 제외하면 880개의 .pm/.t/.c/.h 파일에 약 140,000줄의 변경이 있었어요.

버그 보고 (Reporting Bugs)

버그라고 생각되는 것을 찾으면 https://github.com/Perl/perl5/issues를 확인하세요. 미보고 버그가 있다면 해당 페이지에서 이슈를 여세요. 보안 영향을 미치는 버그는 공개 트래커에 보내기 부적절하므로 perlsec의 "SECURITY VULNERABILITY CONTACT INFORMATION"를 참고하세요.

감사 표하기 (Give Thanks)

Perl 5 Porters에게 감사 인사를 하고 싶다면 perlthanks 프로그램을 실행하면 Perl 5 Porters 목록에 감사 이메일을 보내줘요.

함께 보기 (SEE ALSO)

  • Changes 파일 — 무엇이 바뀌었는지 자세히 보는 방법.
  • INSTALL 파일 — Perl 빌드 방법.
  • README 파일 — 일반 정보.
  • Artistic/Copying 파일 — 저작권 정보.