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를 먼저 읽어 보세요.
공지
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에서 계속 사용 가능.
문서화
perlapi—AvFILL()이 잘못 deprecated로 나열된 것 수정.perlop— null(빈 줄) here doc 종결자 더 이상 없음 언급. 구분자가 아포스트로피일 때tr동작 명확화(하이픈 특수하지 않음,\x{}보간 안 됨).perlreapi,perlvar—lastparen,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') 아래 무한대의 두 철자INFINITY와INFTY를 쓰던 것을 이제 후자만 사용.
유틸리티 변경
xsubpp — OUTLIST 매개변수가 더 이상 생성된 프로토타입(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 — 일부 지원 재추가.
- Cygwin —
cuserid를 노출하지 않음. - Win32 Mingw — C99 수학 함수 사용 가능.
- Windows —
USE_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())가 libcstrtod()와 같은 시그니처로 사용 가능. 모든 플랫폼에서 스트로드 동등 동작 제공, 플랫폼 능력과 Configure 옵션에 따라 최상의 정밀도, 로케일 관련 문제(소수점이 점인지 쉼표인지) 처리. - 소스에서 get magic을 처리하지 않고 SV를 복사하는
newSVsv_nomg()추가. - 이제
PTRDIFF_MAX바이트보다 많이 malloc하는 건 금지. - 두 새 regnode
EXACT_ONLY8와EXACTFU_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 기본:crlfI/O 레이어에서:utf8플래그를 적절히 제거.- 실험적 참조 별칭 기능이 배열·해시 슬라이스 대입을 localised로 오해석하던 것(
\(@a[3,5,7]) = \(....);를local \(...)로 해석) 수정. EXPR이 UTF-8 업그레이드된eval EXPR안의sort SUBNAME이 비-ASCII SUBNAME이면 panic하던 것 수정.- 성공 시 errno를 수정하는 realloc()을 올바르게 처리(perl 사용자에게 보이지 않게).
- Perl이 이제 가능하면 POSIX
getcwd를Internals::getcwd()로 노출(Cwd.pm부트스트래핑용, 예고 없이 제거·변경 가능). pack()이 더 이상 malformed UTF-8 반환 불가.- 정규 표현식 매칭이
$^R을 갱신할 때 오래된 UTF-8 길이 매직을 남기지 않아서length($^R)이 잘못된 값을 반환하던 것 수정. - op의 재귀 감소(극단적으로 깊은 op 트리 처리 시 스택 오버플로 방지).
- 다중 연결(multiconcat)의 오버로딩 누출 방지.
- 사용자 정의
\p{}속성 처리가 C로 재작성(속도 향상, 몇 가지 불일치·버그 수정 포함):- 몇몇 오류 메시지의 문구가 약간 바뀜 — 이제 오류 발생 위치를 표시하는 정규 표현식 오류 처리 메커니즘에 통합.
- 사용자 정의 속성은 제약된 이름 규칙의 perl 서브루틴으로 구현됨. 패키지 미지정 시 현재 패키지에 있어야 한다는 문서가 모든 케이스에서 참이 되도록 수정.
- 모든 재귀 호출이 무한 재귀로 처리(이전엔 인터프리터 panic, 이제 패턴 컴파일 실패).
- 다른 오류도 이제 패턴 컴파일 실패로만.
- 속성 정의의 불법 범위 감지 — 이제 범위 max가 min보다 작으면 컴파일 실패.
- 각 sub가 프로그램 수명 동안 한 번만 호출되어 속성 정의가 불변이라는 의도 — /i 컴파일당 한 번, 잠재적으로 비-/i로 두 번째. 구성 요소가 아직 정의되지 않아 여러 호출 가능한 경우만 다중 호출 허용.
- 한 스레드가 다른 스레드와 동시에 같은 속성을 컴파일할 때의 경합·매우 긴 매달림 수정.
- 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 파일.