Бестиарий программирования
1.06K subscribers
303 photos
5 videos
4 files
374 links
Наблюдения за жизнью ошибок в коде.
Андрей Карпов.

ГОСТ Р 71207-2024, ГОСТ Р 56939-2024, РБПО, Статический анализ кода

Канал-дублёр в MAX: https://max.ru/join/3VWTp9apkQvTMSRQ__LGiTQ5NGVBj8p_tOpwlQO6vS8
Download Telegram
Запись вебинара "Инструменты для разработчиков игр и не только".

Вместе с экспертами из Forgotten Empires и Playrix мы разобрались, какие инструменты входят в арсенал GameDev-команд, зачем они нужны и почему профилировщики играют ключевую роль в разработке. А бонусом — показали, как превратить ваш код в настоящий город.
🔥2
Финальный вебинар цикла!

Тема: "Сертификация процессов РБПО: требования ФСТЭК России, новые стандарты и практика"

На вебинаре разберем практику сертификации, новые национальные стандарты и методику подготовки, опыт компаний, а также подводные камни аудита, ресурсы и преимущества внедрения РБПО.

Приглашенные эксперты:
- Дмитрий Шмойлов, Head of Software Security, Kaspersky.
- Щербаков Алексей, руководитель центра кибербезопасности Платформы СберТех
- Виталий Вареница, руководитель сертификационной лаборатории

Сегодня в 16:00

Регистрация по ссылке 🔗

#вебинар #рбпо
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Один из способов подавления ложных срабатываний PVS-Studio, это специальные комментарии в коде. К сожалению, постепенно в коде могут накапливаться неактуальные комментарии подавления. Такое происходит, если код изменился и не вызывает более подозрения у анализатора. Или анализатор стал лучше понимать задумки программистов и более не выдаёт в каких-то местах срабатываний.

Поэтому мы реализовали в PVS-Studio механизм удаления неактуальных комментариев. Подробности в статье - Комментарии, которые пережили ошибки.
4
Media is too big
VIEW IN TELEGRAM
Для C++ программистов и не только. Обзор 10 уроков, посвящённый написанию своего языка программирования. Полностью материалы бесплатно представлены здесь.
🔥5
Команда PVS-Studio усердно работала над созданием статического анализатора кода для Go, и наконец мы рады объявить о начале открытого тестирования! Приглашаем всех заинтересованных присоединиться.

В этой заметке рассказываем, как это сделать 🔗

#go #тестирование #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Начал появляться код тех самых навайбкоденных проектов, который изменит мир и т.д. Ну а я начинаю потихоньку смотреть код этих проектов вообще и сквозь призму статического анализа в частности. Пока в глаза бросается, что код растянут и это мешает его восприятию. Например, человек бы так писать не стал, а воспользовался функцией sprintf.
      char seq[32];
int s = 0;
seq[s++] = ':';
seq[s++] = ' ';
seq[s++] = 'i';
seq[s++] = 'c';
seq[s++] = 'm';
seq[s++] = 'p';
seq[s++] = '_';
seq[s++] = 's';
seq[s++] = 'e';
seq[s++] = 'q';
seq[s++] = '=';
seq[s++] = '0' + i;
seq[s++] = ' ';
seq[s++] = 't';
seq[s++] = 't';
seq[s++] = 'l';
seq[s++] = '=';
seq[s++] = '6';
seq[s++] = '4';
seq[s++] = ' ';
seq[s++] = 't';
seq[s++] = 'i';
seq[s++] = 'm';
seq[s++] = 'e';
seq[s++] = '=';
/* Random-ish time 10-50ms */
int time_ms = 15 + (i * 7) % 30;
seq[s++] = '0' + (time_ms / 10);
seq[s++] = '0' + (time_ms % 10);
seq[s++] = ' ';
seq[s++] = 'm';
seq[s++] = 's';
seq[s++] = '\n';
seq[s] = '\0';
🤣4😱2👍1
Может зато опечаток нет? Есть.

PVS-Studio: V560 A part of conditional expression is always false: btn_char == '+'. window.c 1713
👍9
Наша команда работает еще над анализатором для JavaScript и TypeScript! 🔥

Приглашаем всех заинтересованных присоединиться к тестированию. В этой заметке все подробности 🔗

#js #ts #статья #тестирование
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5
Создал канал-дублёр в MAX: Бестиарий программирования
😐10🤨4👍3🤯3😢2
Ещё на тему разбухшего vibe-кода. Смотрю проект Vib-OS. Потом про него статья будет. Это очень маленький проект, если убрать сторонние сущности и различные ресурсы, хранящиеся в виде массивов в коде. По делу там около 35 тысяч строк кода в 110 файлах.

Так вот, на эти 110 файлов я насчитал как минимум 4 одинаковые функции копирования строк.
static void str_copy(char *dst, const char *src, int max) {
int i = 0;
while (src[i] && i < max - 1) {
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}

static void str_cpy(char *dst, const char *src, int max) {
int i = 0;
while (src[i] && i < max - 1) {
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}

static void strcpy_safe(char *dst, const char *src, size_t max) {
size_t i = 0;
while (src[i] && i < max - 1) {
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}

static inline char *strncpy_safe(char *dst, const char *src, size_t n) {
size_t i;
for (i = 0; i < n - 1 && src[i]; i++) {
dst[i] = src[i];
}
dst[i] = '\0';
return dst;
}

Видимо у ИИ который это делал, любимый напев – I Like to Move It, Move It :) Частое (местами совершенно бестолковое) копирование массивов. Причём реализованное циклами, а не через memcpy.
😁13
В комментариях к предыдущему посту написали, что memcpy не проверяет завершающий ноль, поэтому плохо подходит для копирования строк. Это так, но я имел в виду, что в рассматриваемом проекте вообще очень много копирования данных "вручную", не являющихся строками. Постоянно встречается код вида:
uint8_t *src = buf + offset_in_block;
uint8_t *dst = (uint8_t *)inode;
for (size_t i = 0; i < sizeof(struct ext4_inode); i++) {
dst[i] = src[i];
}

uint8_t *src = sb_buf;
uint8_t *dst = (uint8_t *)&fs->sb;
for (size_t i = 0; i < sizeof(struct ext4_superblock); i++) {
dst[i] = src[i];
}

uint8_t *src = (uint8_t *)ptr;
uint8_t *dst = (uint8_t *)new_ptr;
for (size_t i = 0; i < old_size; i++) {
dst[i] = src[i];
}

Все эти четверостишия могут быть заменены на один вызов memcpy.
👍3
Ещё пример. Функция bt_set_local_name просто перекладывает строку в буфер размером 248 байт и передаёт её в hci_send_cmd.
int bt_set_local_name(const char *name)
{
uint8_t params[248] = {0};
int len = 0;

while (name[len] && len < 247) {
params[len] = name[len];
len++;
}

return hci_send_cmd(HCI_OP_WRITE_LOCAL_NAME, params, 248);
}

Посмотрим, что происходит со строкой дальше:
static int hci_send_cmd(uint16_t opcode, void *params, uint8_t plen)
{
uint8_t buf[256];

buf[0] = HCI_COMMAND_PKT;

struct hci_command_hdr *hdr = (struct hci_command_hdr *)&buf[1];
hdr->opcode = opcode;
hdr->plen = plen;

if (plen > 0 && params) {
for (int i = 0; i < plen; i++) {
buf[4 + i] = ((uint8_t *)params)[i];
}
}

/* TODO: Send via USB bulk endpoint */
printk(KERN_DEBUG "BT: Send cmd opcode=0x%04x len=%d\n", opcode, plen);

return 0;
}

Формируется новый буфер из специального заголовка и переданной строки. Дальше этот буфер пока не используется, но суть не в этом. Непонятно, зачем вообще был нужен промежуточный буфер в bt_set_local_name. Код можно сократить, попутно ускорив его, убрав одно копирование.
😁1