2013-10-02 5 views
1

Я только что испытал поведение, которое бросает вызов любой логике и потенциально может привести к серьезным проблемам, и задалось вопросом, была ли ошибка , или было ли поведение изменено и какие методы лучше всего обойти проблему? Если это ошибка, есть ли патч?ColdFusion 9: int и type = "numeric" неприятная ошибка?

Вот два поведенческих поведения, которые при объединении представляют собой угрозу целостности данных любой системы.

  1. int('1 2') ->41276
  2. 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') удалит объект с id 41276 вместо того, чтобы выбрасывать исключение, поскольку значение 1 2, очевидно, не является числовым.

Теперь, единственное исправление, о котором я думал, состоит в том, чтобы выполнить дополнительную проверку аргумента с использованием isValid('integer', ... или регулярного выражения, но это настоящая боль, и, кроме того, я никогда не понимал, почему они не реализовали type="integer"?

Очевидно, что я всегда делал ложное предположение, что cfqueryparam type="cf_sql_integer" будет проверять, что переданное значение является действительным целым числом.

EDIT:

Кажется, что даже isvalid('integer', ... также не надежны, как мы можем видеть в
Why isvalid("integer","1,5") = YES?

EDIT2:

Я знаю, что я мог бы добавить проверку additionnal аргументы для каждого ожидаемого целого аргумент в каждой функции, однако это потребует исправить огромную базу кода в моем случае, и это также очень подвержено ошибкам. Это также делает встроенную проверку аргумента совершенно бесполезной в этом случае.

Я бы предпочёл решение, в котором я мог создать и применить неофициальный патч. Это реалистичный вариант? Если так, я бы хотел, чтобы вас указали в правильном направлении.

EDIT3: он не решает все проблемы, но CF11 добавила поддержку конфигурации уровня приложения strictNumberValidation.

«Начиная с ColdFusion 11, эта функция оценивает на более строгой основе. Установка этого значения ложь делает IsValid функцию ведут себя в старой дороге. Эта настройка эффектов cfargument, cfparam и cfform теги везде, где integer & используется цифровая проверка.На основании этого параметр, проверка отражает в этих тегах, а «

+1

Duplicate question of: http://stackoverflow.com/questions/11535979/why-isvalidinteger-1-5-yes похоже, что adobe не фиксирует это. – Jarede

+0

@ Jarede, Спасибо за ссылку. Однако я считаю, что мой вопрос подчеркивает еще несколько аномалий и не дублирует. – plalx

+1

Если вы посмотрите на соответствующий вопрос SO, он в значительной степени ответит на все, что вы подняли. см. @Mike Causer ответ на специфику. – Jarede

ответ

2

Это вариация на эту тему с другим вопросом Смотрите этот код (или запустить его на 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" с предполагаемым годом текущего года.

Это совершенно глупо. Но ты туда.

+1

Будет ли какой-либо способ создать и применить неофициальный патч? В этом случае это поведение делает встроенную проверку аргумента совершенно бесполезной. – plalx

+0

http://www.cflib.org/udf/IsInt, похоже, помогает –

+0

@JamesMohler, Не совсем. Проблема заключается в том, чтобы исправить чрезвычайно огромную базу кода и * ненужные служебные данные, которые подразумеваются при выполнении дополнительной проверки типов для каждого ожидаемого целочисленного аргумента. Я определенно предпочел бы исправить проблему в ее ядре. – plalx

0

Вы можете использовать регулярные выражения, чтобы узнать, есть ли какие-либо нечисловой символы в заданном поле формы:

reFind("[^\d-]", "1 2") 

Это будет соответствовать любому символу, который не является числом, а не -

Если вы хотите проверить только положительные числа, вы можете использовать

reFind("[^\d]", "1 2")  

Если это возвращает true, вы не целое число.

+0

Спасибо, но я уже сказал это решение в вопросе. – plalx

+1

'--0 --- 0 -' не число; проверка того, является ли ввод целым числом со знаком с регулярным выражением, было бы лучше сделать с 'NOT refind ("^-? \ d + $ ", input)' ... для второго, '\ D' является ярлыком для' [^ \ d] ' –

+0

Хорошая точка. Это научит меня быстро не писать регулярное выражение. –