ColdFusion 9: int и type="numeric" противная ошибка?
Я только что испытал поведение, которое не поддается никакой логике и потенциально может привести к серьезным проблемам, и мне было интересно, было ли это ошибкой или было ли поведение исправлено, и каковы лучшие методы, чтобы обойти проблему? Если это ошибка, есть ли патч?
Вот два причудливых поведения, которые в совокупности представляют угрозу для целостности данных любой системы.
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', ...
также не является надежным, как мы можем видеть в
Почему isvalid ("integer", "1,5") = YES?
EDIT2:
Я знаю, что мог бы добавить проверку дополнительных аргументов для каждого ожидаемого целочисленного аргумента в каждой функции, однако это потребовало бы исправления огромной базы кода в моем случае, и это также очень подвержено ошибкам. Это также делает проверку встроенного аргумента совершенно бесполезной в этом случае.
Я бы предпочел решение, где я мог бы создать и применить неофициальный патч. Это реалистичный вариант? Если это так, я хотел бы указать в правильном направлении.
РЕДАКТИРОВАТЬ 3: Это не решает все проблемы, но CF11 добавил поддержку для конфигурации уровня приложения strictNumberValidation.
"Начиная с ColdFusion 11, эта функция оценивается более строго. Если установить для этого значения значение false, функция isValid будет вести себя по-старому. Этот параметр влияет на теги cfargument, cfparam и cfform везде, где используется целочисленная и числовая проверка. На основе этот параметр проверки также отражается в этих тегах ".
2 ответа
Это вариация на эту тему из другого вопроса. Посмотрите этот код (или запустите его на http://cflive.net/):
<cfscript>
s = "1 2";
i = int(s);
v = isValid("numeric", s);
d = createOdbcDate(s);
writeDump([s,i,v,d]);
</cfscript>
s
превращается в 41276
при звонке int()
и при использовании его в качестве входа для createOdbcDate()
, мы получаем:
January, 02 2013 00:00:00 +0000
Так "1 2"
интерпретируется как "m d"
с подразумеваемым годом текущего года.
Что совершенно глупо. Но вот, пожалуйста.
Вы можете использовать регулярные выражения, чтобы узнать, есть ли какие-либо нечисловые символы в данном поле формы:
reFind( "[^\d-]", "1 2")
Это будет соответствовать любому символу, который не является числом, не -
Если вы хотите проверить только положительные числа, вы можете использовать
reFind( "[^\d]", "1 2")
Если это вернется true
, у вас нет целого числа.