에서 SQL의 유효성을 검사 :치명적인 되돌아 내가 일반적인 형태의 일부 SQL을 검증하기 위해 노력하고있어 PHP
UPDATE `mytable` SET `keyname` = 'keyvalue',
`a` = 'somestring',
`b` = 123,
`c` = NULL
WHERE `keyname` = 'keyvalue'
이것보다 더 많은 필드가 있습니다. 값은 문자열, 정수 또는 NULL입니다.
이(?ix)
^
\s*
UPDATE \s+ `mytable` \s+
SET \s+ `keyname` \s = \s 'keyvalue'
(, \s+
`[A-Z_]+` (?# field name)
\s+ = \s+ (?# equals value)
(
-?[0-9]+ (?# an integer, possibly negative)
|
'(\\.|''|[^'])*' (?# a string in single quotes)
|
NULL (?# NULL)
)
)+ (?# one or more such assignments)
\s+ WHERE \s+ `keyname` \s+ = \s+ 'keyvalue'
$
이이 시점까지 작동합니다
내 원래 정규 표현식이 있습니다. https://regex101.com/에 따르면 180 단계로 일치합니다.
불행하게도 실제 SQL 예를 들어,보다 더 긴 것입니다 : 지금 4301 단계를 수행
UPDATE `mytable`
SET `keyname` = 'keyvalue',
`Markup` =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit.
''Quisque vel mattis odio, quis iaculis sem.''
Nulla facilisi.
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere
cubilia Curae; Fusce ut dui venenatis, maximus lorem eget, ornare ex.
Aenean tempus pulvinar est, id fringilla enim sagittis id. Mauris finibus
cursus commodo.\r\n\r\n
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere
cubilia Curae; Fusce ut dui venenatis, maximus lorem eget, ornare ex.
Aenean tempus pulvinar est, id fringilla enim sagittis id. Mauris finibus
cursus commodo.\r\n\r\n\r\n
\'Aenean in augue a est vulputate accumsan.\'
Phasellus nulla diam, laoreet a elit non, mattis finibus magna. Phasellus
faucibus iaculis mi sed pulvinar.\r\n
Aliquam non nisl ultricies, aliquam augue vitae, efficitur sapien.
Etiam viverra, magna a laoreet sollicitudin, ipsum erat tincidunt sem, nec
faucibus enim tortor eget massa.
Nunc nisi orci, lacinia vitae dictum et, vestibulum sed metus. ',
`From_Date` = NULL,
`To_Date` = NULL,
`Foo` = '',
`Box_Colour` = NULL,
`Modification_Date` = '2016-09-08 12:30:47',
`Modified_User` = 1,
`Modified_IP` = '192.168.1.1'
WHERE `keyname` = 'keyvalue'
. 사실 Lorem Ipsum을 더 크게 만들면 20000 단계가 넘습니다. 우리가 오류를 소개하면
또한 변경 예를 들어, (일치하지 만들려면) :
`Foo` = '',
그것은 지금 치명적인가을 되돌아와 충돌
`Foo` = ''
에.
내부 그룹 (키/값 쌍)을 원자 그룹으로 만들어 Catastrophic 역 추적을 제거 할 수 있습니다 (한도 내에서).
SET \s+ `keyname` \s = \s 'keyvalue'
(, \s+
실제 데이터에 20000+ 단계 내 대상 웹 서버에서 실행할 때 PHP 스크립트가 충돌을 일으키는
SET \s+ `keyname` \s = \s 'keyvalue'
(?>, \s+
에 : 그 변화이다. 좀 더 현실적인 가치로 단계를 내려야합니다. regexp가 합리적으로 명시적인 것처럼 보이면 왜 너무 많은 역 추적이있는 지 알 수 없습니다. 소유량 한정자 또는 원자 그룹을 비웃는 것은 아무 것도하지 않거나 "통과"또는 "실패"SQL이 올바르게 일치하지 않는 것으로 보입니다.
나는이 추측하고있어'하나입니다 (\\ |. ''| [^ ']) *'문제입니다. 작은 따옴표로 묶인 문자열의 어떤 형식을 기대합니까? – sln
또한'(? s)'한정자가 그 따옴표 하위 식의 줄에 걸쳐 있어야합니다. – sln
MySQL 스타일의 작은 따옴표가 붙은 문자열을 기대합니다. 실제 텍스트에는 여러 줄이 없을 것입니다 - ** mysqldump **에서 출력됩니다 - 값의 여러 줄은 \ r \ n으로 대체됩니다. –