All streams
Search
Write a publication
Pull to refresh
2
0
quarantino @quarantino

User

Send message
Смотря как «работает». Если работает, но нашли переполнение буфера или подобную дыру — надо исправлять.
Такое есть в MISRA-C (правило 20.1). Не знаю насчет PVS-studio, но, например, Klocwork это может отловить.
Была как-то история.

Приходит баг репорт, жалуются, что наш компилятор не переваривает некий код на С, в то время как в Visual Studio все работает. Присылают кусок кода, смотрим. Функция IsSomeConditionSatisfied, или как-то так, ничего странного. Смотрим внимательнее. Имя функции — Is(zwsp)Some(zwsp)Condition(zwsp)Satisfied, где (zwsp) — zero-width-space, невидимый пробел, в utf8 — 0xE2 0x80 0x8B. Компилятор считает, что пробел — это пробел, и выдает ошибки. Что характерно — функция в таком виде была написана в header файле, собственно в .c файле, и еще в паре мест. GCC тоже выдает ошибки, а cl компилирует. Как такое вообще написали — может специально, может копипаста с форума, где слова побили на куски — черт знает.

Такой вот brainfuck на C.
По одной записи в руки после предъявления паспорта с иногородней пропиской.
Например, этот: bugs.openjdk.java.net/browse/JDK-8007407, как раз со странички с P5, и как раз про лямбды.
Я как-то смотрел исходники одной IDE, наткнулся на класс WolfTheProblemSolver. Вот вроде и нужный API, а лишний раз подумаешь перед тем, как начать использовать.
Кстати, Ctrl+Shift+F — тоже непростая комбинация. В старых линуксах Ctrl+Shift+[A-F|U] использовали для ввода юникодных символов. Сейчас от этого оставили только Ctrl+Shift+U (и затем шестнадцатиричный код).
Сталкивался с таким поведением в IDEA, пришлось включить эклипсную раскладку (за поддержку которой ребятам из JetBrains отдельное спасибо).
В Eclipse, кстати, тоже есть такие аннотации; но чтобы была польза, их придется расставлять по всему проекту.
Все равно слишком длинно получается. Реальнее записать программу в виде байт-кода (например, взять спектрумовский бейсик, там один байт на команду), и заставить ее генерировать такой же байт-код. Либо придумать язык, где нужные функции записываются одной буквой.

Хотя понятно, что такой хак завязан на реализацию генератора псевдослучайных чисел, следовательно, ничем не лучше HQ9+ и других хаков.
Ага, вот здесь у вас переполнение буфера, вот там, там и там — используется неинициализированная переменная со стека, дальше вообще непойми что. Этот код будет чаще падать в коре, чем работать, скажет ПВС студия. :)

На самом деле, код самого эксплойта не обязан иметь уязвимости, которыми он пользуется, так что вряд ли что интересное найдется.
Дело не только в отжирании ресурсов. В чистом 64 линуксе нет некоторых 32-битных библиотек. Например, там не запустится графика (AWT, SWT).
На небольших чисто джавных проектах разницы между эклипсом и идеей нет. Функциональность практически одинакова — редактор, подсказки, шаблоны, автодополнение, рефакторинг, отладка и т.п. — похожи. Что использовать — дело вкуса. Лично мне больше нравится эклипс, например:

— в эклипсе одна комбинация кнопок — Ctrl+space — на автодополнение переменных/методов/классов, шаблоны (for, toarray, ...), переопределение методов (начинаешь писать имя метода родительского класса/интерфейса, Ctrl+space — генерится пустой метод с Override) и т.п. В идее это все на разных кнопках (как переопределять методы — пока вообще не нашел).

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

— эклипс более отзывчив, всё, что долго работает, запускается в бэкграунде. Идея, например, при открытии проекта начинает индексировать и вешает UI — можно идти отдыхать.

На больших проектах уже проявляются плюсы идеи и минусы эклипса:

— в идее сразу поддерживается больше разных языков; в эклипсе нужно доустанавливать плагины;

— в эклипсе довольно ограниченная модель workspace'а. Например, настройки хранятся отдельно, и их нельзя положить в репозиторий. Т.е. если в команду пришел новый человек, ему надо послать файлик с настройками форматирования, и т.п. Такая же ерунда приключается, когда надо достать код с ветки в отдельный воркспейс. Еще более мрачно это выглядит, когда надо открыть и настроить много модулей.
Стоит отметить, что такого рода оптимизация возможна в основном в случае ArrayList.


Можно оптимизировать и обход других коллекций, если перед циклами элементы записать во временный массив, используя toArray(). Итератор каждой коллекции отработает один раз, а дальше циклы будут просто брать элементы массивов. Тогда выигрыш может быть не только за счет меньшего числа созданных итераторов, но еще и за счет уменьшения overhead'а использования итераторов (взять элемент массива по индексу дешевле, чем get() или next()).

Но самое главное, конечно — это сидеть с профайлером и смотреть.
А кстати, как сделать, чтоб ctrl+space работал как в эклипсе — автодополнения, темплейты и т.п. на одной кнопке?
Взгляните как раз на седьмой пример. Ну кто в здравом уме напишет такое без копипасты?

public boolean equals(Object obj) {
  if (obj instanceof PrincipalImpl) {
    PrincipalImpl principalImpl = (PrincipalImpl) obj;
    return user.equals(principalImpl.toString());
  } else {
    return false;
  }
}


Напрашивается «return user.equals(principalImpl.user)» или «return user.equals(principalImpl.getName())», но уж точно не «toString()».
В Паскале эта проблема решена аккуратнее. Вместо квадратных скобок, к примеру, можно писать "(." и ".)", но это распознается на уровне токенов, а не заменяется где попало.
В нашей компании статический анализатор кода (корпоративный) запускается на ночных билдах. В начале он нашел довольно много серьезных ошибок типа возможных NPE, незакрытых потоков, SQL injection'ов и т. д. Постепенно исправили. Только потом начали искать и править вещи типа {s = new String(«aaa»);} — из любви к искусству.

Information

Rating
Does not participate
Registered
Activity