1.84K subscribers
3.27K photos
130 videos
15 files
3.55K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
Bait and switch
😢12😐3🌚2
Блог*
#rustforlinux #suckassstory TL:DR: Тем временем в Linux один активный долбоёб мейнтейнер Christoph Hellwig активно мешает #Rust for Linux. DMA (Direct memory access) — технология, предоставляющая (относительно) прямой доступ к RAM для периферии. Это позволяет…
#rustforlinux #suckassstory

(link)
I no longer have any faith left in the kernel development process or community management approach.

Apple/ARM platform development will continue downstream. If I feel like sending some patches upstream in the future myself for whatever subtree I may, or I may not. Anyone who feels like fighting the upstreaming fight themselves is welcome to do so.


Гектор Мартин (Hector Martin), ведущий разработчик Asahi Linux, снял с себя полномочия мейнтейнера поддержки железа ARM и Apple
😢14👍3👌3
#prog #rustlib #article

parser combinators with nom 8 are here!

(восьмая мажорная версия — это прям дофига для Rust-библиотек)

Geoffroy Couprie рассказывает о новой архитектуре nom. В этой версии он позаимствовал из chumsky подход к архитектуре парсеров. Про этот подход ещё в 2022 году писал Niko Matsakis в статье Many modes: a GAT pattern, которая демонстрировала, как GAT могут пригодиться в реальных библиотеках, и таким образом обосновывала необходимость иметь GAT в языке.

В nom 8 парсером является то, что реализует трейт Parser. Вот как выглядит его определение за вычетом методов с реализацией по умолчанию:

trait Parser<Input> {
type Output;
type Error: ParseError<Input>;

fn process<OM: OutputMode>(
&mut self,
input: Input,
) -> PResult<OM, Input, Self::Output, Self::Error>;
}


Параметр OM реализует трейт OutputMode, реализации которого являются фактически type-level конфигом парсера:

trait OutputMode {
type Output: Mode;
type Error: Mode;
type Incomplete: IsStreaming;
}


Трейт Mode является ключом к новым возможностям. Реализации этого трейта позволяют абстрагироваться над "выходом парсера, имеющего отношение к T":

trait Mode {
type Output<T>;
// методы для комбинирования и преобразовывания Output
}


Для чего всё это нужно? Дело в том, что в nom есть комбинаторы, которые используют переданный аргументом парсер, но при этом не используют то, что этот парсер выдаёт в качестве результата. В качестве примера таких комбинаторов можно назвать preceded и delimited. Если конструирование значения является дорогим (скажем, это условный separated_list0, который собирает результаты разбора под-парсеров в вектор), то запускать парсер только ради того, чтобы отбросить его значение, будет довольно расточительно.

В самом nom определены два типа, которые реализовывают Mode: Emit и Check. Emit реализовывает Mode с type Output<T> = T, то есть парсер работает, как обычно. Check же реализовывает Mode с type Output<T> = (), то есть парсер работает, но отбрасывает результаты. Именно такое поведение годится для комбинаторов, которым не нужен результат под-парсера. Так как конечный парсер имеет методы, обобщённые по параметру OM, реализующему OutputMode, парсер не может сконструировать результат напрямую, а вынужден использовать для этого методы Mode, определённые на OM::Output. В случае Emit эти методы просто применяют переданные функции к аргументам, а для Check эти методы просто дропают переданные функции и возвращают ().

Так как ошибка парсера тоже может дорого конструироваться, тип OutputMode::Error по аналогичным причинам также реализует Mode. Это нужно, например, для opt, который делает парсер опциональным и по понятным причинам отбрасывает и разобранный результат, и ошибку.

Как вы могли заметить, у OutputMode также есть параметр Incomplete, реализующий трейт IsStreaming. Он отвечает за то, является ли недостаточный вход фатальной ошибкой или же одним из вариантов ошибки, от которой можно восстановиться. Раньше почти каждый базовый комбинатор nom существовал в двух версиях: streaming и complete. Это было нежелательно по нескольким причинам, главная из которых — разные сорта парсеров очень легко перепутать при написании своих парсеров и потом долго ловить непонятные ошибки. Ещё одним нежелательным следствием этого подхода стало, очевидно, дублирование кода. Разные версии этих парсеров по разному обрабатывали неполный вход, но за вычетом этого аспекта логика там была одинаковая.

Новый подход позволяет написать ветвление по OM::IsIstreaming::is_streaming() и обработать оба варианта в одной функции, естественным образом собирая разные варианты реагирования на ошибку неполного входа в одном месте. Так как в nom оба типа, реализующих IsStreamingStreaming и Complete — в соответствующих методах просто возвращают true и false соответственно, компилятор может увидеть ветвление по константному значению и просто убрать одну из веток, избежав генерации ненужного кода.
🔥7🎉2👌1
Из чуть менее важных новостей: nom ориентирован больше на написание парсеров для машинно-читаемых форматов, где в приоритете быстродействие. Для написания парсеров конфигов и языков программирования больше нужны другие вещи, которые в библиотеке для написания парсеров общего назначения не очень уместны. С релизом nom 8 также появился новый крейт nom-language, в котором в дальнейшем и будет добавляться код под такие нужды.

В настоящий момент там две вещи. VerboseError собирает все ошибки дерева парсеров и потому больше подходит для диагностирования ошибок в человеко-читаемом формате. Функция precedence позволяет разбирать выражения, учитывая приоритеты операторов, без их кодирования в грамматике:

// пачка импортов, которые не имеет смысла показывать

fn parser(i: &str) -> IResult<&str, i64> {
precedence(
unary_op(1, tag("-")),
fail(),
alt((
binary_op(2, Assoc::Left, tag("*")),
binary_op(2, Assoc::Left, tag("/")),
binary_op(3, Assoc::Left, tag("+")),
binary_op(3, Assoc::Left, tag("-")),
)),
alt((
map_res(digit1, |s: &str| s.parse::<i64>()),
delimited(tag("("), parser, tag(")")),
)),
|op: Operation<&str, &str, &str, i64>| {
use nom_language::precedence::Operation::*;
match op {
Prefix("-", o) => Ok(-o),
Binary(lhs, "*", rhs) => Ok(lhs * rhs),
Binary(lhs, "/", rhs) => Ok(lhs / rhs),
Binary(lhs, "+", rhs) => Ok(lhs + rhs),
Binary(lhs, "-", rhs) => Ok(lhs - rhs),
_ => Err("Invalid combination"),
}
}
)(i)
}

assert_eq!(parser("8-2*2"), Ok(("", 4)));
assert_eq!(parser("4-(2+2)"), Ok(("", 0)));
assert_eq!(parser("3-(2*3)+7+2*2-(2*(2+4))"), Ok(("", -4)));


(Если вы задаётесь вопросом, что там делает fail: этот аргумент функции precedence описывает, как парсить постфиксные выражения. В этой грамматике постфиксных операторов нет, поэтому попытка распарсить что-то, как постфиксное выражение, должно всегда завершаться ошибкой)
🤯4👍1🎉1
A perfectly reasonable development workflow

(часть треда с патчами в drm_sched от Asahi Lina (которые по итогу не приняли))
🤯6
#meme про... Тьюринга

Src
🫡22🌚64😭4🙏1
Forwarded from Too Long, Did Read
Subaru ImpressUs, или как открыть машину, зная только ее номер

https://samcurry.net/hacking-subaru

Прочитал недавно вышедший баг-репорт Сэма Карри - очень крутого баг-баунти хантера, который специализируется на поиске уязвимостей в компаниях-производителях автомобилей.
Сэм рассказывает о том, как год назад купил маме Subaru Impreza нового поколения, к которой по умолчанию прилагается сервис “Starlink” - нет, не спутниковый интернет Маска, а всего лишь умная система управления машиной + ее отслеживания, что-то вроде Find My, но для машин.
Оказалось, что зная номера машины, через эту систему ее можно отследить, открыть и угнать без шума.

Как это часто бывает, самая опасная часть айти-системы - админка для сотрудников, так как защищена она бывает плохо (ну а кто зайдет), а возможностей там просто дохрена.
Вот и в этой истории обнаружилось, что в админке крайне уязвимая апишка, если конкретнее - есть эндпоинт “resetPassword”, который ведет себя вот так:


POST /forgotPassword/resetPassword.json HTTP/1.1
Host: portal.prod.subarucs.com

{
"email": "[email protected]",
"password": "Example123!",
"passwordConfirmation": "Example123!"
}


{
"error": "Invalid email"
}


Дело за малым - нужно найти подходящий емейл сотрудника.
Естественно, корп емейл у Субару, как практически у всех, имеет формат [first_initial][last]@subaru.com, так что достаточно найти ФИО любого сотрудника на линкдине.

Но все-таки, не может же все быть так легко?

И да, и нет.
Для того, чтобы пользоваться функционалом админки после того, как мы вошли туда, сбросив пароль, надо также ввести 2FA - в данном случае, секретный вопрос, вроде “имя первой собаки”. бтв, ужасное решение, никогда не делайте так )
Но вскоре выяснилось, что функционал 2FA реализован… на фронте.
То есть, просто закомментив на уже отрисованном сайте 1 строчку:
//$(‘#securityQuestionModal').modal('show’);, можно спокойно пользоваться всем функционалом сайта.

Итак, мы внутри админки. Что дальше?

Начнем с того, что сотрудник имеет доступ к данным всех покупателей в США, Канаде и Японии (пиздец) - и ему доступен поиск по фио, телефону, и даже номерам машины. Как пишет Сэм, сложно сделать систему безопасной, если в ней предусмотрен такой уровень доступа для любого 18-ти летнего интерна в компании.

Одна из возможностей сотрудника в админке - добавлять верифицированного пользователя в систему Starlink… без уведомления текущих оунеров и юзеров. Ни смс, ни письма на почту, вообще ничего!
То есть, имея доступ в админку, я могу выдать себе доступ к вашей машине, а вы этого даже не узнаете.

А из самой системы Старлинк, наконец, можно:

- Удаленно заводить и останавливать, открывать, закрывать и отслеживать машину. А еще бибикать :)
- Вытащить историю перемещений машины ЗА ПОСЛЕДНИЙ ГОД, размеченную по времени + с информацией о том, когда машину заводили и глушили.
- Получить все персональные данные владельца, включая имена других авторизованных пользователей, домашний адрес и т д.
Хотя кому нужен домашний адрес, когда есть годовая история всех перемещений…

Дальше Сэм с коллегой сделали proof of concept, объединив все находки в одну консольную утилиту: вводишь номер машины, тебя редиректит на Starlink с полным доступом к машине.
Посмотрите видео, это просто полный треш: https://youtu.be/0i8juy6RPBI.

Заключение

Если вы думаете, что такие приколы бывают только с Субару, то можете посмотреть на аналогичную историю с KIA, а также на открытую базу данных Volkswagen, в которой хранится история перемещения ВСЕХ машин марки, включая машины полицейских и сотрудников спецслужб.

А еще советую всем интересующимся посмотреть выступление Сэма на DEFCON (он взломал все модемы очень крупного интернет-провайдера) и подкаст Critical Thinking с его участием: там он, например, рассказывает, к чему приводят его находки (его недавно арестовали на границе в аэропорту и обвинили в какой-то жести. но все хорошо закончилось).
🤯10👍9🤡61🌚1
Does bisexual mean "twice as sexual" or "once every other sexual"? 🧐

#vercheniye_academy
🍌6👍4🤣3
💔24🥰8😁52😭2🤯1
Forwarded from Neural Machine
Мой мозг словно гений, он покончил с собой в молодости и больше не работает.
👍11😁32😢2
notably, this does not compile
playground
🌚7🤯3🤡2🤣1😭1
Awful Rust snippets for fun and profit
notably, this does not compile playground
the problem is that dbg!() expands to something like
match 42 { tmp => ..., }

where tmp now parses as a constant pattern instead of a variable binding
🌚10🤡4🤣3
Nokia: connecting people
😐18🥰10😁9🤨6💩2🤡2
Forwarded from someone's shitpost
🤣23😭104🔥1😐1
Кто скажет, что я выкладываю херню, тот будет абсолютно прав
20👍5
Impossible
😭32
Forwarded from sanspie shi:3
добро пожаловать в питон, у нас в 2к25 до сих пор
😁13💩5🤔2🤡2🍌1
Forwarded from Artful Artform
"An Architectural Approach to Level Design" — первая книга про связь архитектуры и левел-дизайна, которая попалась мне в руки ещё в 2014 году, и с тех пор я считаю её одной из важнейших работ в этой сфере. Почему? Потому что она не просто учит применять архитектурные принципы в геймдизайне, но и позволяет взглянуть на архитектуру через призму видеоигр.

Левел-дизайн — это упрощённая модель архитектуры, где чётче видны её ключевые приёмы. Изучая, как пространство влияет на игрока, можно понять, какие элементы архитектуры действительно работают — и усилить их в реальном мире.

Автор книги, архитектор и геймдизайнер Кристофер Тоттен, рассматривает игровые уровни не просто как фон для геймплея, а как архитектурные пространства, формирующие нарратив и эмоции.

🔷 Архитектура в левел-дизайне
💜Как исторические здания помогают создавать эффективные игровые уровни.
💜Что из планировки, зонирования и направляющих линий можно перенести в геймдизайн.

😒 Как пространство управляет вниманием
💜 Визуальные символы, цвет, освещение и текстуры как инструменты навигации.
💜 Как эмоции игрока формируются через композицию уровней.

🐶 Повествование через пространство
💜 Как архитектура рассказывает истории без слов.
💜 Методы нарративного дизайна в игровых мирах.

👋 Городская среда и социальные взаимодействия
💜 Применение принципов урбанистики в мультиплеерных картах.
💜 Как левел-дизайн формирует способы взаимодействия игроков.

❤️ Музыка и звук как часть левел-дизайна
💜Как ритм и аудиодизайн влияют на восприятие пространства.

Тоттен объясняет базовые принципы проектирования, которые понятны и архитекторам, и геймдизайнерам. Это отличное чтение для всех, кто хочет глубже понять, как пространство влияет на восприятие человека — и в виртуальном, и в физическом мире.

Но самое интересное — через левел-дизайн можно переосмыслить саму архитектуру. Это зеркало, в которое архитектура может заглянуть и увидеть в своём отражении что-то новое.

Вся книга целиком доступна бесплатно в PDF по ссылке 🤓
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍75