Perl : Perl 5.8.0 버전에서의 UTF-8 패턴 매칭 문제
| 분류: Perl | 최초 작성: 2009-01-04 06:36:27 |
현재 펄 안정 버전은 5.8.8까지 나와 있는 상태(*이 글이 쓰여진 시기를 말합니다. 현재는 5.10.0 버전이 최신 버전이며, 5.8.9 버전이 발표되어 있기도 합니다.)입니다만, 아직 웹호스팅 업체들은 5.6.1 아니면 5.8.x대 초반 버전을 사용하고 있는 것이 현실입니다.
이것은 5.8.0 버전에서 발생하는 문제인데요. 예를 들면 이런 것입니다. 게시판 프로그램 등에서 사칭 방지 루틴 등을 짜면서, 일정한 값을 주고 해당 값이 패턴매칭되면 에러 메시지를 돌려주도록 프로그램할 수 있습니다. 예를 들면, 파싱 루틴이 이름을 $Form{'name'} 으로 파싱해준다고 합시다.
다음의 코드를 보십시오.
$Form{'name'} 에는 "관리자" 라는 값이 들어 있습니다.
my( @AdminProtectList ) = ( "관리자", "admin", "Admin" );
foreach $TempStr ( @AdminProtectList )
{
if ( $Form{'name'} =~ /$TempStr/ )
{
&ShowMsg( "Error : 사칭 금지 코드가 검출되었습니다." );
}
}
분명히 동작해야 할 것 같은 코드입니다. 실제로 EUC-KR 인코딩 상태에서는 매우 잘 동작합니다. 그러나, 이것을 UTF-8로 마이그레이션 하는 순간 이 코드는 정상적으로 동작하지 않습니다. 분명 이름 폼에 관리자 라고 입력하였음에도 불구하고 위 코드는 이를 매칭한다고 인식하지 못합니다. 5.8.0 버전의 UTF-8 지원 부분이 아직 완벽하지 못하다는 것이겠지요. (5.8.8 버전에서는 정상적으로 동작 합니다.)
따라서, 이는 (하위 호환성을 고려하여) 다음과 같이 작성되어야 합니다.
my( @AdminProtectList ) = ( "관리자", "admin", "Admin" );
foreach $TempStr ( @AdminProtectList )
{
my( $unpack_data1 ) = unpack "H*", $TempStr;
my( $unpack_data2 ) = unpack "H*", $Form{'name'};
if ( $unpack_data2 =~ /$unpack_data1/ )
{
&ShowMsg( "Error : 사칭 금지 코드가 검출되었습니다." );
}
}
위와 같이 unpack (16진수) 하여 매칭시키는 순간 위 코드는 매우 잘 작동합니다. (16진수로 변환하는 순간 그 안에는 0~9, A~F 밖에 존재하지 않게 되므로, 더 이상 그 변수의 인코딩은 UTF-8이 아니게 됩니다.)
이 문제는 사칭 코드 뿐만 아니라, 패턴 매칭 기법을 사용하는 모든 종류의 검색 및 검출 루틴에서 공통적으로 발생합니다.
[주1] 이 문제는 패턴 매칭에서만 발생하며, 단순 비교에서는 발생하지 않습니다.
즉, 위의 문제 코드의
if ( $Form{'name'} =~ /$TempStr/ )
부분을,
if ( $Form{'name'} eq $TempStr )
과 같이 작성하면 위의 문제는 발생하지 않습니다.
[주2] 이 문제는 한글의 경우 발생하며, 영문의 경우 발생하지 않습니다.