rtrim(DB()->escape($info_hash), ' ')

zxc

Легенда
Версия TP
иная
Вот это очень злая штука в announce.php. Зачем нам экранировать хэш? Нам надо сохранить строку в таком виде какая она есть. И что это за история с обрезанием пробела в конце инфо хэша?

Я бы не придирался к этому, но однажды я не смог зарегистрировать торрент, по причине того, что такой уже существует на трекере, хотя раздаваемые файлы были абсолютно разные и это случилось из-за DB()->escape() и наличии последоветельности \' в info_hash еще до экранирования

Если я заблуждаюсь по этому поводу, дайте знать

пока в announce.php стоит так
PHP:
    $info_hash_sql = bin2hex($info_hash);
 
    $info_hash_sql2 = bin2hex(rtrim($info_hash, ' ')); // старые торренты отвалилисиь пришлось вернуть этот костыль
    $info_hash_sql3 = bin2hex(rtrim(DB()->escape($info_hash), ' '));// старые торренты отвалилисиь пришлось вернуть этот костыль
 
    $passkey_sql   = DB()->escape($passkey);

    // OR HEX(tor.info_hash2) LIKE '$info_hash_sql%' - непонятный экспромт qbittorent разрабов, режут 32битный хэш до 20bit для совместимости
    $sql = "
        SELECT tor.topic_id, tor.poster_id, tor.tor_type, u.*, tor.complete_count
        FROM ". BB_BT_TORRENTS ." tor
        LEFT JOIN ". BB_BT_USERS ." u ON u.auth_key = '$passkey_sql'
        LEFT JOIN bb_users u1 ON u1.user_id = u.user_id
        WHERE HEX(tor.info_hash) = '$info_hash_sql'
            OR HEX(tor.info_hash) = '$info_hash_sql2'
            OR HEX(tor.info_hash) = '$info_hash_sql3'
            OR HEX(tor.info_hash2) = '$info_hash_sql'
            OR HEX(tor.info_hash2) LIKE '$info_hash_sql%'
        LIMIT 1
    ";

в function tracker_register(
PHP:
    $info_hash     = pack('H*', sha1(bencode($info)));
    $info_hash2    = pack('H*', hash('sha256', bencode($info)));
    //$info_hash_sql = rtrim(DB()->escape($info_hash), ' ');
    $info_hash_sql = bin2hex($info_hash);
    $info_hash2_sql= bin2hex($info_hash2);
    $info_hash_md5 = md5($info_hash);

    $sql = "SELECT topic_id
        FROM ". BB_BT_TORRENTS ."
        WHERE HEX(info_hash) = '$info_hash_sql' OR HEX(info_hash2) = '$info_hash2_sql'
        LIMIT 1";

        .....
    $columns = ' info_hash, info_hash2,    post_id,  poster_id,  topic_id,  forum_id,  attach_id,    size,  reg_time,  tor_status';
    $values = "x'$info_hash_sql', x'$info_hash2_sql', $post_id, $poster_id, $topic_id, $forum_id, $attach_id, '$size', $reg_time, $tor_status";
 
Последнее редактирование:

kovalensky

Разработчик (ex)
Модератор
rtrim() стоял в целях совместимости, можете избавиться.
escape() же должен присутствовать, иначе sql инъекция, проблем связанных с ним я не встречал.

Да, бинарная строка экранируется, но это не мешает поиску.
Но если у вас наблюдается что-то, то можно поступить без экранирования:

PHP:
// $info_hash_sql3 = bin2hex(rtrim(DB()->escape($info_hash), ' '));
if (!ctype_xdigit(bin2hex($info_hash))) {
    msg_die("Invalid info hash");
}
 

zxc

Легенда
Так а если у меня info_hash тип varbinary(20) и я туда отправляю bin2hex($info_hash) это тоже грозит инъекцией?
 

kovalensky

Разработчик (ex)
Модератор
ctype_xdigit() я предложил только для проверки в анонсере, если хотите избавиться от этапа экранирования строки (работоспособность в запросе я не проверял).

Я не могу никак понять вашу цель, боюсь возникнет путаница, если продолжу писать.
Почему здесь столько sql запросов на info_hash:
PHP:
        WHERE HEX(tor.info_hash) = '$info_hash_sql'
            OR HEX(tor.info_hash) = '$info_hash_sql2'
            OR HEX(tor.info_hash) = '$info_hash_sql3'
            OR HEX(tor.info_hash2) = '$info_hash_sql'
            OR HEX(tor.info_hash2) LIKE '$info_hash_sql%'
 

zxc

Легенда
Логика следующая (если опираться на мой код):
-Я словил дубль в базе для разных торрентов в поле info_hash из-за DB()->escape() (к сожалению это было несколько лет назад, но помню что это было связано с торрентом у которого в info_hash была последовательность \\', \\"", \\" или что-то подобное)
-Я отказался от экранирования и заменил на rtrim($info_hash, ' ')
-Позже отказался и от rtrim

Поэтому вот такой велосипед из трех проверок для совместимости

четверкая проверка
OR HEX(tor.info_hash2) LIKE '$info_hash_sql%'
Расчитана на то, чтобы проверить является ли хэш обрезаной версией v2 32 битного хэша, либо полной версией

В коде движка это реализовано как SUBSTRING(tor.info_hash_v2, 1, 20)

Если этого не указать в анонсере - отваливаются старые торренты, т.к. в function tracker_register( было указано $info_hash_sql = rtrim(DB()->escape($info_hash), ' ');

Это все делалось на рабочем проекте и наблюдалось
 
Сверху