У меня есть этот фрагмент кода, цель которого - определить, действителен ли полученный пакет:

size_t offset_to_a, offset_to_b;
u_int32_t file_name_length;
u_int32_t packet_length;

if ((offset_to_a + offset_to_b + file_name_length) > packet_length) {
    // Invalid packet
}

size_t равно u_int64_t, возможно, потому что процессор 64-битный.

Теперь, когда file_name_length имеет значение 0xFFFFFFFF (которое недействительно), пакет считается недействительным.

Но если size_t становится u_int32_t из-за базовой архитектуры, то для того же значения file_name_length условие не выполняется, потому что значение будет циклически повторяться, и пакет считается действительным.

Как я могу сделать это условие достаточно общим, чтобы работать на обеих 32/64-битных архитектурах?

Благодарность!

1
Maddy 4 Июл 2017 в 07:10
Значение 0xFFFFFFFF является максимальным 32-битным целым числом без знака и не заставляет 64-битное значение ломать голову. Таким образом, он будет работать идентично, если size_t 32-битный. Возможно, вы ошиблись при вводе 0xFFFFFFFFFFFFFFFF вместо 64-битного значения. Рассматривали ли вы типы фиксированного размера из <stdint.h> и <inttypes.h>? Они часто используются в современном коде, когда размеры фиксированы. (Есть несколько несовместимых альтернатив.) Технически они необязательны - некоторая платформа может не поддерживать uint16_t, и в этом случае не будет типа uint16_t. Однако всегда есть uint_least16_t типы.
 – 
Jonathan Leffler
4 Июл 2017 в 09:14
1
" Теперь, когда file_name_length имеет значение 0xFFFFFFFF (недопустимое), " Так почему же тогда просто не сделать простой if (file_name_length >= 0xffffffff) { // Invalid packet} ?
 – 
alk
4 Июл 2017 в 10:00
@alk: Ваше предложение действительно, и мы его учли. Спасибо!
 – 
Maddy
6 Июл 2017 в 08:23

1 ответ

Лучший ответ

Хитрость заключается в том, чтобы использовать только вычитание и вычитать только после того, как убедится, что вычитание не переносится. Что-то вроде этого:

if (offset_to_a > packet_length || packet_length - offset_to_a < file_name_length) {
    // invalid packet
}
size_t remain = packet_length - offset_to_a;
if (offset_to_b > remain || remain - offset_to_b < file_name_length) {
    // invalid packet
}
1
user3386109 4 Июл 2017 в 07:30