Opened 5 months ago

Closed 5 months ago

Last modified 5 months ago

#649 closed улучшение (не будем делать)

Инвентаризация. Защита от непечатных символов.

Reported by: san Owned by: alx
Priority: средний Milestone: 1 очередь
Component: web-интерфейс (sw) Keywords:
Cc:

Description

Некоторые платы в переменной .250 в качестве серийного номера возвращают непечатные символы, например 0x00(это следствие ошибочной записи серийного номера на производстве), при наличии таких плат в блоке на вкладке инвентаризация не отображается ничего.
Предлагаю добавить "защиту" от неожиданных непечатных символов в серийном номере платы, так чтобы вкладка отображалась и серийный номер проблемной платы отображался исключая непечатные символы.

Change History (5)

in reply to:  description comment:1 by alx, 5 months ago

Resolution: не будем делать
Status: newclosed

Replying to san:

Некоторые платы в переменной .250 в качестве серийного номера возвращают непечатные символы, например 0x00(это следствие ошибочной записи серийного номера на производстве), при наличии таких плат в блоке на вкладке инвентаризация не отображается ничего.

Внесу небольшую поправку. Насколько я понимаю, "непечатные" символы - это символы с кодами от 0 до 31, а также 127. Этим символам не соответствует никаких глифов в шрифтах, и они используются как управляющие. Однако наличие в серийном номере таких символов не приводит к тому, что на странице "Инвентаризация" веб-интерфейса ничего не отображается, как это написано в описании тикета.

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

Для отображения таблицы инвентаризации браузер отправляет серверу в плате SW-01 запрос переменных .250.0 всех плат, примерно такой:

{ "cmd":"snmpget", "varlist":[".4.1.250.0", ".4.2.250.0", ".4.3.250.0"] }

Здесь для упрощения запрашивается только три переменные, в реальности запрашивается двадцать одна.

Получив такой запрос, сервер запрашивает у плат указанные переменные и помещает их значения в приблизительно такой ответ:

{
   "cmd":"snmpget",
   "varlist": {
       ".4.1.250.0": {
           "oid": ".4.1.250.0",
           "status": "OK",
           "value": "F03265"
       }, 
       ".4.2.250.0": {
           "oid": ".4.2.250.0",
           "status": "OK",
           "value": "E8736"
       }, 
       ".4.3.250.0": {
           "oid": ".4.3.250.0",
           "status": "OK",
           "value": "Lauda-Dabuda"
       }, 
   }

Этот ответ сервера закодирован в кодировке UTF-8.

Получив такой ответ как последовательность байтов, браузер декодирует его, в результате чего получает текст. Далее полученный текст парсится (посимвольно) и преобразуется в структуру данных (объект). Значения из полученного объекта отображаются в таблица на вкладке "Инвентаризация".

В случае, который мы обсуждали устно, возникла проблема из-за того, что значение переменной одной из плат содержало нулевой байт (не символ!). Таким образом, значение переменной вообще не являлось корректной строкой текста (в кодировке UTF-8 байт 0 не используется). Далее, когда сервер поместил полученное из платы значение в текст ответа, весь ответ перестал быть текстом (если часть сообщения некорректно закодирована, то и все сообщение в целом некорректно закодировано). Как результат, браузер, получив такой ответ, споткнулся уже на первом этапе - он не смог декодировать полученное сообщение в текст. До посимвольного разбора текста дело просто не дошло!

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

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

И, наконец, не могу удержаться от вопроса, который у меня возник сразу после прочтения тикета: а что, добиться того, чтобы потребителям отправлялись платы без ошибок в серийном номере - никак невозможно? :) ИМХО применять подобную защиту - это значит расписаться в том, что да, компания АДС не в состоянии корректно запрограммировать шесть символов текста... :(

comment:2 by san, 5 months ago

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

Я надеюсь что это возможно)

До обнаружения этой ошибки на производстве какое-то количество плат с ошибкой в серийном номере было отправлено.

значение переменной одной из плат содержало нулевой байт (не символ!)

Строго говоря, по протоколу, нулевой байт имеет право содержаться в одном из байтов строки

in reply to:  2 ; comment:3 by alx, 5 months ago

Replying to san:

Строго говоря, по протоколу, нулевой байт имеет право содержаться в одном из байтов строки

Согласен, здесь я ошибся. Символ NUL (имеющий код 0) в UTF-8 все-таки кодируется байтом 0 (но ни в каких других последовательностях байт 0 появляться не может). Могу предположить, что в упомянутом мной случае нулевой байт присутствовал в какой-то комбинации (а не кодировал символ NUL). А, возможно, это был вообще не байт 0, а какой-то другой (например ff), не готов положиться на свою память...

Кстати, при кодировании JSON-объектов управляющие символы у меня заменяются комбинациями типа \t, \n. Это было сделано из-за того, что когда в значении встречался перевод строки, firefox это не мог нормально обрабатывать. Я не знаю почему... Символ NUL, вероятно, не заменяется, так как я никак не ожидал, что он может встретиться на практике...

Last edited 5 months ago by alx (previous) (diff)

in reply to:  3 comment:4 by alx, 5 months ago

Replying to alx:

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

В разделе 2.5 RFC:4627 сказано:

All Unicode characters may be placed within the
quotation marks except for the characters that must be escaped:
quotation mark, reverse solidus, and the control characters (U+0000
through U+001F).

Видимо поэтому... :)

comment:5 by alx, 5 months ago

Реализовал экранирование всех оставшихся "непечатных" символов (см. #650). Теперь символ NUL не приводит к проблеме.

Note: See TracTickets for help on using tickets.