Break through Java abnormal processing rules

xiaoxiao2021-03-06  38

Q: I call the external method in my application and want to capture the exception that it may thrown. Can I capture java.lang.exception? A: Depending on a given method to process all runtime and detection exceptions are insufficient for preventing external errors. You can read the current JavaWorld article - "Java Tip 134: When Catching Exception, Don't Cast your Net Too Wide". This article warned the capture java.lang.exception and java.lang.throable is not good. It is very important to capture the exception you can specify for the maintenanceability of the code. However, this rule relies on a special environment. If you don't plan your program to crash and keep your data structure safe anomaly, you must capture the true exception thrown.

For example, imagine that you have a server that loads this interface:

Public interface ifoo {/ ** * this method can't throw any checked exceptions ... or can it? * / void bar ();} // end of interface

The reason for giving parameters is to let us notify us where such services are available, and different IFOO implementations can be loaded from external resources. You write the following code:

Try {ifoo foo = ... // Get An ifoo Implementation foo.bar ();} catch (runtimeException ie) {// handle 'oe' ...} catch (error e) {// handle or re-throw 'e' ...}

And you have processed all possible exceptions in this. You don't need to add any capture of java.io ioException, because ifoo implementation does not throw it from ifoo.bar (), right? (In fact, if you add a capture java.io ioException, the compiler may discard it as an unreachable exception) error. In the Evilfoo class I wrote, the bar () method proves any exceptions that will throw you to the class constructor:

Public void bar () {Evilthrow.Throwthrowable (m_throwthis);}

Run the MAIN method:

Public class main {public static void main (final string "args {// this try / catch block Appears {ify, this is not true tryever, this is not true tryever, this is not true tryever New Evilfoo (New Java.io.ioException ("surprise!")); foo.bar ();} catch (runtimeException ooe) {// ignore ooe} catch (error e) {// ignore e}}} // End of class

You will see the java.io.Exception exception instance throw from the bar () method and there is no capture block:

> java -cp classes mainexception in thread "main" java.io.IOException: surprise! at main.main (main.java: 23)

What happened here?

The main observation is that Java rules that typically detect exceptions are only performed when compiling. When running, a JVM cannot guarantee whether the exception thrown by a method and the throwing exception declared in this method. Because the role of the calling method is to capture and process all the exceptions thrown from the calling method. Any exception that is not declared by the calling method will not be ignored and refused to call the stack. If the normal behavior is executed by the compiler, how do I create Evilfoo? There are at least two ways to create an unusual Java method that throws no declaration: thread.stop (thRowable) is not used in favor, but it is still used and passing a throwable THREAD. Compile: You can compile Evilfoo when you do not compile the true declaration bar () method throw the IFOO temporary version of the detection exception. I use the latter choice: I compile the start defined Evilthrow Class: Public Abstract Class Evilthrow {public static void throwthrow (throwable throwable) throws throwable {throw throwable;}}

Next, I use Byte Code Engineering Library (BCEL) Jasminvisitor to remove the throwthrowable () method of throwThrowable () method in assembly code and compile new versions with Jasmin Assembler. If you write a constructor that captures an exception, it should always capture java.lang.Throwable, not just capture java.lang.exception. This rule is suitable for the application of administrative runtime applications and external components that may contain errors or even malicious code. You have to make sure you caught throwable and filter out the error message. The following example illustrates what if you don't follow this suggestion. Example: Breaking Swingutilities.InvokeAndwait () javax.swing.swingutilities.invokeAther () is a useful way to perform a thread on the AWT. When an application thread must update the graphical user interface and obey all Swing thread rules, this method will be called. An exception that does not capture runnable.run () will be captured and packaged in an InvocationTrageTexception to resolve. Sun's J2SE1.4.1 assumes that such an unpaged exception is just a subclass of java.lang.exception. Here is a Swingutilities.InvokeAit () call java.awt.event.invocationEvent:

Public void dispatch () {if (catChexception) {type {runnable.run ();} catch (exception e) {exception = e;}} else {runnable.run ();} if (notifier! = null) {synchronized (notifier) ​​{notifier.notifyall ();}}}

The problem with this code is if runnable.run () throws a throwable, the capture block is not and notifier.notifyall () will never be executed. Then call the application thread will wait for a non-public lock object in java.awt.eventqueue.invokeAndwait () (Lock.Wait () will never be executed):

public static void invokeAndWait (Runnable runnable) throws InterruptedException, InvocationTargetException {class AWTInvocationLock {} Object lock = new AWTInvocationLock (); InvocationEvent event = new InvocationEvent (Toolkit.getDefaultToolkit (), runnable, lock, true); synchronized (lock) {Toolkit .getEventQueue () postEvent (event); lock.wait ();} Exception eventException = event.getException (); if (eventException = null!) {throw new InvocationTargetException (eventException);}} let EvilFoo implement Runnable:

Public void Run () {bar ();

Then, call it in the main:

Swingutilities.invokeAndwait (New Throwable ("Surprise!")))))))

As you can see, untrusted code has enabled your code to enter the exception in the execution path you are not prepared.

转载请注明原文地址:https://www.9cbs.com/read-119380.html

New Post(0)