1. Java / Говнокод #11400

    +117

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    public class Foo { 
     public Foo() {
      System.out.println("constructing foo: " + this);
      throw new RuntimeException();
     }
     public void doEvil() {
      System.out.println("Evil!Evil!Evil");
     }
    }
    
    public class MyFoo extends Foo {
     public static Foo x;
     @Override
     protected void finalize() throws Throwable {
      x = this;
     } 
    }
    
    try {
     Foo x = new MyFoo();
    } catch(Exception e) {
     System.out.println(""+e);
    }
    System.gc();
    System.runFinalization();
    System.out.println("MyFoo instance: " + MyFoo.x);
    MyFoo.x.doEvil();

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

    А теперь вопрос на засыпку: как сделать то же самое, не используя finalize и gc?

    Запостил: someone, 12 Июля 2012

    Комментарии (9) RSS

    • Источник: http://futuretask.blogspot.com/2006/05/java-tip-10-constructor-exceptions-are.html
      Ответить
    • >А теперь вопрос на засыпку: как сделать то же самое, не используя finalize и gc?

      http://ideone.com/1aiJh
      Ответить
      • o_O

        Под SecurityManager'ом не заработает. А как без setAccessible? И вообще без рефлексии?

        EDIT: И без сановских хакерских функций. Чисто стандарт.
        Ответить
        • Такой вопрос - а зачем вам "получать доступ к методу экземпляра объекта, конструктор которого выбрасывает исключение". Имхо если объект недоконструирован - вызов его методов не имеет никакого смысла...
          Ответить
        • Таки вырезать исключения из конструктора. Библиотеки для манипуляций с байткодом есть.
          Ответить
          • Ну если уж мы вдаёмся в такие дебри, то можно использовать AOP, ConstructorInterceptor и в нём игнорировать собственно вызов конструктора.

            Но нет. Чисто языковые средства. Подсказка: уязвимость специфична конкретно для этого класса Foo, в общем случае не сработает.
            Ответить
    • Я стараюсь вообще не выбрасывать исключения в конструкторах. Если нужна валидация аргументов, использую для этих целей фабричный метод или Builder.
      Ответить

    Добавить комментарий