Помню, на anti-malware.ru была статья с громким названием «Windows 10: избавляемся от шпионского функционала», а в ней — инструкции по выключению облачных сервисов (windows defender, smart screen и т.п.).
В общем, я тут наконец погулил и вразумился. Оказалось, что если строка содержит суррогатные пары, то не только Substring, но и другие методы работы со строками будут давать странные результаты, поскольку работают именно с последовательностью 16-битных char, а не грубо говоря с «буквами» (не с логическим значением этих char'ов), то есть фактически не берут в расчёт кодировку. Получается, что для них суррогатрая пара — это действительно два разных символа, хотя для UTF-16 это один символ.
Таким образом, если некая «буква» представлена двумя char'ами, и я пишу слово из трёх таких букв, Length скажет, что длина такой строки — шесть символов. А не три. Так же себя ведут Substring, IndexOf и т.п. Собственно, об этом и статья — что строка C# это не то же самое что строка в кодировке UTF-16.
Спрошу иначе — на каких конкретно данных приведённый выше «плохой код» выдаст неправильный результат?
Сколько байт в суррогатной паре — понятно из статьи. Непонятно то, сколько символов представляет такая суррогатная пара. Если один — тогда Substring() не должен его разбивать на два. Если два — тогда зачем называть их «суррогатной парой», почему просто не считать их двумя разными символами.
Насколько я понял из объяснений — первый элемент суррогатной пары не может быть интерпретирован как самостоятельный символ. То есть, он имеет логический смысл только как составляющая пары, стало быть пара представляет собой один символ, а не два, и соответственно должна интерпретироваться как один символ библиотечными методами работы со строками. Но это, конечно, если строка правильно сформирована, то есть содержит в себе валидное «символьное» значение.
Суррогатная пара — это два отдельных UTF-16 символа.
Что-то тут не так. Выше по тексту сказано: «Если вам нужно представить в UTF-16 символ с кодом больше U+FFFF, то используются два слова: первая часть суррогатной пары (в диапазоне от 0xD800 до 0xDBFF) и вторая (0xDC00 … 0xDFFF)». То есть для представления одного символа используются два слова суррогатной пары. Одного символа же, а не двух.
Несколько комментариев по сути статьи:
1. Анализ Test Impact есть и в tfs 2010 / visual studio 2010. Чем конкретно отличается реализация его в 2013 — точно сказать не могу. Лично я пользовался этой фичей именно в 2010, замечания ниже просьба рассматривать в том же контексте.
2. Очевидный минус данной технологии в том, что для её корректной работы ручные тесты нужно делать строго по описанному сценарию. Любое отклонение от шагов приводит к собиранию лишних данных. Как-либо отредактировать собранные данные тестировщик не может, всё работает только автоматически.
3. Приложение для сбора данных также определяется автоматически. К счастью, можно указать фильтр по именам сборок, данные для которых собирать не надо.
4. Информация для анализа начинает собираться только для .Net-приложений, запущенных ПОСЛЕ старта серии тестов. Если сначала запустить приложение, а потом уже запустить серию тестов, информация собираться не будет. Вкупе с п.2 необходимость запускать приложение заранее приводит к сбору лишней информации.
5. «если проводить тесты от билда к билду, то благодаря анализу информации Code Coverage ручных тестов и ее сохранению для каждого пройденного тестового плана, мы можем четко предсказать то какой тест сломался, а какие тесты вообще не затронуты» — как раз Code Coverage ручных тестов, к сожалению, посчитать нельзя. Нельзя узнать, какой процент когда покрывают ручные тесты. Анализ Test Impact составляет именно список затронутых тестов, объём покрытия тестами кода он не считает.
Действительно, так и происходит — сначала, не читая документации, кликают «дальше»-«дальше»-«дальше», а потом жалуются на глючность кривоустановленного Эксченджа.
Таким образом, если некая «буква» представлена двумя char'ами, и я пишу слово из трёх таких букв, Length скажет, что длина такой строки — шесть символов. А не три. Так же себя ведут Substring, IndexOf и т.п. Собственно, об этом и статья — что строка C# это не то же самое что строка в кодировке UTF-16.
Спасибо, теперь вроде понятно))
Сколько байт в суррогатной паре — понятно из статьи. Непонятно то, сколько символов представляет такая суррогатная пара. Если один — тогда Substring() не должен его разбивать на два. Если два — тогда зачем называть их «суррогатной парой», почему просто не считать их двумя разными символами.
Насколько я понял из объяснений — первый элемент суррогатной пары не может быть интерпретирован как самостоятельный символ. То есть, он имеет логический смысл только как составляющая пары, стало быть пара представляет собой один символ, а не два, и соответственно должна интерпретироваться как один символ библиотечными методами работы со строками. Но это, конечно, если строка правильно сформирована, то есть содержит в себе валидное «символьное» значение.
Что-то тут не так. Выше по тексту сказано: «Если вам нужно представить в UTF-16 символ с кодом больше U+FFFF, то используются два слова: первая часть суррогатной пары (в диапазоне от 0xD800 до 0xDBFF) и вторая (0xDC00 … 0xDFFF)». То есть для представления одного символа используются два слова суррогатной пары. Одного символа же, а не двух.
По-моему для воспроизведения проблемы тут надо сначала делать GetBytes, а потом полученный кусок байт разрывать посередине.
Здесь это краткое причастие, поэтому «уверены». Человек может уверенно говорить уверенным голосом, когда он в чём-то уверен.
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
на уязвимой системе выведется слово «vulnerable»
1. Анализ Test Impact есть и в tfs 2010 / visual studio 2010. Чем конкретно отличается реализация его в 2013 — точно сказать не могу. Лично я пользовался этой фичей именно в 2010, замечания ниже просьба рассматривать в том же контексте.
2. Очевидный минус данной технологии в том, что для её корректной работы ручные тесты нужно делать строго по описанному сценарию. Любое отклонение от шагов приводит к собиранию лишних данных. Как-либо отредактировать собранные данные тестировщик не может, всё работает только автоматически.
3. Приложение для сбора данных также определяется автоматически. К счастью, можно указать фильтр по именам сборок, данные для которых собирать не надо.
4. Информация для анализа начинает собираться только для .Net-приложений, запущенных ПОСЛЕ старта серии тестов. Если сначала запустить приложение, а потом уже запустить серию тестов, информация собираться не будет. Вкупе с п.2 необходимость запускать приложение заранее приводит к сбору лишней информации.
5. «если проводить тесты от билда к билду, то благодаря анализу информации Code Coverage ручных тестов и ее сохранению для каждого пройденного тестового плана, мы можем четко предсказать то какой тест сломался, а какие тесты вообще не затронуты» — как раз Code Coverage ручных тестов, к сожалению, посчитать нельзя. Нельзя узнать, какой процент когда покрывают ручные тесты. Анализ Test Impact составляет именно список затронутых тестов, объём покрытия тестами кода он не считает.