Perl 5.30.0 변경 사항

Perl 5.30.0 변경 사항 (perl5300delta)

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

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

출처: perldoc - perl5300delta

공지

sv_utf8_(downgrade|decode)가 더 이상 실험적이라고 표시되지 않아요.

핵심 개선 사항

제한된 가변 길이 lookbehind가 정규 표현식 패턴 매칭에서 실험적으로 지원

(?<=foo?)(?<!ba{1,9}r) 같은 lookbehind 단언을 쓰면 이전에는 오류를 내고 컴파일을 거부했어요. 이제는 (최대 lookbehind가 최대 255자라면) 컴파일되지만, 새 experimental::vlb 경고 카테고리에서 경고를 발생시켜요. 정확한 동작이 현장 사용 피드백에 따라 바뀔 수 있다는 경고예요. perlre의 "(?<=pattern)"와 "(?<!pattern)"을 보세요.

정규 표현식 수량자 "{m,n}"의 상한 "n"이 65534로 두 배 증가

제한 없는 상한 수량자 "{m,}"의 의미는 바뀌지 않아요. 대부분 플랫폼에서 2**31-1 회 매칭하고, C 언어 short 변수가 4바이트보다 긴 곳에서는 더 많이 매칭해요.

유니코드 12.1 지원

유니코드 릴리스 주기 변경 때문에 Perl은 5.28의 유니코드 10.0에서 5.30의 유니코드 12.1로 점프했어요. (12.1은 12.0과 한 문자 — 새로운 일본 연호용 문자 — 의 추가만 다릅니다.) Word_Break 속성은 이전 Perl 릴리스처럼 Perl 사용자의 기대에 더 부합하도록 유지돼요. 수평 공백 문자의 연속 실행은 분리되지 않고 단일 실행으로 유지돼요. 유니코드 11이 Perl과 더 일치하도록 바뀌었지만 TAB, NO BREAK SPACE, FIGURE SPACE(U+2007) 같은 몇몇 공백 문자를 분리시키는 것으로 남겨뒀어요. 이와 관련해 이전 Perl 맞춤을 계속 사용하기로 했어요.

유니코드 속성 값 지정의 와일드카드가 부분적으로 지원

정규 표현식 패턴에서 이제 다음과 같이 할 수 있어요:

qr! \p{nv= /(?x) \A [0-5] \z / }!

이것은 숫자 값이 0에서 5(포함) 사이인 모든 유니코드 코드 포인트와 매칭해요. 그래서 숫자 값이 0,1,2,3,4,5인 태국어나 벵골어 숫자와 매칭할 수 있어요. 이것은 유니코드 컨소시엄이 제안한 정규 표현식 기능을 구현하는 또 하나의 단계예요. 대부분의 속성이 지원되고, 나머지는 5.32로 계획되어 있어요. 자세한 내용은 perlunicode의 "Wildcards in Property Values"를 보세요.

qr'\N{name}' 이제 지원

이전에는 단일 따옴표 정규 표현식 패턴(평가가 정상 위치에서 지연되는) 안에서 이름 있는 문자 \N{...}를 평가하는 건 오류였어요. 이 제한이 이제 제거됐어요.

터키어 UTF-8 로케일이 이제 매끄럽게 지원

터키어는 다른 언어와 "i""I" 문자의 대소문자 규칙이 달라요. "i"의 대문자는 LATIN CAPITAL LETTER I WITH DOT ABOVE(U+0130)이고, "I"의 소문자는 LATIN SMALL LETTER DOTLESS I(U+0131)예요. 유니코드는 터키어용 대체 대소문자 규칙을 제공해요. 이전에는 Perl이 이를 무시했지만, 이제 터키어 UTF-8 로케일에서 동작 중임을 감지하면 그것을 사용해요.

항상 스레드 안전 로케일 연산을 사용하도록 perl 컴파일 가능

이전에는 이런 호출이 perl이 멀티스레드로 컴파일될 때만 사용됐어요. 항상 활성화하려면 Configure 플래그에 다음을 추가하세요:

-Accflags='-DUSE_THREAD_SAFE_LOCALE'

코어에서 opASSIGN 매크로 사용 제거

이 매크로는 여전히 정의되지만 코어에서 더 이상 사용되지 않아요.

-Drv-DDEBUGGING 빌드에서 이제 의미

이제 -Dr 플래그에 verbose 플래그(-Dv)를 추가하면 가능한 모든 정규 표현식 디버깅이 켜져요.

비호환 변경 사항

$[에 0이 아닌 값을 대입하는 건 치명적

$[를 0이 아닌 값으로 설정하는 건 Perl 5.12부터 deprecated됐고 이제 치명적 오류를 던져요.

구분자는 이제 그라핀이어야 함

"구분자에 미할당 코드 포인트 또는 비독립 그래핀 사용" 이슈를 참고하세요.

이전에 deprecated였던 이스케이프되지 않은 왼쪽 중괄호 "{"의 일부 사용이 이제 무효

하지만 불필요한 코드 파손을 피하려고 deprecation 경고를 냈던 대부분 인스턴스는 여전히 합법이며 이제 non-deprecation 경고를 발생시켜요.

:utf8 핸들에서 이전에 deprecated였던 sysread()/syswrite()가 이제 치명적

:utf8 핸들에서 sysread(), syswrite(), send(), recv()를 명시적이든 암시적이든 호출하는 건 이제 치명적이에요. 이것은 perl 5.24에서 deprecated됐어요. 문제는 두 가지였어요: 1) 네 함수 모두 :utf8 플래그만 보았고 다른 레이어는 완전히 무시했어요(:encoding(UTF-16LE) 레이어 핸들이 UTF-8로 취급됨). 2) sysread()와 recv()는 레이어의 검증을 건너뛰고 자체 검증도 안 해서 부적절히 인코딩된 perl 스칼라로 이어질 수 있었어요.

false 조건부에서 my() 금지

my $x if 0 같은 선언은 더 이상 허용되지 않아요.

$*$# 치명화

오래전부터 deprecated된 이 특수 변수들이 이제 사용 시 예외를 던져요.

비자격 dump() 사용 치명화

오래전부터 권장되지 않은 dump() 함수는 완전 자격(즉 CORE::dump())이 아니면 더 이상 사용할 수 없어요.

File::Glob::glob() 제거

오래전부터 deprecated된 File::Glob::glob() 함수가 제거되고, 대신 File::Glob::bsd_glob() 사용을 권하는 예외를 던져요.

pack()이 더 이상 malformed UTF-8을 반환할 수 없음

그렇지 않으면 malformed UTF-8을 포함한 UTF-8 문자열을 반환할 경우 croak해요. 잠재적 보안 위협으로부터 보호해요. 이것은 버그 수정으로도 간주돼요.

Common 스크립트의 숫자 집합이 다른 스크립트의 스크립트 실행에서 허용

Common 스크립트에는 여러 숫자 집합이 있어요. [0-9]가 가장 익숙하지만 [\x{FF10}-\x{FF19}](FULLWIDTH DIGIT ZERO-FULLWIDTH DIGIT NINE)와 수학 표기법용 여러 집합(MATHEMATICAL DOUBLE-STRUCK DIGIT 등)도 있어요. 이런 집합은 그리스어 같은 스크립트 실행에도 나타날 수 있어야 해요. 하지만 5.30의 설계는 ASCII 숫자 [0-9]를 제외한 모든 것을 간과해서 설계가 결함이었어요. 이것이 고쳐져서 버그 수정이자 비호환이에요. 실행의 모든 숫자는 여전히 같은 10자리 집합에서 와야 해요.

JSON::PP가 기본으로 allow_nonref 활성화

JSON::XS 4.0이 정책을 바꿔 기본으로 allow_nonref를 활성화했으므로, JSON::PP도 기본으로 allow_nonref를 활성화했어요.

Deprecations

XS 코드에서 UTF-8을 다루는 여러 매크로 사용

이 deprecation은 5.30에서 치명적이 되도록 예정됐지만, 일부 CPAN 모듈에서 나타난 문제 때문에 5.32로 연기됐어요.

성능 개선

  • UTF-8을 그것이 나타내는 코드 포인트로 번역하는 것이 결정적 유한 오토마타(DFA)로 수행되어 빨라졌어요. 예를 들어 ord("\x7fff")가 이전보다 12% 적은 명령어를 요구해요. 바이트 시퀀스가 유효한 UTF-8인지 검사하는 성능도 DFA를 써서 비슷하게 개선됐어요.
  • finalize_op()에서 재귀를 제거했어요.
  • 정규 표현식의 문자 접기와 문자 클래스 관련 소수의 작은 최적화.
  • IV에서 UV 변환 최적화.
  • 한 번에 한 자리 대신 두 자리를 처리해 정수 문자열화 알고리즘 가속.
  • LGTM 분석·권장에 기반한 개선.
  • regcomp.c, regcomp.h, regexec.c의 코드 최적화.
  • qr/[^Xa>] 같은 것의 정규 표현식 패턴 매칭이 상당히 빨라졌어요(a는 ASCII 문자). 다른 클래스도 이 속도 향상을 얻을 수 있는데, 어떤 것이 복잡하고 그 문자들의 기본 비트 패턴에 의존해서 ASCII와 EBCDIC 플랫폼에서 다르지만, qr/[Gg]/ 같은 모든 case 쌍과 [^01]이 포함돼요.

모듈과 프래그마

업데이트된 모듈(일부): Archive::Tar 2.30→2.32, B 1.74→1.76, B::Concise, B::Deparse, bignum, bytes, Carp 1.38→1.50, Compress::Raw::Bzip2/Zlib, Config::Extensions, Config::Perl::V(USE_THREAD_SAFE_LOCALE 변수), CPAN, Data::Dumper 2.170→2.174(croak 시 누출 방지), DB_File, deprecate, Devel::Peek, Devel::PPPort, Digest::SHA, Encode 2.97→3.01, Errno, experimental, ExtUtils::CBuilder, ExtUtils::Manifest, ExtUtils::Miniperl, ExtUtils::ParseXS 3.39→3.40(OUTLIST 매개변수가 생성 프로토타입에 잘못 포함되지 않음), feature, File::Copy, File::Find 1.34→1.36($File::Find::dont_use_nlink이 모든 플랫폼 기본 1), File::Glob, File::Path, File::Spec, File::Temp, Filter::Util::Call, GDBM_File, HTTP::Tiny, I18N::Langinfo, IO, IO-Compress 2.074→2.084(IO::Uncompress::Zstd/UnLzip 지원, BinModeIn/BinModeOut이 no-op), IPC::Cmd, JSON::PP 2.97001→4.02(allow_nonref 기본), lib, Locale::Codes, Math::BigInt 1.999811→1.999816(bnok()이 전체 Kronenburg 확장), Math::BigInt::FastCalc, Math::BigRat, Module::CoreList, Module::Load, Module::Metadata, NDBM_File, Net::Ping, ODBM_File, PathTools, parent, perl5db.pl 1.54→1.55(스레드 코드 디버깅이 DB::sub/DB::lsub에서 deadlock 안 함), perlfaq, PerlIO::encoding 0.26→0.27(WARN_ON_ERR 경고가 use warnings "utf8"일 때만), PerlIO::scalar, podlators, POSIX, re, SDBM_File, sigtrap, Storable 3.08→3.15(빌드 시 재귀 제한 프로브 중단, CVE-2015-1592 탐지용 Metasploit 익스플로잇 코드 제거), Test::Simple, Thread::Queue, threads::shared, Time::HiRes, Time::Local, Time::Piece, Unicode::Collate, Unicode::UCD, User::grent, utf8, vars(vars.pm이 더 이상 strict vars 검사 시 non-vars strict 비활성화 안 함), version, warnings, XS::APItest, XS::Typemap.

제거된 모듈과 프래그마

미래 릴리스에서 코어에서 제거될 모듈들이 있고, 그때 CPAN에서 설치해야 해요. 코어 버전은 이제 "deprecated"-카테고리 경고를 내요. 이들은 (드문 예외를 제외하고) 계속 쓰길 권장되는 훌륭한 모듈들이에요.

  • arybase 제거 — $[ 변수(일명 array_base 피처)의 구현을 제공하던 모듈. 피처가 제거되어 이 내부 모듈도 사라졌어요.
  • B::Debug 더 이상 코어 배포에 포함되지 않아요. CPAN에서 계속 사용 가능.
  • Locale::Codes 작성자 요청으로 제거. CPAN에서 계속 사용 가능.

문서화

  • perlapiAvFILL()이 잘못 deprecated로 나열된 것 수정.
  • perlop — null(빈 줄) here doc 종결자 더 이상 없음 언급. 구분자가 아포스트로피일 때 tr 동작 명확화(하이픈 특수하지 않음, \x{} 보간 안 됨).
  • perlreapi, perlvarlastparen, lastcloseparen 문서 개선.
  • perlfunc-X가 대부분 테스트에서 심볼릭 링크를 따른다는 것, reset EXPR 동작, ref(qr/xx/)Regexp(REGEXP 아님) 반환.
  • perlreref/(?(cond)yes)/ 문법 명확화.
  • perllocale — 터키어용과 그 외용의 두 종류 UTF-8 로케일. 5.30부터 Perl이 매끄럽게 처리.
  • perlrecharclass::xdigit:: 문자 클래스 주석.
  • perlvar — 단락 모드의 더 구체적 문서.

진단

기존 진단 변경

  • deprecation 경고 "Unescaped left brace in regex is deprecated here (and will be fatal in Perl 5.30)..."이 non-deprecation 경고 "Unescaped left brace in regex is passed through in regex..."로 변경.
  • 중괄호 사이에 아무것도 없는 \o{} 지정이 치명적 오류 "Empty \o{}"를 내요(이전엔 "Number with no digits"). \p{} 같은 유사 구조와 같은 문구.
  • use re 'strict' 스코프 안에서 빈 \x{}가 "Empty \x{}" 치명적 오류. re 'strict' 밖에서는 빈 \x가 합법(그러나 현명하지 않음)이고 조용히 NUL 문자 생성.
  • Type of arg %d to %s must be %s (not %s) — 해시/glob에서 push, pop 등을 시도하면 더 이상 "스칼라에서 더 이상 동작하지 않음"이 아니라 이 메시지.
  • Prototype not terminated — 이 오류에 이제 파일과 줄 번호가 보고돼요.
  • -Dr(또는 use re 'Debug') 아래 무한대의 두 철자 INFINITYINFTY를 쓰던 것을 이제 후자만 사용.

유틸리티 변경

xsubppOUTLIST 매개변수가 더 이상 생성된 프로토타입(PROTOTYPES: ENABLE)에 포함되지 않아요.

구성과 컴파일

  • 스레드 안전 로케일 함수를 기본적으로 스레드 빌드에서만 쓰던 것을 -Accflags='-DUSE_THREAD_SAFE_LOCALE' 옵션으로 비스레드 빌드에서도 강제 사용 가능.
  • memrchr, strlcat, strlcpy 감지 개선.
  • memmem() Configure 감지 개선.
  • -DPERL_GLOBAL_STRUCT 빌드 옵션의 여러 개선·수정.
  • -DPERL_GLOBAL_STRUCT_PRIVATE 빌드 옵션 수정.

테스트

  • t/lib/croak/op — 해시/glob에서 push 등에 대한 별도 오류.
  • t/op/svleak.t — overload에서 goto &sub 누출 테스트 추가.
  • t/re/fold_grind.t를 여러 테스트 파일로 분할.
  • 병렬 테스트 동안 표면화되는 경합 조건으로 실패하던 간헐적 테스트 수정.
  • 새 테스트 파일 t/io/paragraph_mode.t로 단락 모드 철저 테스트.
  • t/io/eintr.t의 일부 테스트가 pre-16 Darwin에서 매달려 해당 버전에서 스킵.

플랫폼 지원

  • HP-UX 11.11 — HP C-ANSI-C로 컴파일할 때 pack()의 난해한 문제를 pp_pack.c의 최적화 비활성화로 수정.
  • Mac OS X-Duseshrplib 빌드가 System Integrity Protection(SIP)과 호환. SIP가 /bin 등의 바이너리에 DYLD_LIBRARY_PATH 전달을 막아서, 초기 빌드는 빌드 디렉터리에서 libperl.dylib을 찾고 설치 중 라이브러리 경로를 조정.
  • Minix3 — 일부 지원 재추가.
  • Cygwincuserid를 노출하지 않음.
  • Win32 Mingw — C99 수학 함수 사용 가능.
  • WindowsUSE_CPLUSPLUS 빌드 옵션이 win32/GNUmakefile(gmake)에도. nmake가 더 이상 Visual C++ 6.0 기본값 안 함 — CCTYPE 지정 필수. sleep() 경고 개선. Visual Studio 2019(VC++ 14.2) 지원. socket()이 조합을 찾지 못하면 $! 설정. Windows Server 2003 SP1 Platform SDK 빌드 수정.

내부 변경

  • 정규 표현식 컴파일러에서 sizing 패스가 제거됐어요. 대신 일부 케이스에서 괄호 캡처 그룹 수를 세기 위한 추가 패스가 필요할 수 있어요.
  • 새 함수 my_strtod()(또는 동의어 Strtod())가 libc strtod()와 같은 시그니처로 사용 가능. 모든 플랫폼에서 스트로드 동등 동작 제공, 플랫폼 능력과 Configure 옵션에 따라 최상의 정밀도, 로케일 관련 문제(소수점이 점인지 쉼표인지) 처리.
  • 소스에서 get magic을 처리하지 않고 SV를 복사하는 newSVsv_nomg() 추가.
  • 이제 PTRDIFF_MAX 바이트보다 많이 malloc하는 건 금지.
  • 두 새 regnode EXACT_ONLY8EXACTFU_ONLY8 도입. EXACT/EXACTFU와 동등하지만 UTF-8을 요구하는 코드 포인트를 포함해요. 따라서 대상 문자열이 UTF-8이 아니면 시도 없이 매칭 불가능을 알 수 있어요.
  • print_bytes_for_locale()DEBUGGING이면 이제 정의됨(이전에는 LC_COLLATE 정의 시에만).

주요 버그 수정

  • -DPERL_MEM_LOG-DNO_LOCALE 아래 컴파일 수정.
  • 5.28이 도입한 index() 최적화가 when 절 안에서 트리거되면 "Argument %s isn't numeric in smart match" 경고를 일으키던 것 수정.
  • 새 인플레이스 편집 코드가 더 이상 디렉터리 핸들을 누출하지 않아요.
  • 오버로드된 값의 상수 폴딩 연산에서 생성된 경고가 더 이상 가짜 "Use of uninitialized value" 경고를 내지 않아요.
  • "mutator not seen in (lex = ...) .= ..." 수정.
  • pack "u", "invalid uuencoding"이 생성되는 0-길이 SV를 제대로 NUL 종료.
  • -Dm으로 calloc() 호출의 디버깅 출력 개선.
  • Regexp 스크립트 실행이 일부 케이스에서 ASCII 숫자 허용에 실패하던 것 수정.
  • $^X 결정의 플랫폼 특정 기술이 실패할 때(예: /proc 미마운트 Linux) 일반 기술로 대체하지 않던 5.28.0 회귀 수정.
  • SDBM_File이 손상된 데이터베이스 파일에 더 견고해짐.
  • binmode($fh);/binmode($fh, ':raw');이 이제 Win32 기본 :crlf I/O 레이어에서 :utf8 플래그를 적절히 제거.
  • 실험적 참조 별칭 기능이 배열·해시 슬라이스 대입을 localised로 오해석하던 것(\(@a[3,5,7]) = \(....);local \(...)로 해석) 수정.
  • EXPR이 UTF-8 업그레이드된 eval EXPR 안의 sort SUBNAME이 비-ASCII SUBNAME이면 panic하던 것 수정.
  • 성공 시 errno를 수정하는 realloc()을 올바르게 처리(perl 사용자에게 보이지 않게).
  • Perl이 이제 가능하면 POSIX getcwdInternals::getcwd()로 노출(Cwd.pm 부트스트래핑용, 예고 없이 제거·변경 가능).
  • pack()이 더 이상 malformed UTF-8 반환 불가.
  • 정규 표현식 매칭이 $^R을 갱신할 때 오래된 UTF-8 길이 매직을 남기지 않아서 length($^R)이 잘못된 값을 반환하던 것 수정.
  • op의 재귀 감소(극단적으로 깊은 op 트리 처리 시 스택 오버플로 방지).
  • 다중 연결(multiconcat)의 오버로딩 누출 방지.
  • 사용자 정의 \p{} 속성 처리가 C로 재작성(속도 향상, 몇 가지 불일치·버그 수정 포함):
    1. 몇몇 오류 메시지의 문구가 약간 바뀜 — 이제 오류 발생 위치를 표시하는 정규 표현식 오류 처리 메커니즘에 통합.
    2. 사용자 정의 속성은 제약된 이름 규칙의 perl 서브루틴으로 구현됨. 패키지 미지정 시 현재 패키지에 있어야 한다는 문서가 모든 케이스에서 참이 되도록 수정.
    3. 모든 재귀 호출이 무한 재귀로 처리(이전엔 인터프리터 panic, 이제 패턴 컴파일 실패).
    4. 다른 오류도 이제 패턴 컴파일 실패로만.
    5. 속성 정의의 불법 범위 감지 — 이제 범위 max가 min보다 작으면 컴파일 실패.
    6. 각 sub가 프로그램 수명 동안 한 번만 호출되어 속성 정의가 불변이라는 의도 — /i 컴파일당 한 번, 잠재적으로 비-/i로 두 번째. 구성 요소가 아직 정의되지 않아 여러 호출 가능한 경우만 다중 호출 허용.
    7. 한 스레드가 다른 스레드와 동시에 같은 속성을 컴파일할 때의 경합·매우 긴 매달림 수정.
  • EXACTFish regnode가 문자열 길이 제한을 초과할 때 제대로 매칭하지 못하던 것 수정(이전 단계 regnode의 off-by-one 오류).
  • 이전 파일 핸들 없이 호출한 bare eof가 이제 true 반환.
  • 형식 컴파일 실패가 이제 컴파일을 중단(이전엔 파서를 이상한 상태로 남겨 컴파일을 계속하면 crash 가능).
  • 전역 소멸 중 인플레이스 편집이 진행 중이고 프로세스 종료 코드($?)가 0이면 perl이 인플레이스 편집을 성공으로 간주해 입력 파일을 출력으로 대체. perl -i -ne 'print "Foo"; last'는 대체, perl -i -ne 'print "Foo"; die'는 아님.
  • 5.28 회귀로 close(STDIN); open(CHILD, "|wc -l") 코드가 실패하던 것(자식 stdin이 exec에서 닫힘) 수정.
  • 컴파일-타임과 런타임 코드 블록 모두 포함 regexp 컴파일이 잘못된 문법 무언가를 컴파일하려 하던 문제 수정.
  • -DNO_LOCALE_NUMERIC/-DNO_LOCALE_COLLATE 빌드 실패 수정.
  • ext/B/t/strict.t 테스트 스킵 방지.
  • s로 끝나거나 시작하는 /di 노드가 이제 EXACTF. 두 EXACTFU가 최적화 중 합쳐져 ss, sS, Ss, SS 시퀀스를 형성하지 않도록(/ui/di에서 다르게 매칭될 수 있는 유일한 다중 문자 시퀀스).

감사의 말

Perl 5.30.0은 5.28.0 이후 약 11개월 개발, 58명 저자가 1,300개 파일에 약 620,000줄 변경. 자동 생성/문서/릴리스 도구 제외하면 750개 .pm/.t/.c/.h 파일에 약 510,000줄. Sergey Aleynikov가 AFL 퍼징으로 발견한 문제에 대한 고품질 perlbug 보고로 많은 버그 수정이 가능했어요.

버그 보고

https://rt.perl.org/에서 버그 데이터베이스를 확인하고, 미보고 버그는 perlbug를 실행하세요. 보안 함의가 있으면 perlsec의 "SECURITY VULNERABILITY CONTACT INFORMATION"을 보세요.

감사 표현

perlthanks 프로그램을 실행해 Perl 5 Porters에게 감사를 보낼 수 있어요.

함께 보기

Changes, INSTALL, README, Artistic, Copying 파일.