Я только что столкнулся с поведением, которое не поддается никакой логике и потенциально может привести к серьезным проблемам, и мне интересно, это ошибка или это поведение было изменено, и каковы наилучшие способы обойти эту проблему? Если это ошибка, есть ли исправление?
Вот два странных поведения, которые вместе представляют угрозу целостности данных любой системы.
int('1 2')
->41276
isValid('numeric', '1 2')
->true
Почему? Ну посмотрим...
<cffunction name="deleteSomething" access="public" returntype="void">
<cfargument name="somethingId" type="numeric" required="yes">
<cfquery datasource="#dsn()#">
DELETE
FROM Something
WHERE id = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.somethingId#">;
</cfquery>
</cffunction>
<cfset deleteSomething('1 2')>
Здесь проверка аргументов type="numeric"
(которая, возможно, основана на том же алгоритме, что и isValid
?) не срабатывает с '1 2'
. Хуже того, cfqueryparam cfsqltype="cf_sql_integer"
, похоже, использует int
для преобразования значения, которое в конечном итоге будет 41276
.
Другими словами, deleteSomething('1 2')
удалит объект с идентификатором 41276
вместо того, чтобы генерировать исключение, поскольку значение 1 2
явно не является числовым.
Теперь единственное исправление, о котором я подумал, - это выполнить дополнительную проверку аргумента с использованием isValid('integer', ...
или регулярного выражения, но это настоящая боль, и, кроме того, я никогда не понимал, почему они не реализовали type="integer"
?
Очевидно, я также всегда делал ложное предположение, что cfqueryparam type="cf_sql_integer"
подтвердит, что переданное значение является допустимым целым числом.
РЕДАКТИРОВАТЬ:
Кажется, что даже isvalid('integer', ...
также ненадежен, как мы можем видеть в
Why isvalid(integer, 1,5) = ДА?
РЕДАКТИРОВАТЬ2:
Я знаю, что могу добавить дополнительную проверку аргументов для каждого ожидаемого целочисленного аргумента в каждой функции, однако в моем случае это потребует исправления огромной базы кода, а также очень подвержено ошибкам. Это также делает встроенную проверку аргумента совершенно бесполезной в этом случае.
Я предпочел бы решение, в котором я мог бы создать и применить неофициальный патч. Это реальный вариант? Если это так, я хотел бы, чтобы меня указали в правильном направлении.
EDIT3: это не решает всех проблем, но в CF11 добавлена поддержка strictNumberValidation на уровне приложения.
«Начиная с ColdFusion 11, эта функция оценивается на более строгой основе. Установка этого значения в false приводит к тому, что функция isValid ведет себя по-старому. Этот параметр влияет на теги cfargument, cfparam и cfform везде, где используется целочисленная и числовая проверка. этот параметр, проверка также отражается на этих тегах».