Pull to refresh

Comments 65

В Австралии настолько ничего не происходит что из обычной ошибки форматирования текста создали целое расследование.

Там наверное вообще фильтрации входных данных нет. Хотя да, это же просто какое-то медицинское приложение.

Компьютеры хранят всё в байтах. Каждая буква текста этой статьи представлена в компьютере в виде числа. Например, латинская «A» — это 65, и так далее, вплоть до 127. Этого места достаточно для хранения всех букв, символов и чисел английского языка, и остаётся ещё немного свободных позиций. Числа от 31 и ниже не нужны для отображаемых на экране символов. При проектировании этой системы какие-то учёные мужи решили поместить в позиции до 31 «управляющие символы». Это символы, невидимые для читающего текст человека. Они сообщают компьютеру, как размещать идущий после них текст.

Уровень статей для Хабра 2025 года :(

Увы. А Волга впадает в Каспийское море... (хотя, сейчас это уже далеко не для всех очевидный факт).

(хотя, сейчас это уже далеко не для всех очевидный факт).

Тот факт, что запятая здесь не нужна — это уже давно далеко не для всех очевидный факт...

А Волга впадает в Каспийское море

докуда доедет - туда и впадает, если вовремя её не затормозить =)

видел фотку как ока впала в волгу. точнее сказать упала. с путепровода)

Ну я, например, просто пропустил эти несколько абзацев, подумав: "возможно, кому-то, действительно, это надо объяснять" и всё) - кстати, конкретно код 02, естественно, я не помнил, в отличие от многих других

Так это ж наверное перевод. Я тоже сначала триггернулся, но потом подумал, что из оригинала слов не выкинешь.

Да, метка "перевод" стоит на статье.

Это перевод. Считаете, нужно было решить, что на хабре все умеют в ASCII, и выкинуть это?

Не Австралия, Дальний Восток РФ, г. Хабаровск, Судостроительный техникум, год, примерно 1998.

Привезли меня в технику починить странность - неизвестная мне самопальная программа под MS-DOS.
Работала нормально, но стала показывать русские символы кракозябрами.
Программу уже исследует другой спец, безуспешно.

Чем запомнился именно этот случай?
Спец сидит за компом, я прошу разрешения запустить программу - русские буквы нормально.
Запускает тот мужик - кракозябры.
И так пару раз.

Уже не помню нюансов, сделал в config.sys запуск драйвера клавиатуры с более жёсткими опциями и программа перестала баловаться.

Что объединяет историю топикстартера и мою - далеко от Москвы, про символы.

неизвестная мне самопальная программа под MS-DOS

Ох уж эти мамкины программисты.

А чем отличается "самопальная" программа от не-самопальной?

Иногда надо было ещё и локаль поставить... Непомню, уже как опцию зовут...

MS DOS 6.22

config.sys
device=C:\dos\display.sys con=(ega,,1)
country=007,866,C:\dos\country.sys


autoexec.bat
mode con codepage prepare=((866) c:\dos\ega3.cpi)
mode con codepage select=866
keyb ru,,C:\dos\keybrd3.sys


Понравилось. Захватывающе читающийся Bug Mystery.
Автору - респект за проявленные терпение, настойчивость и ответственность (за последнее - особенно). 99 % на его месте просто бы забили на проблему, ибо, во-первых, баг не такой частый, во-вторых - есть рабочий SQL-костыль. А автор всерьёз задумался, не приведёт ли использование этого костыля к другим проблемам (с другой стороны, если на решение этого вопроса было потрачено столько времени и сил - там других проблем вообще почти не было?).

время от времени я диагностирую в продакшене баг, возникающий из-за содержащихся в PMS недопустимых данных, которые невозможно ввести, например, лекарство без названия или вычисление индекса массы тела без веса.

Не совсем понятно - там присутствуют недопустимые данные или их невозможно ввести (т. е. их там нет). Если присутствуют - то как насчёт data entry control? ИМТ без веса, кстати, просто выдаст 0, а лекарство без названия - NULL, безо всяких там 0x2.

Автор очень странный. Первым делом делается санитайзинг или эскейпинг пользовательского ввода (это всё равно жёсткая необходимость и это уже решает проблему), а потом можно удовлетворять своё любопытство, выясняя, откуда там 0x02.

Не удивлюсь, если они там отфильтровали только 0x02, а если юзер скопипастит туда 0x03 – опять что-то навернётся. А то и вообще придёт маленький Бобби Тэйблс (xkcd#327).

Автор не программист, и тем более в такой критичной области у него нет прав что-то даже просто кодить, а тем более вводить новую политику какого-то санитайзинга. Он сделал, что мог.

Есть ненулевые шансы, что санитайзинг был предложен как решение его тикета, но это уже надо иметь инсайдера, чтобы узнать.

Одна из наиболее частых причин, по которой 0x02 или другие непечатаемые символы могут попасть в текстовый файл, — это копирование текста из программ с расширенным форматированием (например, Microsoft Word) и вставка его в обычный текстовый редактор или поле ввода. При таком копировании могут "захватываться" скрытые символы форматирования, которые затем отображаются как 0x02 или другие управляющие символы, если их кодировка совпадает.

Крупная компания, 2012 год. У одного инженера возникла проблема - внезапно его учетная запись постоянно блокировалась в Active Directory. Её разблокировали, как она тут же опять блокировалась.

Сперва думали кто-то ломает, нет, активности извне. Стали слушать трафик внутри - нормально все, нет активности. Уже идеи закончились.

Ответ нашелся весьма не ожиданно: этот инженер однажды работал за столом (там стоит системный блок), потом он переехал в другой кабинет, а потом сисадмин забрал монитор. Клавиатура осталась. Потом, на этот стол стали складывать бумаги, стопка росла, потом кто-то ее уронил и одна папка попала на кнопку Enter и придавила её. А когда включили монитор на экране было вбито имя этого инженера.
Короче комп беспрерывно пытался логиниться с пустым паролем. Естественно AD блокировала аккаунт.

Ржали всем отделом, потому что на расследование потратили 2 полных дня.

В уголке задумчивао курит бухгалтер с выдающимся бюстом. ...

В моём случае - с выдающимся пузом.

При наборе текста периодически начинали вводиться ряды пробелов. Причину найти не удавалось. Баг возникал рандомно, то текст вводится нормально, то поехали пробелы.

В очередной раз, когда начали ехать пробелы, я замер и попытался понять, что сейчас стриггерило баг. Взгляд упал вниз... Причиной оказалось сочетание стола, имевшего полочку для клавиатуры, низкопрофильной клавиатуры и моего отросшего пуза. Во время напряжённых срачей в интернете я слегка подаюсь вперед и краешек пуза ложится на пробел. Этим и объяснялась рандомность: когда я печатаю спокойно, то сижу ровно.

Это абсолютно реальная история из жизни мэрии Москвы. Я тогда там в поддержке работал. И мы всем отделом ходили к тетке разбираться, почему база у нее не работает. Приходим - работает, уходим - не работает. И только один сотрудник понял, в чем дело…

Было аниме про это

Возможно. Но это было в реальности, ник у товарища, открывшего причину - Шахтёр. И тетка была больше похожа на фрёкен Бок, а не на няшную девицу…

У меня такой случай в реальности был. Да, в бухгалтерии.

Вроде стандартные баги. Я за всё время работы подобного видел много. Например, по теме автора могу сказать, что существует два символа тире. Длинное тире и короткое. Длинное поддерживается далеко не всеми программами. Так же проблемы могут возникать из-за разных кодировок.

Это ещё автор с кавычками не встречался, которых лично я 5 видов по памяти назвать смогу и многие из них в подобных случаях без должных валидаций приводят к подобным ошибкам.

Подозреваю, что символ 0х2, скорее всего, подставляется в системе с которой работал автор для любого нерабочего символа, поэтому всегда заменять на тире, если честно, не совсем верное решение. Я бы узнал, какую кодировку использует программа, взял десяток другой спец символов и проверил какие из них ещё вызывают 0х2, а потом набросал бы валидатор для формы ввода, что сразу бы врачу показывал проблемные символы.

В общем, замена на 0х2 на пустоту или пробел, как предлагали разработчики, как по мне более правильный хотфикс, но это не решает проблему до конца.

Латинские "C/c" и русские "С/с" - вообще классика.

МЕЯ ВИДО? (c)

(Если кто не застал – это прикол времён Фидонета, когда буква 'Н' сжиралась, если я не путаю, GoldEdом. Ещё буква 'р' была проклята – в результате зачастую даже раскладку русификатора делали так, что гни заменялись на латинские 'H' и 'p' соответственно... Думаю, если сейчас погуглить русские слова с такой заменой – найдётся много текстов с артефактами тех времён).

АСТРОЙ БУКВУ ЛАМЕР!

огда буква 'Н' сжиралась, если я не путаю, GoldEdом.

ЕМНИП при тоссинге.

Буква р даже в каких-то старых версиях Norton Commander не вводилась. Не знаю, почему именно с ней были проблемы.

А в более новых версиях Norton Commander в просмотровщике не показывались буквы «оп», поэтому в нём было интересно читайть прайс‑листы, в которых упоминались «европейские цены».

два символа тире. Длинное тире и короткое. Длинное поддерживается далеко не всеми программами.

о да! Приколы начинаются когда из какого-нибудь экселя-ворда начинают копировать строки с такими тире.... Причем обычно такое тире не поддерживают всякие финансовые проги...

А если на полный штык копать, то есть минус, дефис, короткое тире (полутире) и длинное тире (просто тире).

Даже у казалось бы простейшего символа - пробела - есть много видов: обычный, неразрывный, и прочие различной ширины и назначения (а память еще подсказывает полузабытый типографское термин "шпация")

Я бы вайт-лист сделал бы для символов. Все равно врачи не будут Юникод смайлики в свои эпилоги вставлять

+Отдельный список маппинга/авто замены для миллионов видов тире/кавычек/пробелов/и и.п.

Например, по теме автора могу сказать, что существует два символа тире. Длинное тире и короткое. Длинное поддерживается далеко не всеми программами.

Ха-ха-ха. Тире есть длинное и среднее (оно же короткое, вроде бы), а ещё дефис. И еще несколько менее популярных разновидностей. Но по части поддержки они все в одной лодке, потому что на клавиатуре в стандартной раскладке их вообще нет - ни тире, ни даже дефиса. Только минус.

ни тире, ни даже дефиса. Только минус.

Согласно последнему постановлению ~ВЦСПС~, немного не так:

002D;HYPHEN-MINUS;Pd;0;ES;;;;;N;;;;;

то есть он одновременно и минус, и дефис.

По отдельности они как раз есть в юникоде.

 Первым делом делается санитайзинг или эскейпинг пользовательского ввода (это всё равно жёсткая необходимость и это уже решает проблему)

Не очень знаю, что такое санитайзинг и эскейпинг, но подозреваю, что речь идет о проверке пользовательского ввода. На мой взгляд, удобнее применять принудительное перекодирование символов перед помещением данных в базу или преобразованием в формат для обмена

FUNCTION xml_tran
PARAMETER m.S
* удаление ненужных символов из строки
  PRIVATE T
  T = chrtran(S, chr(0), ' ')

  T = strtran(T, '&', '&')
  T = strtran(T, '<', '&lt;')
  T = strtran(T, '>', '&gt;')
  T = strtran(T, "'", '&apos;')
  T = strtran(T, '"', '&quot;')
  T = strtran(T, '№', '&#8470;')

  T = strtran(T, CHR(0x11), '&quot;')
  T = strtran(T, CHR(0x12), '&quot;')
  
RETURN m.T

Санитайзинг – чистка от запрещённого (удалением или заменой, например 0x02 удалить или заменить на тире, как в статье). Эскейпинг – обратимая замена запрещённого (как в вашем примере для символов пунктуации).

В общем, всё вы знаете, только термины почему-то мимо прошли :-)

В общем, всё вы знаете, только термины почему-то мимо прошли

Конечно, я начинал программировать в седой древности, когда таких терминов не существовало

Эскейпинг – обратимая замена запрещённого (как в вашем примере для символов пунктуации)

Если быть совсем уж точным, то в моем примере замена не обратимая, поскольку открывающие и закрывающие кавычки, а также просто двойные кавычки заменяются на один и тот же символ XML

Вот не надо делать XML-кодирование перед помещением в базу! Потому что прочитать данные может понадобиться и не через XML, а в другом формате - и тогда их придётся декодировать обратно.

Особенно бесполезным является кодирование символа номера. Потому что если выходная кодировка поддерживает Юникод - то этот символ можно оставить как есть. А если выходная кодировка Юникод не поддерживает - то этот символ является далеко не единственным "проблемным". Ну и выходная кодировка в общем случае неизвестна пока вы не начинаете формировать, собственно, выходной файл.

Если внимательно прочитать мой комментарий, то в нем написано

удобнее применять принудительное перекодирование символов перед помещением данных в базу или преобразованием в формат для обмена

Приведенная функция использовалась именно для создания XML файла, который посылался в систему ЭДО. Без этого перекодирования система просто не принимала файл - в ней не было предусмотрено использование, например, открывающих или закрывающих кавычек

А если выходная кодировка Юникод не поддерживает - то этот символ является далеко не единственным "проблемным"

В данном случае я не занимался созданием универсальной системы. Оно преспокойно себе работало, но иногда XML файл отвергался. В этом случае нужно было просто найти символ, вызвавший проблему и добавить его в функцию перекодирования. Такой подход несколько отличается от описанного в статье, когда нужно было каждый раз ВРУЧНУЮ запускать скрипт и заменять один известный символ

Еще чуть-чуть воды добавить, и можно как книгу издать.
Тем не менее, причина возникновения НЕ была обнаружена. А, вероятно, она всего лишь в замене кодов символов при формировании PDF, обычно ПО использует это для font subsetting (когда глифы для букв шрифта включаются в PDF только если буква встречается в тексте), а тут могло быть следствием косяков особенностей библиотеки

Я тогда занимался софтом для кассовых компьютеров. И вот создают мне тикет, что при закрытии большого чека в сотню позиций вываливается ошибка драйвера такая-то. Проверяю - все ок. Выясняю модель кассы, беру на складе, проверяю - все ок. Иду к тестеру, беру его кассу (точно такую же) - проверяю всё ок. А у него воспроизводится прям на моих глазах. Меняли провода - не помогает.

Уже не помню как до этого дошли - но в какой-то момент воткнули блок питания кассы в другую розетку - нет ошибки! Оказалось что на розетке без заземления баг проявляется, на розетке с заземлением - нет.

Что-то там не так было в схеме блока питания, и при печати большого чека и незаземленной розетке из-за большой потребляемой мощности (а термоголовка если не ошибаюсь потребляет ватт 40-50) что-то куда-то пробивало и процессор кассы сбоил.

Примечательно что на небольших чеках баг не проявлялся.

Два варианта

  1. Может розетки без заземления были дальше от щита и подведены кабелем поменьше сечением? Тогда все проще - начиналась печать, а не очень хороший БП просаживал питание, ловил шумы, и касса спотыкалась.

  2. Или из-за разных БП принтера и компа, без заземления и при потреблении на них появлялась разница потенциалов, замыкалась через коннектор, и летела прямиком в мозги компа

Может розетки без заземления были дальше от щита и подведены кабелем поменьше сечением?

Не, прям в одном "пилоте". Там были розетки с заземлением и без.

> Или из-за разных БП принтера и компа
RS-232 по-идее должен эту проблему решать. Проявлялось только при длинном чеке, то есть термоголовка "съедала" много мощности и (сейчас будет дилетантская мысль) - не хватало емкости стабилизирующих конденсаторов для поддержания нужных уровней напряжения на процессоре. Какую роль в этом играло защитное заземление - мне не ясно, скорее всего какой-то "баг" в схеме.
Впрочем, эту проблему я сдал в отдел разработки железа и дальше ее судьба мне неизвестна.

Ко мне тоже однажды обратились с багом - программа не запускается, жалуется на какую-то ерунду, хотя по коду всё чисто. Заняло не так много времени, но результат был неожиданным - японские(!) пробелы.

Да. У них даже пробелы свои есть (широкие). И вот один из таких пробелов, видимо, был в комментарии (естественно, написанном на японском). Коммент удалили, а пробел - не заметили. Вот компилятор за него и цеплялся.

В наши дни во всех известных мне IDE такое подчеркивается, так что, видимо, не только я сталкивался.

Ну в том же ворде есть просто пробел (anykey при наборе) и неразрывный пробел (ctrl+shift+anykey).

Первый в жизни Ассемблер (программа-транслятор, а не язык, который пишется с прописной буквы). Так вот, нашли-таки транслятор (а раньше писали в машинных кодах) - кажется, для ДВК, но это не точно. И в некоторых строках с комментариями он выдавал ошибку именно из-за комментария. Но удаление коммента не помогало. Ну, анализ и т.п. А тогда русских раскладок клавиатуры было много. На наших клавах были к тому же две клавише: РУС и ЛАТ - для перехода туда и обратно. Оказалось, что они шлют в текст символы (уж не помню коды - что-то вроде 16 и 17). Коммент на русском языке приводил иногда к тому, что символ ЛАТ уже был в начале команды на следующей строке. Всё просто. Но с тех пор уже полвека не пишу комменты на русском.

Ещё распространенный случай при копипасте забыл какой то utf вставляется, если с некоторых web страниц копировать, ссылку не copy link, а select-copy у нас это было в тикетной системе и операторы постоянно его копировали в разные места где им надо было вставить ссылку. Ещё помню ве6эндор тоц тикет системы не хотел фиксить свой вывод, мотивируя какой то неведомрй семантикой чтоли.

Просто интересно, вот мой коммент -2, ниже ровно такой же +5 ;) поставьте ещё минусов чтоли.

Однажды был интересный баг: на компе тестировщика не работал поиск товара по отсканированному ШК, а на компах разработчиков (как обычно) всё работало отлично. Баг проявлялся только на сканере с эмуляцией клавиатурного ввода, что дало первую зацепку. Не помню уже деталей расследования, но виновником оказалась установленная на компе тестировщика популярная в 00х программа PuntoSwitcher, которая умела замечать текст, введенный не в той раскладке, автоматически его удалять и заменять корректным.

Это вы ещё не видели MSB и LSB, а также десяток видов букв "с" или "е" в юникоде - или разные виды m-dash и т.п

Sign up to leave a comment.

Information

Website
ruvds.com
Registered
Founded
Employees
11–30 employees
Location
Россия
Representative
ruvds