UF.IMAGEIO

UF (Use Freed) issues are reported when there is an attempt to use resources after they were released. The UF.IMAGEIO warning indicates an attempt to use an ImageIO stream after it was closed.

Example 1

Copy
     public boolean canDecodeInput(ImageInputStream stream) {
         byte[] b = new byte[8];
         try {
             final long l = stream.length();
             if (l > 655335) {
                 return false;
             }
             stream.mark();
             stream.readFully(b);
             stream.reset();
         } catch (IOException e) {
             return false;
         } finally {
             try {
                 stream.close();
             } catch (IOException e) {
                 // do nothing
             }
         }
 
         // Cast unsigned character constants prior to comparison
         return (b[0] == (byte) 'm' && b[1] == (byte) 'y' &&
                 b[2] == (byte) 'f' && b[3] == (byte) 'o' &&
                 b[4] == (byte) 'r' && b[5] == (byte) 'm' &&
                 b[6] == (byte) 'a' && b[7] == (byte) 't');
     }
 
     public void decode(Object data) throws IOException {
         final ImageInputStream stream = ImageIO.createImageInputStream(data);
         if (canDecodeInput(stream)) {
             try {
                 final int[] colors = new int[(int) stream.length()];
                 for (int i = 0; i < colors.length; i++) {
                     colors[i] = stream.readInt();
                 }
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
 
     }

UF.IMAGEIO is reported for the snippet on line 48: image input stream 'stream' is used after it was closed on line 31.

Example 2

Copy
     public boolean canDecodeInput(ImageInputStream stream) {
         byte[] b = new byte[8];
         try {
             final long l = stream.length();
             if (l > 655335) {
                 return false;
             }
             stream.mark();
             stream.readFully(b);
             stream.reset();
         } catch (IOException e) {
             return false;
         }
 
         // Cast unsigned character constants prior to comparison
         return (b[0] == (byte) 'm' && b[1] == (byte) 'y' &&
                 b[2] == (byte) 'f' && b[3] == (byte) 'o' &&
                 b[4] == (byte) 'r' && b[5] == (byte) 'm' &&
                 b[6] == (byte) 'a' && b[7] == (byte) 't');
     }
 
     public void decode(Object data) throws IOException {
         final ImageInputStream stream = ImageIO.createImageInputStream(data);
         try {
             if (canDecodeInput(stream)) {
                 try {
                     final int[] colors = new int[(int) stream.length()];
                     for (int i = 0; i < colors.length; i++) {
                         colors[i] = stream.readInt();
                     }
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
         } finally {
             stream.close();
         }
     }

The snippet from the previous section is fixed. Method 'canDecodeInput' no longer closes the stream. Now it is closed by the 'decode' method, which is the method that opened the stream. In general, it is good coding practice to release a resource with the same method that originally allocated the resource.