В сей нити мы упорядочиваем усилия по доработке местного движка. Репозиторий: https://codeberg.org/FBE410/fbe-410 1. Для ваших предложений предназначена ветка public. 2. Только администрация 410чана решает, что в этом движке надо, а что не надо. Соответственно, не стоит излишне пропихивать всякие там революционные идеи. Одобренные потенциальные изменения перечислены на багтрекере (записи, созданные владельцами репозитория). 3. Тестирование предложенных изменений и развёртывание принятых ведётся при наличии у администрации свободного времени на это. Обычно это делается по выходным. 4. Код выложен как есть. Никаких неопубликованных скрытых функций и частей не существует. Предыдущая нить: >>20450
Думаю в качестве значка сажи использовать шалфей, лол. Пока как-то так. >>27829 Можно. Я так понимаю, с точки зрения расширения «Ѳеора» = ОГВ, и нам уже сейчас следует убрать его из разрешённых к загрузке?
>>27831 Да. Ужé послѣ того, как загрузка перестанет быть разрѣшённою, можно будет и из кода FBE выкинуть строчку специальной обработки таких загрузок («if( $expectedFormat === 'ogv' ) $expectedFormat = 'ogg';»).
>>27831 Как-то с шалфеем вы меня потеряли, в чем суть?
>>27833 Sage (сажа) — не только мудрец, но и растение. https://www.nccih.nih.gov/health/sage
>>27833 А ведь обо всём написано здесь: https://noobtype.ru/wiki/Sage
>>27836 Читайте и тщательно конспектируйте Нубтайп...
Завёл задачу про значок сажи: https://codeberg.org/FBE410/fbe-410/issues/51 Файл приложен сюда, но следует преобразовать его, как описано здесь: https://codeberg.org/FBE410/fbe-410/src/branch/public/icons
На мобилке, может, вернуть старый размер шрифта для topmenu? У меня не влезает и не красиво. A52.
>>27842 Скукожили обратно.
>>27842 Алсо, смотрю я на этот скрин с формой постинга на весь экран, и думается, а не стоит ли нам сделать сворачивание формы создания нити как на «4чане»?
>>27847 Мне кажется как минимум ради мобилок стоило бы, чтобы сразу было видно топ-нить и не надо было пролистывать
>>27851 Но верхнюю нить (начало её) и так сразу видно. >>27847 Не на весь.
>>27852 Да всё равно, на пол-экрана форма что на мобилках, что на ПК.
>>27543 > Давайте обсудим, как эта лабуда должна себя вести. Предлагаю, окромя счётчиков слѣва (у букв досок), помѣстить ещё один счётик справа (у кнопки «Главная»), который бы показывал наличие новостей на главной, а то они ж теперь нифигушеньки не появляются сообщениями на доске d/ (потому что >>/d/3126).
В общем, добавил задачу на сворачивание формы постинга: https://codeberg.org/FBE410/fbe-410/issues/54 Хотя последнее время желающих ковырять движок не видно, похоже.
Год. Цѣлый год каждая новая версия каждого сколько-нибудь популярнаго web-браузера выходит с поддержкою AVIF, но 410чан остаётся без оной.
>>27793 >>27794 Сделано. Счётчик отображается, если набранное наполовину подобралось к ограничению по длине. При превышении ограничения, кнопка отправить не disable'ится, но по клику на неё показывается сообщение о превышении без его отправки на сервер. Стилеспецифичный CSS не делал. Побочка. Надо будет перегенерировать страницы. Поскольку максимальная длина для скрипта передаётся ему через template, их надо будет перегенерировать при любом её изменении в настройках доски. Так что по-хорошему это надо бы не в template-ы, а во что-то наподобие https://a.4cdn.org/boards.json, которое перед отправкой сообщения читать и проверять его длину и другие параметры на соответствие. Но такой JSON, наверное, потом вместе с улучшением фоновой проверки в целом стоит запилить. Запилив, скажем >>27485. Ещё, сейчас отправка идёт через fetch, но если сделать через XMLHttpRequest, можно будет вместо Отправка... отображать Отправлено 78%.
キタ━━━(゚∀゚)━━━!!
>>27873 Судя по всему, не работает и продолжает проверять размер в байтах.
>>27875 Странно, УМВР. Новый posting.class.php точно был скопирован?
Аа, вижу. На 122-ой там забыл strlen на mb_strlen поменять. > exitWithErrorPage(sprintf(_gettext('Sorry, your message is too long. Message length: %d, maximum allowed length: %d'), mb_strlen($_POST['message']), $board_class->board_messagelength)); Но всё равно странно. До exitWithErrorPage оно не должно было дойти: условие в if-е верное.
Судя по всему, проблема в том, что internal_encoding у PHP на сервере, где производилась проверка, стоит не UTF-8. Стало быть, проблема решается либо редактированием php.ini и перезапуском Apache, либо указанием для mb_stlen кодировки: заменить mb_strlen($_POST['message']) в posting.class.php/CheckMessageLength() на mb_strlen($_POST['message'], 'UTF-8').
С этим posting.class.php сейчас должно работать, но по-хорошему стоит посмотреть, что в настройках сервера.
>>27883 Да, это работает, но, судя по всему, оно включает имя файла в длину сообщения.
Так как идея https://codeberg.org/FBE410/fbe-410/issues/41 состояла в том, чтобы сосчитать сѵмволы (а не двухбайтовики UTF-16), то свойство «.length» в джаваскрипте не годится в диапазоне U+010000…U+10FFFF (то есть для многих эмоджи — напримѣръ, сѵмволъ «🕸️» состоит из кодов U+1F578 и U+FE0F), а считать придётся как-нибудь так: const countCharacters = textStr => { var strLen = textStr.length; if( strLen < 1 ) return 0; var total = 0; var curr = 0; var code; while( curr < strLen ){ code = textStr.codePointAt(curr); if( typeof code == 'number' ){ total++; if( code < 0x10000 ){ // Basic Multilingual Plane curr++; } else curr += 2; // UTF-16 surrogate pair } else return total; } return total; };
>>27890 Спасибо, исправил. > cостоит из кодов U+1F578 и U+FE0F Но разве для кодирования '🕸' не достаточно одного UTF-16 символа, пусть и из двух юнитов? https://www.compart.com/en/unicode/U+1F578 Также учёл конвертацию "\n" в "\n\r" браузером при отправке.
Видимо, действительно не достаточно: в >>27891 паутинка отображается только на десктопе, а в >>27890 и на мобилке, тоже.
>>27891 > Также учёл конвертацию «\n» в «\n\r» браузером при отправке. Лучше всего было бы не наращивать счётчик на 2 при каждом переводе строки, а замѣнять «\r\n» на сёрверной стороне единичным «\n» перед подсчётом числа сѵмволовъ. Основание этой мысли вижу в том, что формат «\r\n» свойственен системе Windows, тогда как пользователи системы macOS или Linux (а также Android, FreeBSD и проч.) ничѣмъ двухсѵмвольную оцѣнку перевода строки не заслужили — но тогда и пользователей системы Windows проще перетащить на тот же уровень во имя единообразия.
>>27894 https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart-form-data Формат свойствен стандарту: endl при отправке — это "\r\n". Безотносительно системы. Тоже думал решить эту особенность на сервере, но всё-таки решил на клиенте, чтобы сервер делал проверку по и возвращал ровно то количество UTF-8 символов сообщения, которое туда приходит, без подвохов. Могу сделать проверку с mb_strlen() - substr_count($_POST['message'], "\r\n"), перенос строки при проверке будет считаться за один символ, если Соус того желает. Если нет, то можно обновить lib/javascript/kusaba.js файлом из >>27891, и подсчёт должен работать корректно.
С одной стороны, технически возражение >>27896 совершенно справедливо. С другой стороны, его воплощение противорѣчило бы привычному поведению счётчиков на других имиджбордах. В настоящее время всегда видимый счётчик на Абучане считает перенос строки единичным байтом. Не всегда видимый счётчик на Форчане (становящийся видимым на красном фоне при превышении лимита, равного 2000 байтов на большинстве досок — однако на досках jp/ и vt/ это 5000 байтов, а на досках lit/ и mlp/ и qst/ это 3000 байтов, как нам содержимое файла https://a.4cdn.org/boards.json подсказывает) также считает перенос строки единичным байтом. На всякий случай тотчас же поясню, что насчёт этих двух имиджбордовых счётчиков я пишу о байтах (а не о сѵмволахъ) по той причине, что тот и другой имиджборд наращивает счётчик на двойку для сѵмвола «ы» (слѣдовательно, считает его как байты 0xD1 0x8B кодировки UTF-8) и на семёрку для сѵмвола «🕸️» (слѣдовательно, считает его как байты 0xF0 0x9F 0x95 0xB8 0xEF 0xB8 0x8F кодировки UTF-8). Поэтому возможны контраргументы такого рода: — По отношению к другим имиджбордам мы будем «неэкономнѣе» считать (и хранить?) переносы строк, однако зато не «наказывать» многобайтовость сѵмволовъ, эффект от чего будет гораздо больше для подсчёта, так что чего уж теперь придираться к мелочи. — Если двухсѵмвольный подсчёт переноса строки непривычен при сравнении с другими имиджбордами, то ужъ тѣмъ болѣе непривычен небайтовый подсчёт сѵмволовъ, так что чего уж теперь стремиться к привычности. — Другие имиджборды для нас ни в чём не указка, к удобству их завсегдатаев мы не стремимся и не привѣчаемъ их. Насколько эти контраргументы убедительны, умѣстно ли руководиться ими?
Для оцѣнки распространённости явления я дополнительно сообщаю, что и Twitter (нынѣ 𝕏), и Telegram, и даже порносайт https://pornolab.net/ наращивают свои счётчики на единицу при подсчёте перехода на новую строку.
>>27896 >если Соус того желает Меня больше вот эта проблема интересует сейчас: >>27884
>>27900 Так там не в имени файла дело же оказалось.
>>27901 Да? Я не могу попробовать новую версию скрипта пока, но вы тут пишете про какие-то четырёхбайтовые эмодзи и переносы, в то время как в >>27884 оно при проверке считает имя файла в суммарную длину сообщения (и без файла даёт запостить). Как это связано, лол?
Пока не забыл, ещё вопросы насчёт функции «setup_message_length_indicators» в коде >>27891: ➊ Какой смысл добавлять к счётчику нули слѣва? ➋ Почему счётчик должен быть трёхразрядным (напримѣръ, «001/1000»), если считает до тыщщи, но четырёхразрядным (напримѣръ, «0001/8192»), когда считает до всякого другого четырёхразрядного числа? Не проще ли и не короче ли было бы вмѣсто «Math.ceil(Math.log10(max_message_length))» использовать выражение «('' + max_message_length).length», результат которого не создаёт этого нюанса? А не то сбивает с толку намёком на то, что считает только до 999, а не до тыщщи — однако условие «c_len > max_message_length» в функции «check_post» говорит нам, что до max_message_length всё же можно досчитывать. ➌ Точно ли нужно создавать и наполнять свойство «msg_area.last_msg_len» для того, чтобы не вызывать присваивание «indicator.textContent = ''» лишний раз? (Сильно ли тормозит?)
>>27902 Длина строки «[Doremi].Chuunibyou.demo.Koi.ga.Shitai!.Movie.Take.On.Me.[1920x1080].[Blu-ray].[2BB3C549].mkv_snapshot_00.25.07_[2018.07.27_23.17.43].jpg» равна 137 сѵмволовъ и оттого подозрительно не похожа на разницу между величинами 8257 и 8192 наверху скриншота >>27884, которая равна 65.
Зато разница >>27905 превосходно равняется количеству концов строк в тексте, состоящем из 66 строк (между которыми 65 концов, раздѣляющихъ строки между собою) — а вѣдь прямо сейчас в вики-коде https://noobtype.ru/w/?title=Ычан&action=edit§ion=1 (ещё ни разу не перемѣнявшемся въ нынѣшнемъ году) можно насчитать как раз 64 строки, если первою считать заголовок «== История ==», а послѣднею — строку «Среди нововведений 2009 года можно назвать начало сотрудничества с другими имиджбордами по добавлению их досок во фрейм «Ычана».», которая видна на скриншоте >>>>27884 одной из послѣднихъ и позволяет нам угадывать источник используемой копипасты. И за нею (дополняя до 66 строк) видны ещё строки «2010—2011» и «рпопопо…». Вот поэтому-то мы и разсуждаемъ о том, как правильно считать сѵмвол (или два сѵмвола) конца строки.
>>27906 > gettext('Sorry, your message is too long Встречается только в posting.class.php и только единожды — в CheckMessageLength. > CheckMessageLength( Вызов этой функции встречается только в board.php и тоже только один раз. Можно было бы предположить, что где-то до выполнения CheckMessageLength при наличии файла выполняется $_POST['message'] = str_replace("\r\n", "\n", $_POST['message'])), но у меня такого нет: есть файл, нет файла, а сервер возвращает ту же длину. Так что… >>27902 > Как это связано, лол? Не знаю. > (и без файла даёт запостить) Can not reproduce. Воспроизводился неправильный подсчёт клиентом UTF-8 длины would-be отправляемого сообщения, что в новой версии kusaba.js и починил.
>>27903 ➊ Так в >>27794 нарисовано было; ➋ Починил; ➌ Не нужно. Последил за htop, когда setup_message_length_indicators закоментированно и когда нет, на 100000 символов разница в нагрузке особо не заметна. С другой стороны, лишний раз textContent менять не нужно, either, так что оставил.
>>27908 > Так в >>27794 нарисовано было Это соображение совершенно справедливо. (Впрочем, если им послѣдовательно руководиться, то тогда и счётчику слѣдовало бы считать от 0000, а не от полумаксимума.) Дополнительно сообщаю о двух возможностях упрощения: ① запись «'/' + String(max_message_length)» можно упростить до «'/' + max_message_length», ② запись «msg_area.oninput = (e) => {» можно упростить до «msg_area.oninput = () => {».
В общем, по главной предлагаю пока сделать как на картинке. Если потом нарешаем какие-то декоративные штуки прикрутить, можно будет уже отдельно обсуждать. Ещё надо добавить <meta name="viewport" content="width=device-width,initial-scale=1"> на news.php и её подстраницы, чтобы мобилочная ЦСС работала.
Господин Соусов выложил предложение >>27913, или админ сайта, или анонимный разработчик-помощник? — что-то никак не соображу. Вот что значит отказ не от одного только надёвывания шапок, но и от употребления аватар.
>>27923 Внёс упоминание в задачу на трекере.
Реквестирую мёрдж https://codeberg.org/FBE410/fbe-410/pulls/56 тогда.
Я так понимаю, что у нас движок кроме картинок и видосов файлы на соответствие не проверяет? А то вон «4чан» якобы поломали через ПДФ, которые на самом деле не ПДФ. В связи с этим я пока отключил в /dev/ загрузку архивов и прочих файлов, кроме картинок и видео. Вопрос, соответственно, действительно ли это уязвимость для нас, ну и давайте обсудим, можно ли прикрутить проверки к файлам (и тогда нужен список форматов, которые потенциально нужны кому-то тут). Также замечу, что я >>27939 видел, но работа по движку пока встала с нашей стороны.
>>27943 > Вопрос, соответственно, действительно ли это уязвимость для нас Хотѣлось бы максимум подробностей (и, в идеале, гиперссылку на первоисточник) утверждения о том, что 4чан «якобы поломали через ПДФ, которые на самом деле не ПДФ». Тогда его разбор может сдѣлаться предметным подобно тому, как прежде в случае формата WebP мы разбирали (я надѣюсь) не ѳэзисъ «WebP уязвим, избѣгайте его», а конкретную уязвимость BLASTPASS в библиотеке libwebp, насчёт которой можно буквально посмотрѣть и самостоятельно оцѣнить непродуманные правки исходнаго кода: и насколько давно появилися, и когда были поправлены, и какой эффект имѣли. Если ж подробностей не будет, то тогда семь общих соображений: ① Давно и достаточно хорошо извѣстны файлы, являющіеся своего рода «кентаврами», то есть способные быть прочитанными (в зависимости от их обработчика — и, в частности, в зависимости от придаваемого им расширения имени файла) как файлы двух разных форматов. (И не только быть прочитанными, но и имѣть в каждом из этих форматов нѣкоторое содержательное содержимое.) Классический для имиджборд примѣръ — это RARJPEG, то есть приклеивание к хвосту JPEG-картинки нѣкотораго RAR-архива. ② Обычными примѣненіями таких «кентавров» является, во-первых, принуждение нѣкоторой имиджборды к хостингу небольших файлов, без такого принуждения не принимаемых ею (но которые можно засунуть в файл другого формата и при выкладывании сопроводить его общедоступною инструкциею по распаковке), а во-вторых, своего рода стеганография (это когда инструкция по распаковке не общедоступна, но небольшому кругу частных лиц сообщают, что к хвосту такой-то картинки на таком-то сайте присоединён был желаемый файл). У первого из таких примѣненій возможна альтернатива, которая не потребует такого «кентавра» (просто сохранять байты файла по три штуки в качестве RGB-значений пикселов PNG — это даже будет своего рода «архивациею» по своей силе сжатия, потому что сжатие в PNG работает на основе классического алгоритма DEFLATE), но зато создаёт явный визуальный «мусор» в картинке. (Способы, https://github.com/mosegontar/underbyte подобные, уменьшают замѣтность «мусора», но уменьшают и величину файла, способного быть засунутым в PNG.) ③ Примѣненіе таких «кентавров» для взлома сайтов требует того, чтобы «кентавр» оказался загруженным в такую область файловой системы сайта, откуда можно запускать на исполнение код PHP (на стороне сёрвера) или код JavaScript (на стороне читателя сайта, когда читатель — залогиненный админ, у которого хочется стырить пароли). При этом движки имиджборд (а также форумов, вики и проч.) проектируются обыкновенно таким образом (и инструктируют настраивать сайт таким образом), чтобы запускать PHP из файла, только что выложенного пользователем, было нельзя. (Как правило, запуск файлов PHP разрѣшается из одного подкаталога, а файлы от пользователей принимаются в другой подкаталог, который сёрвер не перепутает с первым.) Также и HTML-тэг <script src="загруженная_картинка"> создать не получится. ④ Вроде бы исключением могут считаться скрипты в PDF, которые реально запускаются на исполнение. Однако в большинстве современных браузеров просмотр PDF совершается посредством движка PDF.js, запускаемого изолированно (то есть скрипты PDF не должны — в теории, по крайней мѣрѣ — управлять браузером от имени админа сайта, даже открывшего этот PDF на том сайте, на котором залогинился). Уязвимость этого движка, позволяющая выбраться из изоляции, была бы серьёзною новостью, а новостей таких вроде бы не появлялося. Напротив, в новости https://xakep.ru/2025/04/16/4chan-hacked/ и https://bsky.app/profile/zappit.bsky.social/post/3lmudrfovzc26 процитированы слухи (по-видимому, изъ нѣкоторой микроблогозаписи в Bluesky, в настоящее время сдѣланной подзамочною) про использование уязвимости слишком старой версии движка PHP (2016 г.) для взлома 4чана, что предполагает атаку совершившеюся не на клиентской, а на сёрверной стороне. ⑤ Ещё одним таким форматом файла, который вроде бы картинка, но в нём браузеры запускают джаваскрипты при его открытии, является SVG. Разрѣшать его загрузку на имиджборды поэтому опасно. ⑥ В обыкновенных файлах картинок (когда онѣ не SVG) браузеры не запускают джаваскрипты, даже если картинку эту открыть не помѣщённою в качестве иллюстрации на web-странице, а ѿдѣльно перейти по гиперссылке к такой картинке. То есть для атаки потребуется ясно приказать браузеру использовать этот файл не как иллюстрацию, а как скрипт (то есть сформировать HTML-тэг <script src="загруженная_картинка"> на странице), что пользователь на имиджборде обыкновенно сдѣлать не может, потому что запрещено. В этом смысле равно безопасны и картинки условно «старых» форматов (GIF, JPEG, PNG), и условно «новых» (WebP и AVIF, а в будущем — также JPEG XL). ⑦ Предубеждение «новый формат опаснѣе» (вроде бы подкрѣпляемое обнаружением уязвимости BLASTPASS в WebP) не может считаться вѣрнымъ по отношению к возможности создания файлов-«кентавров». Как раз наоборот: самый старый из используемых форматов иллюстраций (а именно GIF) в силу своего возраста лучше всего изучен насчёт приёмов, обеспечивающих засовывание туда джаваскриптов, не нарушающее ни внѣшній видъ картинки в GIF, ни работоспособность джаваскриптов. (Примѣромъ может служить утилита https://github.com/pranavms13/gifjs или, напримѣръ, статья https://habr.com/ru/companies/vdsina/articles/518162/ на Хабрахабре.)
>>27944 https://iichan.hk/b/res/5370171.html#5370232
Если мы сейчас обсуждаем выложенный по адресу https://iichan.hk/b/res/5370171.html#5370232 (без указания на первоисточник) файл PNG (который я прилагаю здѣсь сконвертированным в формат WebP, но который исходно был JPEG, судя по артефактам вокруг букв), то в нём утверждается, что 4чан был взломан на сёрверной стороне через уязвимость старой версии Ghostscript (2012 г.) благодаря тому, что ею создавалися миниатюры файлов PDF (причём любых — в том числе и содержащих не PDF, а PostScript). Если это правда, то тогда можно быть близко к 100% увѣреннымъ в том, что на 410чанѣ такой уязвимости не может случиться, потому что у нас в коде FBE создаются миниатюры только для картинок (в число которых вроде как не входят файлы PDF, если здравый смысл никому не измѣнилъ при настройке движка на 410чанѣ) да ещё и для видеофайлов, тогда как для остальных файлов вмѣсто миниатюр показывается заранѣе заготовленный значок, сѵмволизирующий конкретный тип файла их. Провѣрка картинок на картиночность совершается в GD, а GD не может читать PDF и оттого не признает картинкою. Провѣрка видеофайлов на видеофайловость совершается в FFprobe, а FFprobe не будет же (я надѣюсь) запускать Ghostscript, если кто-нибудь подгонит PDF, переимѣнованный в MP4 или в WebM. (Вроде бы FFprobe просто-напросто нельзя и собрать с Ghostscript в качестве движка для чтения PDF.)
>>27946 Вопрос в том, что если файл (кроме картинок и видео) вообще не проверяется на соответствие формату, то на сервер под видом такого файла можно загрузить что угодно и выполнить что угодно.
>>27947 >загрузить Да. >выполнить Нет. Покуда Апач не настроен выполнять всё подряд ИЛИ файл каким-то образом смогут переименовать после загрузки ИЛИ уже есть доступ хотя бы с правами сервера.