Приходит баг репорт, жалуются, что наш компилятор не переваривает некий код на С, в то время как в Visual Studio все работает. Присылают кусок кода, смотрим. Функция IsSomeConditionSatisfied, или как-то так, ничего странного. Смотрим внимательнее. Имя функции — Is(zwsp)Some(zwsp)Condition(zwsp)Satisfied, где (zwsp) — zero-width-space, невидимый пробел, в utf8 — 0xE2 0x80 0x8B. Компилятор считает, что пробел — это пробел, и выдает ошибки. Что характерно — функция в таком виде была написана в header файле, собственно в .c файле, и еще в паре мест. GCC тоже выдает ошибки, а cl компилирует. Как такое вообще написали — может специально, может копипаста с форума, где слова побили на куски — черт знает.
Я как-то смотрел исходники одной IDE, наткнулся на класс WolfTheProblemSolver. Вот вроде и нужный API, а лишний раз подумаешь перед тем, как начать использовать.
Кстати, Ctrl+Shift+F — тоже непростая комбинация. В старых линуксах Ctrl+Shift+[A-F|U] использовали для ввода юникодных символов. Сейчас от этого оставили только Ctrl+Shift+U (и затем шестнадцатиричный код).
Все равно слишком длинно получается. Реальнее записать программу в виде байт-кода (например, взять спектрумовский бейсик, там один байт на команду), и заставить ее генерировать такой же байт-код. Либо придумать язык, где нужные функции записываются одной буквой.
Хотя понятно, что такой хак завязан на реализацию генератора псевдослучайных чисел, следовательно, ничем не лучше HQ9+ и других хаков.
Ага, вот здесь у вас переполнение буфера, вот там, там и там — используется неинициализированная переменная со стека, дальше вообще непойми что. Этот код будет чаще падать в коре, чем работать, скажет ПВС студия. :)
На самом деле, код самого эксплойта не обязан иметь уязвимости, которыми он пользуется, так что вряд ли что интересное найдется.
На небольших чисто джавных проектах разницы между эклипсом и идеей нет. Функциональность практически одинакова — редактор, подсказки, шаблоны, автодополнение, рефакторинг, отладка и т.п. — похожи. Что использовать — дело вкуса. Лично мне больше нравится эклипс, например:
— в эклипсе одна комбинация кнопок — Ctrl+space — на автодополнение переменных/методов/классов, шаблоны (for, toarray, ...), переопределение методов (начинаешь писать имя метода родительского класса/интерфейса, Ctrl+space — генерится пустой метод с Override) и т.п. В идее это все на разных кнопках (как переопределять методы — пока вообще не нашел).
— в эклипсе проект сразу инкрементально перекомпилируется при изменении любого файла, и если где-то в другой части проекта возникает ошибка, видно сразу — маркер с ошибкой дорисовывается к файлу в дереве. В идее, чтобы узнать, что в файле есть ошибка, нужно файл сначала открыть.
— эклипс более отзывчив, всё, что долго работает, запускается в бэкграунде. Идея, например, при открытии проекта начинает индексировать и вешает UI — можно идти отдыхать.
На больших проектах уже проявляются плюсы идеи и минусы эклипса:
— в идее сразу поддерживается больше разных языков; в эклипсе нужно доустанавливать плагины;
— в эклипсе довольно ограниченная модель workspace'а. Например, настройки хранятся отдельно, и их нельзя положить в репозиторий. Т.е. если в команду пришел новый человек, ему надо послать файлик с настройками форматирования, и т.п. Такая же ерунда приключается, когда надо достать код с ветки в отдельный воркспейс. Еще более мрачно это выглядит, когда надо открыть и настроить много модулей.
Стоит отметить, что такого рода оптимизация возможна в основном в случае ArrayList.
Можно оптимизировать и обход других коллекций, если перед циклами элементы записать во временный массив, используя toArray(). Итератор каждой коллекции отработает один раз, а дальше циклы будут просто брать элементы массивов. Тогда выигрыш может быть не только за счет меньшего числа созданных итераторов, но еще и за счет уменьшения overhead'а использования итераторов (взять элемент массива по индексу дешевле, чем get() или next()).
Но самое главное, конечно — это сидеть с профайлером и смотреть.
В Паскале эта проблема решена аккуратнее. Вместо квадратных скобок, к примеру, можно писать "(." и ".)", но это распознается на уровне токенов, а не заменяется где попало.
В нашей компании статический анализатор кода (корпоративный) запускается на ночных билдах. В начале он нашел довольно много серьезных ошибок типа возможных NPE, незакрытых потоков, SQL injection'ов и т. д. Постепенно исправили. Только потом начали искать и править вещи типа {s = new String(«aaa»);} — из любви к искусству.
Приходит баг репорт, жалуются, что наш компилятор не переваривает некий код на С, в то время как в Visual Studio все работает. Присылают кусок кода, смотрим. Функция IsSomeConditionSatisfied, или как-то так, ничего странного. Смотрим внимательнее. Имя функции — Is(zwsp)Some(zwsp)Condition(zwsp)Satisfied, где (zwsp) — zero-width-space, невидимый пробел, в utf8 — 0xE2 0x80 0x8B. Компилятор считает, что пробел — это пробел, и выдает ошибки. Что характерно — функция в таком виде была написана в header файле, собственно в .c файле, и еще в паре мест. GCC тоже выдает ошибки, а cl компилирует. Как такое вообще написали — может специально, может копипаста с форума, где слова побили на куски — черт знает.
Такой вот brainfuck на C.
Хотя понятно, что такой хак завязан на реализацию генератора псевдослучайных чисел, следовательно, ничем не лучше HQ9+ и других хаков.
На самом деле, код самого эксплойта не обязан иметь уязвимости, которыми он пользуется, так что вряд ли что интересное найдется.
— в эклипсе одна комбинация кнопок — Ctrl+space — на автодополнение переменных/методов/классов, шаблоны (for, toarray, ...), переопределение методов (начинаешь писать имя метода родительского класса/интерфейса, Ctrl+space — генерится пустой метод с Override) и т.п. В идее это все на разных кнопках (как переопределять методы — пока вообще не нашел).
— в эклипсе проект сразу инкрементально перекомпилируется при изменении любого файла, и если где-то в другой части проекта возникает ошибка, видно сразу — маркер с ошибкой дорисовывается к файлу в дереве. В идее, чтобы узнать, что в файле есть ошибка, нужно файл сначала открыть.
— эклипс более отзывчив, всё, что долго работает, запускается в бэкграунде. Идея, например, при открытии проекта начинает индексировать и вешает UI — можно идти отдыхать.
На больших проектах уже проявляются плюсы идеи и минусы эклипса:
— в идее сразу поддерживается больше разных языков; в эклипсе нужно доустанавливать плагины;
— в эклипсе довольно ограниченная модель workspace'а. Например, настройки хранятся отдельно, и их нельзя положить в репозиторий. Т.е. если в команду пришел новый человек, ему надо послать файлик с настройками форматирования, и т.п. Такая же ерунда приключается, когда надо достать код с ветки в отдельный воркспейс. Еще более мрачно это выглядит, когда надо открыть и настроить много модулей.
Можно оптимизировать и обход других коллекций, если перед циклами элементы записать во временный массив, используя toArray(). Итератор каждой коллекции отработает один раз, а дальше циклы будут просто брать элементы массивов. Тогда выигрыш может быть не только за счет меньшего числа созданных итераторов, но еще и за счет уменьшения overhead'а использования итераторов (взять элемент массива по индексу дешевле, чем get() или next()).
Но самое главное, конечно — это сидеть с профайлером и смотреть.
Напрашивается «return user.equals(principalImpl.user)» или «return user.equals(principalImpl.getName())», но уж точно не «toString()».