Гепардово гнездо
https://github.com/boostorg/beast/pull/2878 ☕️☕️☕️ Как думаете, примут ли PR? :) :)
PR, кстати, приняли 🎉🎉🎉
GitHub
Add 418 I'm a teapot HTTP status · boostorg/beast@4bff457
HTTP and WebSocket built on Boost.Asio in C++11. Contribute to boostorg/beast development by creating an account on GitHub.
Скомпилируется ли такой код на Си?
И если нет, то почему?
Примечания:
- компилируем под GNU/Linux на x86_64 с glibc и компилятором gcc любой не очень древней версии
- можно убедиться, что код содержит только ASCII-символы и не содержит длинных последовательностей пробелов (то есть приколов вроде «вот здесь используется кириллическое е вместо e латиницей, попались!» в этом коде нет)
- в дополнение к предыдущему пункту: если вы перенаберете код в своей любимой IDE так, как его видите в посте, то он будет абсолютно идентичен
Догадки можно писать в комментарии :)
И если нет, то почему?
#include <sys/fcntl.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
typedef struct {
int mtime;
int size;
} Storage;
void load(Storage *st) {
scanf("%d%d", &st->mtime, &st->size);
}
int main() {
Storage st;
load(&st);
int st_mtime = st.mtime;
int st_size = st.size;
printf("st_mtime = %d, st_size = %d\n", st_mtime, st_size);
return 0;
}
Примечания:
- компилируем под GNU/Linux на x86_64 с glibc и компилятором gcc любой не очень древней версии
- можно убедиться, что код содержит только ASCII-символы и не содержит длинных последовательностей пробелов (то есть приколов вроде «вот здесь используется кириллическое е вместо e латиницей, попались!» в этом коде нет)
- в дополнение к предыдущему пункту: если вы перенаберете код в своей любимой IDE так, как его видите в посте, то он будет абсолютно идентичен
Догадки можно писать в комментарии :)
Гепардово гнездо
Скомпилируется ли такой код на Си? И если нет, то почему? #include <sys/fcntl.h> #include <sys/types.h> #include <errno.h> #include <unistd.h> #include <stdio.h> typedef struct { int mtime; int size; } Storage; void load(Storage *st) { scanf("%d%d"…
Ответ такой: код не скомпилируется. Даже несмотря на то, что он выглядит довольно безобидно, и явно никаких ошибок не видно.
Разгадка, как правильно указали в комментариях, заключается в следующем.
Где-то в недрах системных заголовков есть
И теперь выходит, что объявление переменной
Разгадка, как правильно указали в комментариях, заключается в следующем.
Где-то в недрах системных заголовков есть
struct stat
(здесь он прилетает через #include <sys/fcntl.h>
) — структура с метаданными файла, которая используется в системном вызове stat
. Изначально времена доступа к файлам хранились в этой структуре в полях st_mtime
, st_atime
, st_ctime
в виде UNIX таймстемпа с точностью до секунды. Затем точность повысили до наносекунд и стали использовать struct timespec
для задания времени (поля st_atim
, st_ctim
, st_mtim
). А чтобы не ломать обратную совместимость для тех программ, которые про наносекундную точность ничего не знают, вставили вот такой вот костыль:#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
И теперь выходит, что объявление переменной
st_mtime
дает ошибку, поскольку уже объявлен макрос ровно с таким же именем, и препроцессор раскрывает st_mtime
в st_mtim.tv_sec
Про throwing values
Расскажу коротко про throwing values (они же иногда называются herbceptions, потому что предложил их Herb Sutter). Полностью прочитать можно здесь, а я лишь отмечу основные моменты:
* функции, которые кидают исключение, помечены как
* такие «исключения» пробрасываются автоматически и синтаксически ловятся
* все исключения лежат в типе
Также в proposal'е предлагается добавить
На картинке выше (которую я честно украл из статьи) показывается сравнение синтаксиса throwing values и
Наверное, можно было бы еще поговорить на эту тему, но я вас уже и так закидал кучей разного текста на сегодня, поэтому остановимся здесь :)
Расскажу коротко про throwing values (они же иногда называются herbceptions, потому что предложил их Herb Sutter). Полностью прочитать можно здесь, а я лишь отмечу основные моменты:
* функции, которые кидают исключение, помечены как
throws
, при этом по сути они возвращают исключение просто как значение, в регистрах (почти как Result<T, E>
в Rust и std::expected<>
)* такие «исключения» пробрасываются автоматически и синтаксически ловятся
try
/catch
как обычные, хотя на самом деле в этом случае раскрутка стека не используется. Конечно, можно их так не реализовывать, а сделать почти как в Rust и требовать подобие оператора ?
, чтобы явно пробрасывать ошибку* все исключения лежат в типе
std::error
размером с два указателя (чем-то похоже на гошный тип error
и существующий в C++ std::error_code
). Первая половина — это категория ошибки, а вторая — ее содержание (просто код ошибки для простых случаев, указатель на подробное описание для сложных, в зависимости от категории). В статье приводится также мотивация в пользу единого типа ошибок std::error
вместо кучи разных типов как в текущей реализации исключенийТакже в proposal'е предлагается добавить
_Either(T, E)
в Си для поддержания совместимости, а еще оптимизации вида «юзать регистр флагов, чтобы понять, вернулась ошибка или значение».На картинке выше (которую я честно украл из статьи) показывается сравнение синтаксиса throwing values и
std::expected<>
, где видно, что код со throwing values выглядит гораздо проще.Наверное, можно было бы еще поговорить на эту тему, но я вас уже и так закидал кучей разного текста на сегодня, поэтому остановимся здесь :)
Драма в двух актах
(оригинал здесь: https://github.com/nim-lang/Nim/issues/23796)
(это я так законтрибутил фикс своей баги в Nim, а потом оказалось, что мой фикс ломает существующий код в специфичном сценарии)
(оригинал здесь: https://github.com/nim-lang/Nim/issues/23796)
(это я так законтрибутил фикс своей баги в Nim, а потом оказалось, что мой фикс ломает существующий код в специфичном сценарии)
Недавно наткнулся на интересный пост про онлайн-безопасность (а точнее, ее отсутствие) в Южной Корее:
https://palant.info/2023/01/02/south-koreas-online-security-dead-end/
Если кратко:
- по историческим причинам крупные банки вместо TLS используют свою криптографию и протоколы для организации шифрованного соединения
- чтобы эти протоколы использовать, необходимо ставить сторонние расширения или приложения
- сами эти приложения защищены плохо и используют устаревшие и уязвимые библиотеки
- по этой же причине долгое время обязательно требовался Internet Explorer, но ситуация с тех пор поменялась
- никто эту проблему так и не решил (по крайней мере, на момент начала 2023 года, когда этот пост вышел)
Если честно, я шокирован, что такая ситуация может быть в целой стране, причем довольно развитой и технологичной
https://palant.info/2023/01/02/south-koreas-online-security-dead-end/
Если кратко:
- по историческим причинам крупные банки вместо TLS используют свою криптографию и протоколы для организации шифрованного соединения
- чтобы эти протоколы использовать, необходимо ставить сторонние расширения или приложения
- сами эти приложения защищены плохо и используют устаревшие и уязвимые библиотеки
- по этой же причине долгое время обязательно требовался Internet Explorer, но ситуация с тех пор поменялась
- никто эту проблему так и не решил (по крайней мере, на момент начала 2023 года, когда этот пост вышел)
Если честно, я шокирован, что такая ситуация может быть в целой стране, причем довольно развитой и технологичной
Almost Secure
South Korea’s online security dead end
Websites in South Korea often require installation of “security applications.” Not only do these mandatory applications not help security, way too often they introduce issues.
Есть такой сайт в интернетах: https://tylervigen.com/spurious-correlations. Это наглядная демонстрация того, что корреляция не обязательно означает причинно-следственную связь, и может быть лишь удачным совпадением.
Работает он очень просто:
* собираем много разных графиков на много разных тем (около 20'000 штук!)
* попарно пробуем вычислить корреляцию между ними
* собираем все случаи, когда величины коррелируют с хорошей такой достоверностью
* публикуем :)
Сайт существует довольно давно, какое-то время назад он был сломан. Сегодня я зашел и увидел, что он снова работает и получил обновление в духе нынешнего времени:
* добавились «объяснения» корреляций с помощью LLM'ок
* также LLM'ками генерятся «научные» статьи вокруг найденной корреляции
Получилась еще и довольно забавная иллюстрация того, как можно «объяснить» все, что угодно :)
Работает он очень просто:
* собираем много разных графиков на много разных тем (около 20'000 штук!)
* попарно пробуем вычислить корреляцию между ними
* собираем все случаи, когда величины коррелируют с хорошей такой достоверностью
* публикуем :)
Сайт существует довольно давно, какое-то время назад он был сломан. Сегодня я зашел и увидел, что он снова работает и получил обновление в духе нынешнего времени:
* добавились «объяснения» корреляций с помощью LLM'ок
* также LLM'ками генерятся «научные» статьи вокруг найденной корреляции
Получилась еще и довольно забавная иллюстрация того, как можно «объяснить» все, что угодно :)
Tylervigen
Spurious Correlations
Correlation is not causation: thousands of charts of real data showing actual correlations between ridiculous variables.
Чем я еще заnimался
Расскажу, пожалуй, еще одну интересную историю про Nim.
Но сначала познакомлю вас с действующими лицами сего повествования:
*лучшего языка программирования в мире. Можете считать примерным аналогом
*
*
Теперь можно начинать рассказ.
Однажды я заметил, что мой CI-пайплайн программы на Nim замедлился аж на целых пять минут! Все мы прекрасно помним
В итоге, используя метод grep'а и внимательного чтения нагрепанного кода (очень полезный метод, кстати), я выяснил вот что:
*
* перед тем, как создать ссылки на распакованные бинарники в нужной папке,
*
* далее
* сборка компилятора — конечно же, дело небыстрое, и занимает те самые пять минут. Скажем лишь спасибо, что компилятор собирается довольно быстро, и не приходится ждать часами.
В общем, предсказуемо никакого Jia Tan'а здесь не оказалось, зато оказался банальный баг. А с багами поступают обычно просто: репортят и ждут фикса. Пофиксили его, впрочем, быстро и легко: теперь
Выводы из этой истории делайте сами.
Расскажу, пожалуй, еще одну интересную историю про Nim.
Но сначала познакомлю вас с действующими лицами сего повествования:
*
nim
: компилятор Nim, rustc
из мира Rust.*
nimble
: пакетный менеждер для языка Nim. Примерный аналог cargo
из мира Rust.*
choosenim
: утилита, которая умеет устанавливать nim
и nimble
нужных версий, а также обновлять их. Примерный аналог rustup
из мира Rust.Теперь можно начинать рассказ.
Однажды я заметил, что мой CI-пайплайн программы на Nim замедлился аж на целых пять минут! Все мы прекрасно помним
xz
и Jia Tan, и как из-за тормозов openssh
был найден очень хорошо спрятанный бэкдор. Но в случае с openssh
замедление составляло сотни миллисекунд, а здесь — аж целых пять минут! Паранойя зашкаливает, желание разобраться — еще больше.В итоге, используя метод grep'а и внимательного чтения нагрепанного кода (очень полезный метод, кстати), я выяснил вот что:
*
choosenim
скачивает бинарники nim
и nimble
(и еще кучу разных других нужных вещей), и распаковывает их* перед тем, как создать ссылки на распакованные бинарники в нужной папке,
choosenim
зовет nimble --version
, чтобы напечатать предупреждение, если версия nimble
слишком древняя и не поддерживается*
nimble
перед тем, как показать свою версию, проверяет свое окружение, и обнаруживает, что компилятора nim
нет на месте* далее
nimble
пытается исправить это безобразие. Для этого он сам клонирует репу с компилятором nim
и собирает его из исходников!* сборка компилятора — конечно же, дело небыстрое, и занимает те самые пять минут. Скажем лишь спасибо, что компилятор собирается довольно быстро, и не приходится ждать часами.
В общем, предсказуемо никакого Jia Tan'а здесь не оказалось, зато оказался банальный баг. А с багами поступают обычно просто: репортят и ждут фикса. Пофиксили его, впрочем, быстро и легко: теперь
--version
лишь выводит версию и больше ничего сделать не пытается.Выводы из этой истории делайте сами.
Я написал очень длинный и очень интересный текст про Юникод. Поскольку в Telegram пост такого размера не помещается, выложил на сайт:
https://blo.gepar.do/v0/unicode.html
Все бегом читать :)
https://blo.gepar.do/v0/unicode.html
Все бегом читать :)
Вдогонку про Юникод и Rust
Во-первых, спасибо всем, кто читал и распространял мой пост про Юникод :) Формат с большими текстами на сайте оказался, как видно, довольно неплох, и надо будет когда-нибудь попробовать его еще раз…
Во-вторых, хотелось бы рассказать еще немного про крейт unicode_categories в Rust, который упоминался в посте. Крейт этот примечателен вот чем:
* С одной стороны, он заброшен и не развивается (последний релиз в 2016 году, последний коммит в репу — в 2021), а еще имеет версию
* С другой стороны, он очень активно используется: под 80'000 скачиваний ежедневно, занимает 623 место по общему числу скачиваний, и от него зависят многие другие крейты. Какое-то время назад он даже использовался в
Выводы делайте сами. Мне вспоминается лишь https://xkcd.com/2347 :)
Во-первых, спасибо всем, кто читал и распространял мой пост про Юникод :) Формат с большими текстами на сайте оказался, как видно, довольно неплох, и надо будет когда-нибудь попробовать его еще раз…
Во-вторых, хотелось бы рассказать еще немного про крейт unicode_categories в Rust, который упоминался в посте. Крейт этот примечателен вот чем:
* С одной стороны, он заброшен и не развивается (последний релиз в 2016 году, последний коммит в репу — в 2021), а еще имеет версию
0.1.1
и не поддерживает новые версии Юникода.* С другой стороны, он очень активно используется: под 80'000 скачиваний ежедневно, занимает 623 место по общему числу скачиваний, и от него зависят многие другие крейты. Какое-то время назад он даже использовался в
rustfmt
, но, к счастью, его там заменили на более современный unicode-properties.Выводы делайте сами. Мне вспоминается лишь https://xkcd.com/2347 :)
This media is not supported in your browser
VIEW IN TELEGRAM
Про переписывание истории
В баше (а точнее, в GNU Readline, который используется башом), есть довольно странная фича: историю команд можно редактировать!
Делается это так:
* нажимаем клавишу ↑, доматываем до команды, которую хотим отредактировать
* редактируем команду
* нажимаем клавишу ↓, доматываем до конца
* готово :)
Наглядную демонстрацию можно видеть на видео выше.
Я на эту «фичу» неумышленно натыкался много раз, и, сам того не зная, редактировал историю. А потом недоумевал, почему у меня при вызове
Как это отключить? Можно почитать, например, здесь. Если коротко, то надо в домашней папке создать файл с названием
В баше (а точнее, в GNU Readline, который используется башом), есть довольно странная фича: историю команд можно редактировать!
Делается это так:
* нажимаем клавишу ↑, доматываем до команды, которую хотим отредактировать
* редактируем команду
* нажимаем клавишу ↓, доматываем до конца
* готово :)
Наглядную демонстрацию можно видеть на видео выше.
Я на эту «фичу» неумышленно натыкался много раз, и, сам того не зная, редактировал историю. А потом недоумевал, почему у меня при вызове
history
часть строк оказывались пустыми.Как это отключить? Можно почитать, например, здесь. Если коротко, то надо в домашней папке создать файл с названием
.inputrc
и поместить в него такие строчки:$include /etc/inputrc
set revert-all-at-newline on
Еще про проклятые фичи баша
https://yossarian.net/til/post/some-surprising-code-execution-sources-in-bash
tl;dr: вот эта функция на баше при передаче «правильного» аргумента может привести к выполнению произвольного кода:
Мораль проста:не пишите на баше не передавайте в bash-скрипты недоверенные данные
https://yossarian.net/til/post/some-surprising-code-execution-sources-in-bash
tl;dr: вот эта функция на баше при передаче «правильного» аргумента может привести к выполнению произвольного кода:
function guess() {
num="${1}"
if [[ "${num}" -eq 42 ]]
then
echo "Correct"
else
echo "Wrong"
fi
}
Мораль проста:
https://www.ryanliptak.com/blog/every-rc-exe-bug-quirk-probably/
Не знаю, как вы, а я просто обожаю такие посты.
Здесь автор попытался написать альтернативную реализацию компилятора ресурсов Windows. Это программа, которая принимает текстовый
Альтернативных реализаций компилятора ресурсов много, но у автора была цель, которой не добивались остальные:написать все на новом модном современном Zig как можно точнее сохранить совместимость с оригинальной версией от Microsoft, вплоть до багов и незадокументированного поведения.
Как достичь этой цели? Например, можно написать код, а затем пофаззить оригинальную реализацию с альтернативной и найти, на каких данных они выдают разные результаты. В результате этого процесса автор нашел горы странного поведения в компиляторе ресурсов от Microsoft.
Пост длинный; если хотите посмотреть только самое интересное, можно поискать по странице по словам
Не знаю, как вы, а я просто обожаю такие посты.
Здесь автор попытался написать альтернативную реализацию компилятора ресурсов Windows. Это программа, которая принимает текстовый
.rc
файл с описанием менюшек, кнопочек, окошек, иконок, курсоров и прочего, и компилирует это описание в бинарный .res
файл, который потом встраивается в бинарник приложения под Windows.Альтернативных реализаций компилятора ресурсов много, но у автора была цель, которой не добивались остальные:
Как достичь этой цели? Например, можно написать код, а затем пофаззить оригинальную реализацию с альтернативной и найти, на каких данных они выдают разные результаты. В результате этого процесса автор нашел горы странного поведения в компиляторе ресурсов от Microsoft.
Пост длинный; если хотите посмотреть только самое интересное, можно поискать по странице по словам
utterly baffling
. Если же у вас много времени и вам не лень, можно прочесть и все :)Ryanliptak
Every bug/quirk of the Windows resource compiler (rc.exe), probably - ryanliptak.com
Fuzz testing decades-old software can turn up some curious behaviors
Сегодня читал про то, как Debian везде перешел на 64-х битный
Проблема очень важная, ведь в 2038 году 32-х битный(осталось всего-то пережить пару эпидемий, восстание машин и ядерную войну), то проблему надо как-то решать!
Конечно же, не все настолько драматично. Большинство процессоров в мире уже давно как 64-х битные, и юзают «правильный», 64-х битный
Итак, для решения проблемы 2038 года в Debian приняли рядкомпромиссных решений странных костылей. Следите внимательно, чтобы не запутаться :)
* Для 64-х битных систем
* Для
* Для других 32-х битных архитектур (
Кстати, в Ubuntu этот переход тоже проделали, и пакеты с суффиксом
Выводы из всей этой истории делайте сами.
time_t
. Изменение войдет в релиз Debian 13 (будет выпущен летом/осенью следующего года).Проблема очень важная, ведь в 2038 году 32-х битный
time_t
переполнится, и многие компьютеры по всему миру не смогут узнать правильное время! А учитывая, что до 2038 года осталось немногим более 13 лет Конечно же, не все настолько драматично. Большинство процессоров в мире уже давно как 64-х битные, и юзают «правильный», 64-х битный
time_t
по умолчанию почти везде. Но старые, 32-х битные системы все еще существуют, и для них надо что-то придумать.Итак, для решения проблемы 2038 года в Debian приняли ряд
* Для 64-х битных систем
time_t
уже и так 64-х битный, поэтому весь «переход» заключается лишь в переименовании пакетов (например, libcurl4
→ libcurl4t64
). Новые пакеты с t64
при этом «предоставляют» пакет со старым именем, чтобы сторонние программы не заметили поломки ABI, не получили неудовлетворенных зависмостей и продолжали себе спокойно работать.* Для
i386
(так в Debian называют 32-х битные Intel'ы) пакеты тоже получили суффикс t64
, но time_t
там так и остался 32-х битным 🐳🐳 Как и на 64-х битных архитектурах, новые пакеты с t64
«предоставляют» старые. Так сделано, потому что либы под i386
очень уж часто юзаются для запуска старых программ, которые невозможно перекомпилить, поэтому поломка ABI для них нежелательна. А суффикс t64
все равно приписали, видимо, потому что переименование пакетов сделали для всех архитектур сразу.* Для других 32-х битных архитектур (
armel
, armhf
) пакеты тоже получили t64
суффикс, но при этом они получили еще и 64-х битный time_t
.Кстати, в Ubuntu этот переход тоже проделали, и пакеты с суффиксом
t64
уже есть в последнем LTS-релизе, 24.04.Выводы из всей этой истории делайте сами.
https://habr.com/ru/post/472970/
Статья 2019 года, то есть довольно старая, с учетом того, сколько всего разного с тех пор добавили в Telegram (включая комментарии, истории и анимированных китов🐳 )
В ней описывается куча странных технических решений и множество костылей в Telegram и его протоколе MTProto.
Насколько все улучшилось в Telegram со времен написания этой статьи? Я не знаю, но мне кажется, с учетом всего добавленного за пять лет, костылей и подпорок в нем стало сильно больше…
К сожалению, слова «часть 1» в заголовке — неправда, и вторая часть так и не вышла :(
Статья 2019 года, то есть довольно старая, с учетом того, сколько всего разного с тех пор добавили в Telegram (включая комментарии, истории и анимированных китов
В ней описывается куча странных технических решений и множество костылей в Telegram и его протоколе MTProto.
Насколько все улучшилось в Telegram со времен написания этой статьи? Я не знаю, но мне кажется, с учетом всего добавленного за пять лет, костылей и подпорок в нем стало сильно больше…
К сожалению, слова «часть 1» в заголовке — неправда, и вторая часть так и не вышла :(
Please open Telegram to view this post
VIEW IN TELEGRAM
Хабр
Критика протокола и оргподходов Telegram. Часть 1, техническая: опыт написания клиента с нуля — TL, MT
В последнее время на Хабре стали чаще появляться посты о том, как хорош Telegram, как гениальны и опытны братья Дуровы в построении сетевых систем, и т.п. В то же время, очень мало кто действительно...