Comments 87
Кстати, на коде Идеи у вас вменяемое количество предупреждений? :-)
Ничего себе! У нас только dataflow выдаёт больше 10000 предупреждений, а все включённые инспекции на всём коде Идеи — около 200000. Что с ними делать — абсолютно непонятно :-D
Спасибо что вы наконец пришли в java мир, как всегда приятно читать ваши статьи.
Вы на проект SonarQube смотрели? Там только для Java больше 1700 инспекций...
Ну а если вы таки сможете придумать что-то дополнительно к уже имеющемуся там, то имеет смысл написать плагин для SonarQube, т.к. он является стандартом де-факто в корпоративной среде. Уж коли вы на корпоративный рынок целитесь...
Там только для Java больше 1700 инспекций...
Смотрите мой ответ на первый комментарий. И независимо от наличия собственных инструментов анализа, мы рекомендуем использовать совместно разные инструменты контроля качества кода для получения хорошего программного продукта.
Это-то понятно. Но так же нужно понимать и то, что вы вступаете на рынок, на котором тема статического анализа прорабатывается давно и плотно. И далеко не любителями...
Так что мне будет очень любопытно понаблюдать за развитием событий :-)
Больше статик анализа большого и разного :-)
Не могу сказать куда вы смотрите, но вот прям сейчас у нас в боевом профиле светится цифра 1255. Это при том, что нам не все правила нужны/подходят и очень многое выключено.
V6029 Possible incorrect order of arguments passed to method: 'parent', 'profile'. InheritanceActionTest.java 254:
private void setParent(QProfileDto profile, QProfileDto parent) {
ruleActivator.setParentAndCommit(dbSession, parent, profile);
}
RuleActivator.java
public List<ActiveRuleChange> setParentAndCommit(
DbSession dbSession,
QProfileDto profile,
@Nullable QProfileDto parent) {
....
}
private void setUpdatedAtFromDefinition(@Nullable Long updatedAt) {
if (updatedAt != null && updatedAt > definition.getUpdatedAt()) {
setUpdatedAt(updatedAt);
}
}
private void setUpdatedAtFromMetadata(@Nullable Long updatedAt) {
if (updatedAt != null && updatedAt > definition.getUpdatedAt()) {
setUpdatedAt(updatedAt);
}
}
Что-то мне подсказывает, что здесь скопипастили и забыли во втором случае поменять definition на metadata.
Когда?
@Autowired
private SomeService someService;
Есть ли идеи использования нейронных сетей для поиска ошибок в коде?
Так можно ненароком скомпилировать нечто такое, что человек никогда бы не написал (голос ИИ за кадром: МУАХАХАХАХАХА)
В таком случае НС максимум повторит компилятор.
Ошибки в логике компилятор не ищет.
Молодцы, что статью написали! И жалко, что вас на конференцию не взяли (я рекомендовал брать, но не послушали).
Да, FABA — это был проект в JetBrains, и он интегрирован в Идейку. Чистоту методов тоже иногда умеем выводить. И контракты вида null->false. И по сорцам умеем иногда, не только по байткоду. Причём по сорцам на лету в процессе редактирования.
Вопрос: при сравнении строк вы различаете равенство по ссылке и по контенту? str1.equals(str2) && str1 != str2
вы подсветите (ошибочно) как всегда ложное или нет?
int *ptr1 = ....;
int *ptr2 = ....;
if (*ptr1 == *ptr2 && ptr1 != ptr2) { .... }
Если в двух словах, то виртуальные значения для ссылок в Java, это наши виртуальные значения для указателей из C++. А виртуальное значение для указателя может, в свою очередь, содержать «boxed» значение (например целого числа, строки, и т.п.).
Ну и соответственно, в одном случае сравниваются виртуальные значения строк, а в другом
Далее — Veracod сканирует jar/war/ear файлы и ему не нужны исходники. Fortify встраивается в билд процесс (у нас был maven). Из этого можно сделать выводы, что Veracode просто разбирает Java bytecode, а Fortify получает AST (abstract syntax tree) и уже работает с ним. То есть обе системы не работают напрямую с исходниками и нет необходимости осуществлять синтаксический анализ исходников. По моему мнению это правильный подход, тем более что Java bytecode хорошо описан в спецификации. Я писал программу, которая его разбирает и дошел до команд виртуальной машины. По ощущениям, структура скомпилированного Java class файла достаточно логичная и понятная.
По поводу того, как используется сканер — приложение обязательно должно сканироваться перед релизом и релизить можно только приложения без critical и very height уязвимостей (это идеал, на практике, конечно, бывает по разному). К упомянутым типам уязвимостей относятся XSS, SQL injection, hardcoded passwords. На code smells всем наплевать при сканировании. То есть сканирование — это выявление уязвимостей, которые могут повлиять на безопасность системы. Качество кода не является сколь-нибудь важным на данном этапе.
И еще одно — не знаю как сейчас устроено у HP Fortify, но Veracode предоставляет сервис: вы закачиваете артифакты, Veracode их сканирует, вы получаете отчет (в web системе), в котором указаны найденные проблемы. У вас есть возможность связаться с сотрудниками Veracode, чтобы обсудить найденные уязвимости и пометить их как false positive (при необходимости). То есть это целая инфраструктура, которая не заканчивается на сканере.
На уровне байткода анализировать джаву — довольно тупиковый путь. Я писал свой анализатор на байткоде. Некоторые проблемы в принципе не увидишь. Надо быть как можно ближе к исходникам.
Я вот даже не уверен, что автоматическое удаление скобок в Spoon — это хорошая идея. Например, a << 16 + b
похоже на ошибку: приоритет сложения выше, чем сдвига, а выглядит так будто автор забыл про это. С другой стороны, a << (16 + b)
уже выглядит сознательным решением, и тут предупреждать не надо. Если есть дерево без скобок, эту разницу не увидишь. Даже комментарии в коде и отступы очень важны для статического анализа.
Как вариант, можно анализировать на разных уровнях. В компиляторном мире, как правило, даже разделяют понятия: дерево разбора (Parse Tree) и абстрактное синтаксическое дерево (AST). Первое вообще может быть преобразовано обратно в код символ-в-символ (full fidelity). Второе не содержит незначимые узлы.
У нас в Идейке parse tree с full fidelity, конечно, но это не сильно усложняет потоковый анализ. Конечно, у нас и вычисление типов, и резолв ссылок сделан. В байткоде с этим проще, но и свои минусы есть — erasure. Восстановить generic-сигнатуру бывает очень сложно (эту задачу решают декомпиляторы). С байткодом, кстати, ещё большой минус — привязать предупреждение к конкретному элементу исходника. Там только номера строк есть, если отладочную инфу генерировали. Иногда это сильно усложняет понимание, где же ошибка.
У вас изначально очень крутой анализатор C++. Потом вы прикрутили C#. Верно ли, что анализатор С# гораздо более слабый по сравнению с С++ анализатором? И это направление вы, похоже, решили не развивать? Как при этом планируется позиционировать Java-анализатор по сравнению с С#: хотите ли проработать направление Java лучше, чем С#?
А можете еще раз в двух словах (для идиотов) пояснить, что означает использовать С++ ядро для java-анализатора? В статье это как-то очень замысловато описано. И почему не получилось это сделать для С# анализатора?
А можете еще раз в двух словах (для идиотов) пояснить, что означает использовать С++ ядро для java-анализатора? В статье это как-то очень замысловато описано.Как-же в двух словах то объяснить… Целая статья для этого понадобилась. :)
И почему не получилось это сделать для С# анализатора?Мы были неопытные и решили просто разработать новый анализатор. Про использование одного из другого мы не думали, да и возможно не осилили такое сделать тогда просто в силу трудоёмкости.
Про C# я не знаю наверняка, но думаю что на тот момент и инфраструктура C++ анализатора тоже не позволила бы так просто перенести что-либо в C#.
Вы приходите в мир, где статических анализаторов масса. Покажите примеры ошибок, которые не находят существующие популярные решения. До этого- мысль только «ещё одни решили сделать революцию, а вышел пшик».
В посте пару ошибок из самого intellij.
Вопрос именно в обнаружении ошибок. IDEA может это делать бесплатно, да и платно- у неё куча других плюсов. А PVC новый узкоспециализированный продукт- и вопрос, нужен ли он.
Это ни о чём не говорит. Идейка в сорцах Идейки находит двести тысяч предупреждений. В том числе и те, которые в посте есть. Просто не всегда доходят руки их исправить.
Это тут ни при чём. Там и реальных проблем полно, десятки тысяч, и можно сделать профиль инспекций, который только реальные проблемы будет показывать. Особенно с nullability много. Это механически не исправишь, там в каждом месте смотреть надо.
Т.е. создан статический анализатор кода, которым невозможно пользоваться? Даже сами разработчики не могут настроить его, чтобы использовать результаты его работы в своём проекте?
Вот у нас вывод PVS-Studio на PVS-Studio чистый. И если где-то накосячили, то нам на почту приходит только одно-два предупреждения. :)
Ну и вы же сами зачем-то поддерживаете режим «показать только свежие предупреждения». По вашей логике, если эта фича востребована, значит, вашим анализатором тоже невозможно пользоваться ;-)
String colOrScalar1 = tdesc[4];
....
if (colOrScalar1.equals("Col") &&
colOrScalar1.equals("Column")) {
....
} else if (colOrScalar1.equals("Col") &&
colOrScalar1.equals("Scalar")) {
....
} else if (colOrScalar1.equals("Scalar") &&
colOrScalar1.equals("Column")) {
....
}
Такой паттерн это же явно баг.
Нет, я про другой пример. Нумеруйте их что ли, чтобы ссылаться можно было =)
public static boolean equal(byte[] arg1, final int start1,
final int len1, byte[] arg2,
final int start2, final int len2) {
if (len1 != len2) { // <=
return false;
}
if (len1 == 0) {
return true;
}
....
if (len1 == len2) { // <=
....
}
}
Буду ждать дальше :)
Не в тему статьи, но кто-то пользуется статическими анализаторами SQL & PL/SQL? Можете опытом поделиться?
Логика tsql была без тестов — проект легаси с человеко-годами техдолга. Масштабы бедствия менеджменту и команде показал, но адекватных действий так и не дождался. Разработчики хранимок так и не использовали этот подход в процессе разработке.
Для PL/SQL мой бывший коллега скрещивал статический анализатор Toad c Sonar, чтобы сэкономить деньги компании на платном плагине. На других проектах максимум что использовали DBA — это юнит тесты для хранимок в Oracle, без статического анализа кода.
Разработка нового статического анализатора: PVS-Studio Java