Лучший способ предотвратить XSS не состоит в том, чтобы попытаться отфильтровать все, а скорее просто сделать кодирование Объекта HTML. Например, автоматически поворот < в & лейтенант;. это - идеальное решение, принимающее Вас, не должны принимать ввод HTML (за пределами областей форума/комментария, где это используется в качестве разметки, должно быть довольно редко должно принять HTML); существует столько перестановок через альтернативную кодировку, что что-либо кроме ультрастрогого белого списка (a-z, A-Z, 0-9, например) собирается пропустить что-то.
Внедрение SQL, вопреки другому мнению, все еще возможно, если Вы просто пристраиваете строку запроса. Например, если Вы просто свяжете входящий параметр на строку запроса, у Вас будет Внедрение SQL. Лучший способ защитить от этого также не фильтрует, а скорее неукоснительно использовать параметризированные запросы и НИКОГДА не связывать ввод данных пользователем.
Нельзя сказать, что фильтрация не является все еще лучшей практикой, но с точки зрения Внедрения SQL и XSS, Вы будете намного более защищены, если Вы неукоснительно будете использовать, Параметризовали Запросы и Кодирование Объекта HTML.
и Оператор
выполняет логическую операцию «И» для операндов bool
и не замыкается.
Это не точка последовательности. Вы не можете полагаться на порядок вычисления операндов. Однако гарантируется, что оцениваются оба операнда.
Я не рекомендую делать это. Использование временных переменных - лучшее решение. Не жертвуйте удобочитаемостью ради «умного кода».
Вы можете банально написать свой собственный.
bool LongCircuitAnd( bool term1, bool term2 ) { return term1 && term2; }
bool Func3(int x, int y, int z, int q){
return LongCircuitAnd( Func1(x,y), Func2(z,q) );
И если вы хотите быть очень необычным, вы можете даже встроить его !!!
Хорошо, хорошо, если вы действительно не хотите ' Я не хочу ужасных накладных расходов на вызов функции.
bool Func3(int x, int y, int z, int q){
return ((int)Func1(x,y)) * ((int)Func2(z,q));
Но я не считаю это элегантным. Вполне возможно, что слишком умный компилятор мог бы замкнуть это ...
и да, я понимаю, что могу использовать временные переменные для хранения результатов, возвращаемых двумя функциями, а затем выполнять логику «короткого замыкания» для временных переменных, но мне было интересно, есть ли там было "элегантным" языковым решением, позволяющим сохранить однострочный возврат в Func3, при этом получая сообщения журнала от обеих функций.
Это было бы "элегантное" решение :). Полагаться на побочные эффекты порядка оценки было бы далеко не изящным, подверженным ошибкам и трудным для понимания следующим разработчиком, который займется вашим проектом. Опора на побочные эффекты , конечно, контрастирует с чем-то вроде следующего фрагмента, который является полностью логичным и допустимым вариантом использования, полагающимся только на порядок оценки:
if ( obj != NULL && obj->foo == blah ) { /* do stuff */ }
Если вы хотите использовать временные переменные, но сохранить возврат к одному оператору, вы можете использовать оператор запятой:
return (b1=Func1()), (b2=Func2()), (b1&&b2);
Оператор запятой заставляет точку последовательности, поэтому каждая из них оценивает его левый операнд отбрасывает результат, а затем оценивает его правый операнд.
Другая возможность, но я бы не рекомендовал ее, будет для двух функций, чтобы вернуть тип, который перегружает оператор '&&'. Поскольку перегруженный оператор вызывает функцию, он всегда вычисляет оба операнда, даже в случаях (например, &&), где встроенный оператор не выполняет - обычно это проблема, но в данном случае это точно что вы хотите:
class mybool {
bool value;
public:
bool operator&&(mybool const &other) const {
return value && other.value;
}
};
mybool Func1(int, int);
mybool Func2(int, int);
bool Func3(int x, int y, int z, int q) {
return Func1(x, y) && Func2(z,q);
}
Хотя это работает, мне кажется, что это слишком "умно" - что-то, что не не быть очевидным для большинства читателей. Другое название для mybool
может помочь, но я не могу вспомнить одно, которое бы хорошо отражало намерение, не становилось бы таким многословным, что было бы чистым убытком.
Да, для этого есть встроенные операторы.
+
выполняет операцию ИЛИ без короткого замыкания, а *
выполняет операцию И.
#include <iostream>
using namespace std;
void print(bool b)
{
cout << boolalpha << b << endl;
}
int main()
{
print(true + false);
print(true * false);
}
Вывод:
true
false
Да. В перегруженных версиях оператора &&
и оператора ||
не происходит короткого замыкания - они оценивают оба операнда, даже если левый операнд «определяет» результат ... ( Источник )
При этом не следует перегружать оператор &&
или оператор ||
. Будьте вежливы со своими программистами по техническому обслуживанию, которые посмотрят на &&
или ||
и предположат, что у них происходит короткое замыкание.