Почему литералы символа C ints вместо символов?

Существует множество способов предотвращения SQL-инъекций и других SQL-хаков. Вы можете легко найти его в Интернете (Google Search). Конечно, PDO - одно из хороших решений. Но я хотел бы предложить вам некоторые хорошие ссылки с помощью SQL Injection.

Что такое SQL-инъекция и как предотвратить

Руководство PHP для SQL-инъекция

Microsoft объяснение SQL-инъекции и предотвращения в PHP

и некоторые другие, подобные Предотвращение SQL-инъекций с MySQL и PHP

Теперь, почему вам нужно предотвратить запрос из SQL-инъекции?

Я хотел бы сообщить вам: почему мы пытаемся предотвратить SQL-инъекцию с помощью Ниже приведен короткий пример:

Запрос для проверки подлинности входа:

$query="select * from users where email='".$_POST['email']."' and password='".$_POST['password']."' ";

Теперь, если кто-то (хакер) помещает

$_POST['email']= admin@emali.com' OR '1=1

и пароль что-либо ....

Запрос будет анализироваться в системе только до:

$query="select * from users where email='admin@emali.com' OR '1=1';

Другая часть будет отброшена. Итак, что будет? Неавторизованный пользователь (хакер) сможет войти в систему как администратор без своего пароля. Теперь он может делать все, что может сделать администратор / адрес электронной почты. См., Очень опасно, если SQL-инъекция не предотвращается.

101
задан Eitan T 6 July 2012 в 00:44
поделиться

9 ответов

обсуждение тот же предмет

"Более конкретно интегральные продвижения. В K& R C было фактически(?) невозможно использовать символьное значение без него продвигаемый на интервал сначала, таким образом делание интервала символьной константы во-первых устранило тот шаг. Были и все еще много символьные константы, такие как 'abcd', или однако многие поместятся в интервал"

36
ответ дан Malx 24 November 2019 в 04:44
поделиться

Я не знаю определенные причины, почему символьный литерал в C имеет интервал типа, Но в C++, существует серьезное основание не пойти тем путем. Рассмотрите это:

void print(int);
void print(char);

print('a');

Вы ожидали бы, что вызов для печати выбирает вторую версию, берущую символ. Наличие символьного литерала, являющегося интервалом, сделало бы это невозможным. Обратите внимание, что в литералах C++, имеющих больше чем один символ все еще, имеют интервал типа, хотя их значение является определенной реализацией. Так, 'ab' имеет тип int, в то время как 'a' имеет тип char.

21
ответ дан Johannes Schaub - litb 24 November 2019 в 04:44
поделиться

с помощью gcc на моем MacBook, я пробую:

#include <stdio.h>
#define test(A) do{printf(#A":\t%i\n",sizeof(A));}while(0)
int main(void){
  test('a');
  test("a");
  test("");
  test(char);
  test(short);
  test(int);
  test(long);
  test((char)0x0);
  test((short)0x0);
  test((int)0x0);
  test((long)0x0);
  return 0;
};

, который, когда выполненный дает:

'a':    4
"a":    2
"":     1
char:   1
short:  2
int:    4
long:   4
(char)0x0:      1
(short)0x0:     2
(int)0x0:       4
(long)0x0:      4

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

18
ответ дан dmckee 24 November 2019 в 04:44
поделиться

Я не забываю читать K& R и наблюдение фрагмента кода, который считал бы символ за один раз, пока оно не поразило EOF. Так как все символы являются допустимыми символами, чтобы быть в потоке файла/входа, это означает, что EOF не может быть никаким символьным значением. То, что сделал код, должно было поместить символ чтения в интервал, затем протестировать на EOF, затем преобразовать в символ, если бы это не было.

я понимаю, что это точно не отвечает на Ваш вопрос, но имело бы некоторый смысл для остальной части символьных литералов быть sizeof (интервал), если бы литерал EOF был.

int r;
char buffer[1024], *p; // don't use in production - buffer overflow likely
p = buffer;

while ((r = getc(file)) != EOF)
{
  *(p++) = (char) r;
}
6
ответ дан Kyle Cronin 24 November 2019 в 04:44
поделиться

Я не видел объяснения для него (C символьные литералы, являющиеся международными типами), но вот что-то, что Stroustrup должен был сказать об этом (от Дизайна и Эволюции 11.2.1 - Мелкозернистое Разрешение):

В C, тип символьного литерала такой как 'a' int. Удивительно, давая 'a' тип char в C++ не вызывает проблем совместимости. За исключением патологического примера sizeof('a'), каждая конструкция, которая может быть выражена и в C и в C++, дает тот же результат.

Так по большей части, это не должно вызывать проблемы.

5
ответ дан Michael Burr 24 November 2019 в 04:44
поделиться

Это - корректное поведение, названное "интегральное продвижение". Это может произойти в других случаях также (главным образом бинарные операторы, если я помню правильно).

РЕДАКТИРОВАНИЕ: Только, чтобы быть уверенным, я проверил свою копию Опытное Программирование C: Непостижимые тайны , и я подтвердил, что символьный литерал не делает , запускаются с интервал типа . Это имеет первоначально символ типа , но когда это используется в выражение , это , продвинул интервал . Следующее заключается в кавычки из книги:

Символьные литералы имеют интервал типа, и они получают там следующим правила для продвижения от символа типа. Это слишком кратко покрыто K& R 1, на странице 39, где это говорит:

Каждый символ в выражении преобразовывается в международное Уведомление, которое все плавание в выражении преобразовывается для удвоения.... Так как аргумент функции является выражением, преобразования типов также происходят, когда аргументы передаются функциям: в частности, символ и короткий становится интервалом, плавание становится двойным.

1
ответ дан PolyThinker 24 November 2019 в 04:44
поделиться

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

0
ответ дан Roland Rabien 24 November 2019 в 04:44
поделиться

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

0
ответ дан Blaisorblade 24 November 2019 в 04:44
поделиться

Это является только тангенциальным к спецификации языка, но в аппаратных средствах ЦП обычно только имеет один размер регистра - 32 бита, скажем, - и поэтому каждый раз, когда это на самом деле работает над символом (путем добавления, вычитая, или сравнивая его) существует неявное преобразование в интервал, когда это загружается в регистр. Компилятор заботится о надлежащем маскировании и смещении числа после каждой операции так, чтобы, если Вы добавляете, скажем, 2 к (неподписанный символ) 254, он повторился к 0 вместо 256, но в кремнии это - действительно интервал, пока Вы не сохраняете его назад к памяти.

Это - вид академической точки, потому что язык, возможно, указал 8-разрядный литеральный тип так или иначе, но в этом случае спецификация языка, оказывается, отражает более тесно, что действительно делает ЦП.

(x86 зубрилы может отметить, что существует , например, собственный addh op, который добавляет общекороткие регистры за один шаг, но в ядре RISC это переводит в два шага: добавьте числа, затем расширьте знак, как add/extsh пара на PowerPC)

0
ответ дан Crashworks 24 November 2019 в 04:44
поделиться