(Надеюсь, этот ответ не слишком многословен. Я не думаю, что существующие ответы дали достаточно информации, но, надеюсь, не зашли слишком далеко...)
В CF есть разные области, в которые могут быть помещены переменные (приложение, сеанс, URL, cgi и т. д.).
Некоторые из них требуют использования явного объявления (например, переменные сеанса всегда должны иметь область действия), другие могут быть доступны автоматически при чтении переменной (например, переменные формы и URL-адреса могут быть прочитаны с использованием переменной без области видимости) - существует порядок приоритета. здесь, который определяет, какие области проверяются для переменной без области.
Нижняя область в этом порядке — это область variables
, которая применяется ко всему текущему экземпляру страницы/объекта.
При установке новой переменной, если она не определена, она создается в области variables
. Поскольку это глобальная область, к ней можно получить доступ как из разных экземпляров одной и той же функции, так и из разных функций, что вызывает проблемы, о которых вы знаете.
Чтобы переменная не попала в область глобальных переменных, вы должны поместить ее в область видимости local
функции. (Технически вы можете поместить его в область действия функции arguments
, но это, скорее всего, запутает людей.)
В более ранних версиях CF не было возможности явного доступа к локальной области — вам нужно было использовать ключевое слово var
, чтобы создать переменную внутри локальной области — и после создания она всегда будет иметь приоритет (как для чтения, так и для записи). над областью переменных.
В CF9 область local
теперь является "правильной" областью действия и к ней можно получить доступ явно, поэтому вместо использования <cfset var x = 0 />
вы можете написать <cfset local.x = 0 />
- основное преимущество этого заключается в том, что вы создаете переменную, в которой нельзя использовать ключевое слово var
, например. <cfquery name="local.qGetElementsByType" ...>
и <cfloop index="local.lcv"...>
Вам по-прежнему нужно применять локальную область видимости только при первом создании каждой переменной, чтобы она не попала в область переменных — последующие операции чтения/обновления могут быть неограничены, если вы предпочитаете, точно так же, как при выполнении var scope.
(Хотя есть и другие потенциальные проблемы, связанные с областью действия переменных без области видимости, например, внутри блока <cfloop query="queryname">
, и из-за этого некоторые люди будут утверждать, что вы всегда должны охватывать все переменные, несмотря ни на что.)
Подводя итог, чтобы сделать код, который вы показываете, безопасным, вам необходимо определить область действия:
qGetElementsByType
из тега cfquery
lvc
из тега cfloop
Поскольку эти переменные не создаются с помощью cfset, определение области действия проще всего выполнить, добавив к именам префикс local.
.
Поскольку вы уже определили область видимости переменной listCount в var
, вам не нужно делать это снова в той же функции — вы можете дополнительно использовать <cfset local.listCount = local.listCount + 1>
(или даже <cfset local.listCount++ >
), но опять же это вопрос предпочтений и не требуется для защиты от утечки в область действия переменных.
(примечание: в идеале вы должны использовать тег cfqueryparam вокруг #lcv#
для защиты от SQL-инъекций - даже если это запрос запроса, это все еще может быть проблемой, и всегда лучше перестраховаться в плане безопасности.)
Конечно, это только эта функция — вам также нужно исправить другие функции — и простой способ сделать это — использовать varscoper инструмент для сканирования всей вашей кодовой базы и определения переменных, которые нуждаются в области видимости.
person
Peter Boughton
schedule
10.06.2012
WHERE subjectid IN ( <cfqueryparam value="#arguments.element_type_id#" cfsqltype="cf_sql_integer" list="true"> )
- person Leigh   schedule 11.06.2012