Обновить
7

Пользователь

3
Подписчики
Отправить сообщение
Полтора — это половина трех, а не половина второго; это количественное числительное, а не порядковое.
Вам нужно описывать операцию среднего взвешенного. Чтобы библиотека (условно) через unsafe получала скаляры, делала математику и возвращала усредненную температуру. Складывать температуру нельзя, можно усреднять. Т.е. можно складывать только при условии последующего деления, например.
На слайсах невозможно построить эффективный с точки зрения процессорного времени парсинг, по крайней мере кастомный

Уточню: на сырых слайсах.

Я не против слайсов в целом и не предлагаю аллоцировать новые буферы на каждый чих. Я считаю дефектом что в UnmarshalJSON передается сырой слайс (byte[]), а не завернутый в Node. Да, Node тоже надо аллоцировать, но это-то должно быть копейками.

Вызывать Unmarshal внутри UnmarshalJSON — кажется очень естественно, а текущие интерфейсы делают это неэффективным. Почитал исходники, если есть много вложенных объектов с кастомными анмаршалингами — то асимптотика становится квадратичной от уровня вложенности за счет повторных валидаций.

она сразу бежит до конца этого объекта как бы вложенный он ни был


Бежит, проверяя валидность джсона внутри. Фактически, проводит работу по парсингу внутреннего объекта — без этого невозможно найти конец объекта.

библиотека использует рефлексию и парсит последовательно поля


Допустим у нас нет кастомного анмаршалинга. Как будет работать библиотека? Я предполагаю что так: «О, поле internal1 типа Internal1. Для типа нет кастомного анмаршалинга, что ж, найду конец поля internal1 и вызову рекурсивно анмаршалинг полученного слайса в тип Internal1». И по слайсу будет сделано два прохода — сначала с целью определить конец Internal1, потом чтобы собственно распарсить. Или конец поля ищется только для полей с кастомным анмаршаллингом?

Для вызывающей стороны вполне достаточно

Тут еще надо определить что вы имеете в виду под вызывающей стороной. Потребитель который вызывает условный JsonStringToObject должен предоставить только слайс/строку, да. А для восстановления объекта из кастомного джсон-представления библиотеке лучше бы использовать метод JsonNodeToObject. Нет кастомного анмаршалинга — вызывай JsonStringToObject и не парься. Есть — определи JsonNodeToObject и вызывай JsonStringToObject.

Вообще, в UnmarshalJSON всегда передается слайс, гарантированно являющийся JsonNode. По нему парсер уже прошелся и определил что он валидный (иначе бы парсер не нашел конец объекта). Тем не менее в сигнатуре это никак не отражено и единственное что с этим слайсом можно сделать — это вызвать json.Unmarshal(data, &raw). Который снова будет проверять, что в слайсе валидный джсон. На слайсах невозможно построить эффективный с точки зрения процессорного времени парсинг, по крайней мере кастомный
Вот есть у нас джсон `{«internal1»:{«internal2»:{}}}`. Как он распарсится? Допустим, парсим мы не в interface{} а в конкретный тип. Окей, анмаршал весь слайс как конкретный объект. Прочитали токен «internal1», смотрим — сейчас должен быть объект типа Internal1. Нужно подготовить слайс для него, то есть понять где он заканчивается. Для этого нужно пройтись и полностью распарсить {«internal2»:{}} — чтобы понять, что это наша закрывающая скобка, что здесь слайс заканчивается. В том числе определить что полю «internal2» соответствует слайс {} — иначе как мы поймем что поле «internal2» закончилось и закрывающая скобка соответствует концу нашего internal1.

Окей, определили слайс для internal1, вызвали анмаршал для этого слайса. Теперь анмаршал будет снова парсить содержимое слайса {«internal2»:{}}, в том числе определять что полю «internal2» соответствует слайс {}.

Слайс — это недостаточное количество информации. Нужно либо передавать для каста к пользовательскому типу «размеченный слайс», decodeState, узел дерева разбора; либо парсинг будет неэффективным, одни и те же слайсы будут парситься по нескольку раз. Возможно, из-за второго и требуется заменять на «что-то более быстрое»

Если аллокации неэффективны — нужно искать способы повышать эффективность (выделять пачками-массивами?)
А лучше даже так, с обработкой ошибки парсинга play.golang.com/p/tPYQZFGLajT
Нет, надо не «проверить», надо определить правила преобразования. Брать слайс из сырой джсон-строки между кавычек и интерпретировать его как джсон-число — однозначно порочный подход. Гораздо лучше распарсить джсон как есть, посмотреть что распарсилось (какие типы) и исходя из этого сделать явное преобразование в нужный тип.

Боюсь, исправить Unmarshal так просто не выйдет, это значит что надо разделять парсинг на две части, разбор из строки в дерево джсон-узлов, потом конвертацию узла дерева в заданный тип. Первое всегда общее, второе — можно доопределять для пользовательских типов.
Лишняя закрывающая квадратная скобка массива. Все работает play.golang.com/p/0qJBtd4HaPi
За
err := json.Unmarshal(data[1:len(data)-1], &cf.Float64)

надо отдельно бить линейкой по рукам. Кто вам сказал что json.Unmarshal для float64 ведет себя как обычный парсинг числа из строки? Изучили ли вы полностью стандарт json, чтобы утверждать что да? Что будет с научной записью, например — если она вдруг появится? (Тут я сам наверняка сказать не могу). Нужно использовать strconv.ParseFloat().

А как поведет себя парсинг части json-строки как числа? Вот тут могу привести пример — строка "\u0032\u002e\u0031\u0035" эквивалентна строке «2.15». Но на первой ваш код сломается, а по смыслу должен работать.
И так я тоже делать бы не стал. 01 например — это 1 с точки зрения джсона. А с точки зрения вашего кода — ошибка. Тоже распарсить в interface{}, посмотреть тип и значение и тогда решать.
И вообще, не нужно руками лезть в сырой джсон.
Сначала unmarshal в interface{}, а потом смотреть что там — строка или не строка
play.golang.com/p/Fl6yQHh-Hyj
Регуляркой нельзя. Регулярка не отловит вложенность произвольного уровня. И «по-простому» нельзя — в строковом литерале может быть закрывающая скобка, ее нужно пропустить. Ну а если учитывать экранирование символов — так это уже полный парсинг и получается)
Кажется, это дефект (issue) json-библиотеки. Там должен быть не []byte, а JsonValue (интерфейс?). И лежать в нем должен один из JsonNull, JsonString, JsonNumber, JsonBool, JsonObject, JsonArray.

Если у нас есть слайс байтов, значит сам json уже распаршен (как иначе могут быть найдены границы слайса?). Значит конструкции вида {"id":1, "price":} досюда дойти не могут — они будут отброшены раньше. Но это неочевидно (а может даже ошибочно — я не смотрел исходники) из-за интерфейса библиотеки.
Для того чтобы рисовать отрезок прямой не нужно <гипотенуза> пикселей! Достаточно max(dx,dy). Почти наверняка у вас пиксели перерисовываются по несколько раз.

На вики наглядная гифка.
К чему привязан лимит? В API приходит 3 разных refreshToken'а, как апи узнает, что это — 3 попытки расшифровки одного зашифрованного? Отдельный DeviceID/SessionID?
Нет таких векторов атаки, где ваш вариант устоит, а мой — нет

Я отталкивался от того что у вас refreshToken — многоразовый. Если одноразовый — пин-код в открытом виде действительно снижает безопасность.
Где гайды можно почитать? Вы в комментариях ссылаетесь на OAuth2, но оно во-первых трехстороннее, а во-вторых refreshToken там многоразовый. А у вас уже не refreshToken получается, а nonce какой-то.

Только сейчас понял, что refreshToken у вас одноразовый, надо подумать)

Да, но по сети все еще можно перехватить.

пин можно и в моем варианте изменить

Так у вас вообще расшифрованный токен по сети идет, бери и повторяй запрос. И смена пина не защитит от повтора. А у меня смена пина — защитит от повтора запроса.
ничего не мешает ввести логопасс

А в моем варианте логин вводить не надо)

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

Называть отправку пин-кода в апи ошибкой — ошибка. Это приемлимо и даже дает преимущества.
Действительно, этот вектор я не предусмотрел, спасибо. Но криптография на сервере нас спасет: храним в БД хеш от токена и хеш от пары токен+пин-код. При утечке БД Ева не сможет определить пин-код — исходного токена у нее не будет, перебирать нечего.

Вариант с проверкой на сервере позволяет гораздо более обширный функционал; например, безопасное изменение пин-кода и разблокировку паролем от аккаунта (если забыл/не захотел задавать пин-код).

И он безопаснее в некоторых сценариях. Например, Ева перехватила пакет, в котором Алиса обменивает токен. После этого Алиса меняет пин-код. Токен перешифровывается, но у Евы-то есть расшифрованный, Ева может повторить запрос и получить новый токен. В случае с проверкой пин-кода на сервере — Ева не знает новый пин-код.

Информация

В рейтинге
Не участвует
Откуда
Красноярск, Красноярский край, Россия
Зарегистрирован
Активность