Author: toad
Date: 2005-11-12 00:41:46 +0000 (Sat, 12 Nov 2005)
New Revision: 7533

Modified:
   trunk/freenet/src/freenet/client/Metadata.java
   trunk/freenet/src/freenet/client/StandardOnionFECCodec.java
   trunk/freenet/src/freenet/node/Version.java
   trunk/freenet/src/freenet/support/BucketTools.java
   trunk/freenet/src/freenet/support/FileLoggerHook.java
   trunk/freenet/src/freenet/support/compress/GzipCompressor.java
Log:
170:
Fix more possible fd leaks.

Modified: trunk/freenet/src/freenet/client/Metadata.java
===================================================================
--- trunk/freenet/src/freenet/client/Metadata.java      2005-11-12 00:21:27 UTC 
(rev 7532)
+++ trunk/freenet/src/freenet/client/Metadata.java      2005-11-12 00:41:46 UTC 
(rev 7533)
@@ -5,6 +5,7 @@
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -45,7 +46,15 @@
         * @throws IOException If we could not read the metadata from the 
bucket.
         */
        public static Metadata construct(Bucket data) throws 
MetadataParseException, IOException {
-               return new Metadata(data);
+               InputStream is = data.getInputStream();
+               Metadata m;
+               try {
+                       DataInputStream dis = new DataInputStream(is);
+                       m = new Metadata(dis, false, data.size());
+               } finally {
+                       is.close();
+               }
+               return m;
        }

        /** Parse some metadata from a byte[]. 
@@ -54,12 +63,6 @@
                this(new DataInputStream(new ByteArrayInputStream(data)), 
false, data.length);
        }

-       /** Parse some metadata from a Bucket.
-        * @throws IOException If the data is incomplete, or something wierd 
happens. */
-       public Metadata(Bucket meta) throws IOException {
-               this(new DataInputStream(meta.getInputStream()), false, 
meta.size());
-       }
-
        /** Parse some metadata from a DataInputStream
         * @throws IOException If an I/O error occurs, or the data is 
incomplete. */
        public Metadata(DataInputStream dis, boolean 
acceptZipInternalRedirects, long length) throws IOException, 
MetadataParseException {

Modified: trunk/freenet/src/freenet/client/StandardOnionFECCodec.java
===================================================================
--- trunk/freenet/src/freenet/client/StandardOnionFECCodec.java 2005-11-12 
00:21:27 UTC (rev 7532)
+++ trunk/freenet/src/freenet/client/StandardOnionFECCodec.java 2005-11-12 
00:41:46 UTC (rev 7533)
@@ -108,101 +108,130 @@
        }

        public void realDecode(SplitfileBlock[] dataBlockStatus, 
SplitfileBlock[] checkBlockStatus, int blockLength, BucketFactory bf) throws 
IOException {
-               Logger.minor(this, "Doing decode: "+dataBlockStatus.length+" 
data blocks, "+checkBlockStatus.length+" check blocks, block length 
"+blockLength+" with "+this, new Exception("debug"));
-               if(dataBlockStatus.length + checkBlockStatus.length != n)
+               Logger.minor(this, "Doing decode: " + dataBlockStatus.length
+                               + " data blocks, " + checkBlockStatus.length
+                               + " check blocks, block length " + blockLength 
+ " with "
+                               + this, new Exception("debug"));
+               if (dataBlockStatus.length + checkBlockStatus.length != n)
                        throw new IllegalArgumentException();
-               if(dataBlockStatus.length != k)
+               if (dataBlockStatus.length != k)
                        throw new IllegalArgumentException();
                Buffer[] packets = new Buffer[k];
                Bucket[] buckets = new Bucket[n];
                DataInputStream[] readers = new DataInputStream[n];
                OutputStream[] writers = new OutputStream[k];
                int numberToDecode = 0; // can be less than n-k
-               
-               byte[] realBuffer = new byte[k * STRIPE_SIZE];
-               
-               int[] packetIndexes = new int[k];
-               for(int i=0;i<packetIndexes.length;i++)
-                       packetIndexes[i] = -1;

-               int idx = 0;
-               
-               for(int i=0;i<k;i++)
-                       packets[i] = new Buffer(realBuffer, i*STRIPE_SIZE, 
STRIPE_SIZE);
-               
-               for(int i=0;i<dataBlockStatus.length;i++) {
-                       buckets[i] = dataBlockStatus[i].getData();
-                       if(buckets[i] == null) {
-                               buckets[i] = bf.makeBucket(blockLength);
-                               writers[i] = buckets[i].getOutputStream();
-                               Logger.minor(this, "writers["+i+"] != null");
-                               readers[i] = null;
-                               numberToDecode++;
-                       } else {
-                               long sz = buckets[i].size();
-                               if(sz < blockLength) {
-                                       if(i != dataBlockStatus.length-1)
-                                               throw new 
IllegalArgumentException("All buckets except the last must be the full size but 
data bucket "+i+" of "+dataBlockStatus.length+" ("+dataBlockStatus[i]+") is 
"+sz+" not "+blockLength);
-                                       if(sz < blockLength)
-                                               buckets[i] = pad(buckets[i], 
blockLength, bf, (int) sz);
-                                       else throw new 
IllegalArgumentException("Too big: "+sz+" bigger than "+blockLength);
+               try {
+
+                       byte[] realBuffer = new byte[k * STRIPE_SIZE];
+
+                       int[] packetIndexes = new int[k];
+                       for (int i = 0; i < packetIndexes.length; i++)
+                               packetIndexes[i] = -1;
+
+                       int idx = 0;
+
+                       for (int i = 0; i < k; i++)
+                               packets[i] = new Buffer(realBuffer, i * 
STRIPE_SIZE,
+                                               STRIPE_SIZE);
+
+                       for (int i = 0; i < dataBlockStatus.length; i++) {
+                               buckets[i] = dataBlockStatus[i].getData();
+                               if (buckets[i] == null) {
+                                       buckets[i] = bf.makeBucket(blockLength);
+                                       writers[i] = 
buckets[i].getOutputStream();
+                                       Logger.minor(this, "writers[" + i + "] 
!= null");
+                                       readers[i] = null;
+                                       numberToDecode++;
+                               } else {
+                                       long sz = buckets[i].size();
+                                       if (sz < blockLength) {
+                                               if (i != dataBlockStatus.length 
- 1)
+                                                       throw new 
IllegalArgumentException(
+                                                                       "All 
buckets except the last must be the full size but data bucket "
+                                                                               
        + i + " of "
+                                                                               
        + dataBlockStatus.length + " ("
+                                                                               
        + dataBlockStatus[i] + ") is " + sz
+                                                                               
        + " not " + blockLength);
+                                               if (sz < blockLength)
+                                                       buckets[i] = 
pad(buckets[i], blockLength, bf,
+                                                                       (int) 
sz);
+                                               else
+                                                       throw new 
IllegalArgumentException("Too big: " + sz
+                                                                       + " 
bigger than " + blockLength);
+                                       }
+                                       Logger.minor(this, "writers[" + i
+                                                       + "] = null (already 
filled)");
+                                       writers[i] = null;
+                                       readers[i] = new 
DataInputStream(buckets[i]
+                                                       .getInputStream());
+                                       packetIndexes[idx++] = i;
                                }
-                               Logger.minor(this, "writers["+i+"] = null 
(already filled)");
-                               writers[i] = null;
-                               readers[i] = new 
DataInputStream(buckets[i].getInputStream());
-                               packetIndexes[idx++] = i;
                        }
-               }
-               for(int i=0;i<checkBlockStatus.length;i++) {
-                       buckets[i+k] = checkBlockStatus[i].getData();
-                       if(buckets[i+k] == null) {
-                               readers[i+k] = null;
-                       } else {
-                               readers[i+k] = new 
DataInputStream(buckets[i+k].getInputStream());
-                               if(idx < k)
-                                       packetIndexes[idx++] = i+k;
+                       for (int i = 0; i < checkBlockStatus.length; i++) {
+                               buckets[i + k] = checkBlockStatus[i].getData();
+                               if (buckets[i + k] == null) {
+                                       readers[i + k] = null;
+                               } else {
+                                       readers[i + k] = new 
DataInputStream(buckets[i + k]
+                                                       .getInputStream());
+                                       if (idx < k)
+                                               packetIndexes[idx++] = i + k;
+                               }
                        }
-               }
-               
-               if(idx < k)
-                       throw new IllegalArgumentException("Must have at least 
k packets");
-               
-               for(int i=0;i<packetIndexes.length;i++)
-                       Logger.minor(this, "["+i+"] = "+packetIndexes[i]);
-               
-               if(numberToDecode > 0) {
-                       // Do the (striped) decode
-                       for(int 
offset=0;offset<blockLength;offset+=STRIPE_SIZE) {
-                               // Read the data in first
-                               for(int i=0;i<k;i++) {
-                                       int x = packetIndexes[i];
-                                       readers[x].readFully(realBuffer, 
i*STRIPE_SIZE, STRIPE_SIZE);
+
+                       if (idx < k)
+                               throw new IllegalArgumentException(
+                                               "Must have at least k packets");
+
+                       for (int i = 0; i < packetIndexes.length; i++)
+                               Logger.minor(this, "[" + i + "] = " + 
packetIndexes[i]);
+
+                       if (numberToDecode > 0) {
+                               // Do the (striped) decode
+                               for (int offset = 0; offset < blockLength; 
offset += STRIPE_SIZE) {
+                                       // Read the data in first
+                                       for (int i = 0; i < k; i++) {
+                                               int x = packetIndexes[i];
+                                               
readers[x].readFully(realBuffer, i * STRIPE_SIZE,
+                                                               STRIPE_SIZE);
+                                       }
+                                       // Do the decode
+                                       // Not shuffled
+                                       int[] disposableIndexes = new 
int[packetIndexes.length];
+                                       System.arraycopy(packetIndexes, 0, 
disposableIndexes, 0,
+                                                       packetIndexes.length);
+                                       code.decode(packets, disposableIndexes);
+                                       // packets now contains an array of 
decoded blocks, in order
+                                       // Write the data out
+                                       for (int i = 0; i < k; i++) {
+                                               if (writers[i] != null)
+                                                       
writers[i].write(realBuffer, i * STRIPE_SIZE,
+                                                                       
STRIPE_SIZE);
+                                       }
                                }
-                               // Do the decode
-                               // Not shuffled
-                               int[] disposableIndexes = new 
int[packetIndexes.length];
-                               System.arraycopy(packetIndexes, 0, 
disposableIndexes, 0, packetIndexes.length);
-                               code.decode(packets, disposableIndexes);
-                               // packets now contains an array of decoded 
blocks, in order
-                               // Write the data out
-                               for(int i=0;i<k;i++) {
-                                       if(writers[i] != null)
-                                               writers[i].write(realBuffer, 
i*STRIPE_SIZE, STRIPE_SIZE);
-                               }
                        }
+
+               } finally {
+
+                       for (int i = 0; i < k; i++) {
+                               if (writers[i] != null)
+                                       writers[i].close();
+                       }
+                       for (int i = 0; i < n; i++) {
+                               if (readers[i] != null)
+                                       readers[i].close();
+                       }
+
                }
-               for(int i=0;i<k;i++) {
-                       if(writers[i] != null) writers[i].close();
-               }
-               for(int i=0;i<n;i++) {
-                       if(readers[i] != null) readers[i].close();
-               }
                // Set new buckets only after have a successful decode.
                // Note that the last data bucket will be overwritten padded.
-               for(int i=0;i<dataBlockStatus.length;i++) {
+               for (int i = 0; i < dataBlockStatus.length; i++) {
                        Bucket data = buckets[i];
-                       if(data.size() != blockLength)
-                               throw new IllegalStateException("Block "+i+": 
"+data+" : "+dataBlockStatus[i]+" length "+data.size());
+                       if (data.size() != blockLength)
+                               throw new IllegalStateException("Block " + i + 
": " + data
+                                               + " : " + dataBlockStatus[i] + 
" length " + data.size());
                        dataBlockStatus[i].setData(data);
                }
        }
@@ -234,84 +263,111 @@
        /**
         * Do the actual encode.
         */
-       private void realEncode(SplitfileBlock[] dataBlockStatus, 
SplitfileBlock[] checkBlockStatus, int blockLength, BucketFactory bf) throws 
IOException {
-               System.err.println("************* Encoding 
"+dataBlockStatus.length+" -> "+checkBlockStatus.length+" *************");
-               Logger.minor(this, "Doing encode: "+dataBlockStatus.length+" 
data blocks, "+checkBlockStatus.length+" check blocks, block length 
"+blockLength+" with "+this);
-               if(dataBlockStatus.length + checkBlockStatus.length != n)
+       private void realEncode(SplitfileBlock[] dataBlockStatus,
+                       SplitfileBlock[] checkBlockStatus, int blockLength, 
BucketFactory bf)
+                       throws IOException {
+               System.err.println("************* Encoding " + 
dataBlockStatus.length
+                               + " -> " + checkBlockStatus.length + " 
*************");
+               Logger.minor(this, "Doing encode: " + dataBlockStatus.length
+                               + " data blocks, " + checkBlockStatus.length
+                               + " check blocks, block length " + blockLength 
+ " with "
+                               + this);
+               if (dataBlockStatus.length + checkBlockStatus.length != n)
                        throw new IllegalArgumentException();
-               if(dataBlockStatus.length != k)
+               if (dataBlockStatus.length != k)
                        throw new IllegalArgumentException();
                Buffer[] dataPackets = new Buffer[k];
-               Buffer[] checkPackets = new Buffer[n-k];
+               Buffer[] checkPackets = new Buffer[n - k];
                Bucket[] buckets = new Bucket[n];
                DataInputStream[] readers = new DataInputStream[k];
-               OutputStream[] writers = new OutputStream[n-k];
-               int[] toEncode = new int[n-k];
-               int numberToEncode = 0; // can be less than n-k
-               
-               byte[] realBuffer = new byte[n * STRIPE_SIZE];
+               OutputStream[] writers = new OutputStream[n - k];

-               for(int i=0;i<k;i++)
-                       dataPackets[i] = new Buffer(realBuffer, i*STRIPE_SIZE, 
STRIPE_SIZE);
-               for(int i=0;i<n-k;i++)
-                       checkPackets[i] = new Buffer(realBuffer, 
(i+k)*STRIPE_SIZE, STRIPE_SIZE);
+               try {

-               for(int i=0;i<dataBlockStatus.length;i++) {
-                       buckets[i] = dataBlockStatus[i].getData();
-                       long sz = buckets[i].size();
-                       if(sz < blockLength) {
-                               if(i != dataBlockStatus.length-1)
-                                       throw new IllegalArgumentException("All 
buckets except the last must be the full size");
-                               if(sz < blockLength)
-                                       buckets[i] = pad(buckets[i], 
blockLength, bf, (int) sz);
-                               else throw new IllegalArgumentException("Too 
big: "+sz+" bigger than "+blockLength);
+                       int[] toEncode = new int[n - k];
+                       int numberToEncode = 0; // can be less than n-k
+
+                       byte[] realBuffer = new byte[n * STRIPE_SIZE];
+
+                       for (int i = 0; i < k; i++)
+                               dataPackets[i] = new Buffer(realBuffer, i * 
STRIPE_SIZE,
+                                               STRIPE_SIZE);
+                       for (int i = 0; i < n - k; i++)
+                               checkPackets[i] = new Buffer(realBuffer, (i + 
k) * STRIPE_SIZE,
+                                               STRIPE_SIZE);
+
+                       for (int i = 0; i < dataBlockStatus.length; i++) {
+                               buckets[i] = dataBlockStatus[i].getData();
+                               long sz = buckets[i].size();
+                               if (sz < blockLength) {
+                                       if (i != dataBlockStatus.length - 1)
+                                               throw new 
IllegalArgumentException(
+                                                               "All buckets 
except the last must be the full size");
+                                       if (sz < blockLength)
+                                               buckets[i] = pad(buckets[i], 
blockLength, bf, (int) sz);
+                                       else
+                                               throw new 
IllegalArgumentException("Too big: " + sz
+                                                               + " bigger than 
" + blockLength);
+                               }
+                               readers[i] = new 
DataInputStream(buckets[i].getInputStream());
                        }
-                       readers[i] = new 
DataInputStream(buckets[i].getInputStream());
-               }
-               
-               for(int i=0;i<checkBlockStatus.length;i++) {
-                       buckets[i+k] = checkBlockStatus[i].getData();
-                       if(buckets[i+k] == null) {
-                               buckets[i+k] = bf.makeBucket(blockLength);
-                               writers[i] = buckets[i+k].getOutputStream();
-                               toEncode[numberToEncode++] = i+k;
-                       } else {
-                               writers[i] = null;
+
+                       for (int i = 0; i < checkBlockStatus.length; i++) {
+                               buckets[i + k] = checkBlockStatus[i].getData();
+                               if (buckets[i + k] == null) {
+                                       buckets[i + k] = 
bf.makeBucket(blockLength);
+                                       writers[i] = buckets[i + 
k].getOutputStream();
+                                       toEncode[numberToEncode++] = i + k;
+                               } else {
+                                       writers[i] = null;
+                               }
                        }
-               }
-               
-               if(numberToEncode > 0) {
-                       // Do the (striped) decode
-                       for(int 
offset=0;offset<blockLength;offset+=STRIPE_SIZE) {
-                               // Read the data in first
-                               for(int i=0;i<k;i++) {
-                                       readers[i].readFully(realBuffer, 
i*STRIPE_SIZE, STRIPE_SIZE);
+
+                       if (numberToEncode > 0) {
+                               // Do the (striped) decode
+                               for (int offset = 0; offset < blockLength; 
offset += STRIPE_SIZE) {
+                                       // Read the data in first
+                                       for (int i = 0; i < k; i++) {
+                                               
readers[i].readFully(realBuffer, i * STRIPE_SIZE,
+                                                               STRIPE_SIZE);
+                                       }
+                                       // Do the encode
+                                       // Not shuffled
+                                       long startTime = 
System.currentTimeMillis();
+                                       code.encode(dataPackets, checkPackets, 
toEncode);
+                                       long endTime = 
System.currentTimeMillis();
+                                       Logger.minor(this, "Stripe encode took "
+                                                       + (endTime - startTime) 
+ " ms for k=" + k + ", n="
+                                                       + n + ", stripeSize=" + 
STRIPE_SIZE);
+                                       // packets now contains an array of 
decoded blocks, in order
+                                       // Write the data out
+                                       for (int i = k; i < n; i++) {
+                                               if (writers[i - k] != null)
+                                                       writers[i - 
k].write(realBuffer, i * STRIPE_SIZE,
+                                                                       
STRIPE_SIZE);
+                                       }
                                }
-                               // Do the encode
-                               // Not shuffled
-                               long startTime = System.currentTimeMillis();
-                               code.encode(dataPackets, checkPackets, 
toEncode);
-                               long endTime = System.currentTimeMillis();
-                               Logger.minor(this, "Stripe encode took 
"+(endTime-startTime)+" ms for k="+k+", n="+n+", stripeSize="+STRIPE_SIZE);
-                               // packets now contains an array of decoded 
blocks, in order
-                               // Write the data out
-                               for(int i=k;i<n;i++) {
-                                       if(writers[i-k] != null)
-                                               writers[i-k].write(realBuffer, 
i*STRIPE_SIZE, STRIPE_SIZE);
-                               }
                        }
+
+               } finally {
+
+                       for (int i = 0; i < k; i++)
+                               if (readers[i] != null)
+                                       readers[i].close();
+                       for (int i = 0; i < n - k; i++)
+                               if (writers[i] != null)
+                                       writers[i].close();
+
                }
-               for(int i=0;i<k;i++)
-                       if(readers[i] != null) readers[i].close();
-               for(int i=0;i<n-k;i++)
-                       if(writers[i] != null) writers[i].close();
                // Set new buckets only after have a successful decode.
-               for(int i=0;i<checkBlockStatus.length;i++) {
-                       Bucket data = buckets[i+k];
-                       if(data == null) throw new NullPointerException();
+               for (int i = 0; i < checkBlockStatus.length; i++) {
+                       Bucket data = buckets[i + k];
+                       if (data == null)
+                               throw new NullPointerException();
                        checkBlockStatus[i].setData(data);
                }
-               System.err.println("************* Encoded 
"+dataBlockStatus.length+" -> "+checkBlockStatus.length+" *************");
+               System.err.println("************* Encoded " + 
dataBlockStatus.length
+                               + " -> " + checkBlockStatus.length + " 
*************");
        }

        private Bucket pad(Bucket oldData, int blockLength, BucketFactory bf, 
int l) throws IOException {

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2005-11-12 00:21:27 UTC (rev 
7532)
+++ trunk/freenet/src/freenet/node/Version.java 2005-11-12 00:41:46 UTC (rev 
7533)
@@ -20,10 +20,10 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       public static final int buildNumber = 169;
+       public static final int buildNumber = 170;

        /** Oldest build of Fred we will talk to */
-       public static final int lastGoodBuild = 169;
+       public static final int lastGoodBuild = 170;

        /** The highest reported build of fred */
        public static int highestSeenBuild = buildNumber;

Modified: trunk/freenet/src/freenet/support/BucketTools.java
===================================================================
--- trunk/freenet/src/freenet/support/BucketTools.java  2005-11-12 00:21:27 UTC 
(rev 7532)
+++ trunk/freenet/src/freenet/support/BucketTools.java  2005-11-12 00:41:46 UTC 
(rev 7533)
@@ -68,58 +68,63 @@
                out.close();
        }

-       public final static void paddedCopy(
-               Bucket from,
-               Bucket to,
-               long nBytes,
-               int blockSize)
-               throws IOException {
+       public final static void paddedCopy(Bucket from, Bucket to, long nBytes,
+                       int blockSize) throws IOException {

                if (nBytes > blockSize) {
                        throw new IllegalArgumentException("nBytes > 
blockSize");
                }

-               OutputStream out = to.getOutputStream();
-               byte[] buffer = new byte[16384];
-               InputStream in = from.getInputStream();
+               OutputStream out = null;
+               InputStream in = null;

-               long count = 0;
-               while (count != nBytes) {
-                       long nRequired = nBytes - count;
-                       if (nRequired > buffer.length) {
-                               nRequired = buffer.length;
-                       }
-                       long nRead = in.read(buffer, 0, (int) nRequired);
-                       if (nRead == -1) {
-                               throw new IOException("Not enough data in 
source bucket.");
-                       }
-                       out.write(buffer, 0, (int) nRead);
-                       count += nRead;
-               }
+               try {

-               if (count < blockSize) {
-                       // hmmm... better to just allocate a new buffer
-                       // instead of explicitly zeroing the old one?
-                       // Zero pad to blockSize
-                       long padLength = buffer.length;
-                       if (padLength > blockSize - nBytes) {
-                               padLength = blockSize - nBytes;
-                       }
-                       for (int i = 0; i < padLength; i++) {
-                               buffer[i] = 0;
-                       }
+                       out = to.getOutputStream();
+                       byte[] buffer = new byte[16384];
+                       in = from.getInputStream();

-                       while (count != blockSize) {
-                               long nRequired = blockSize - count;
-                               if (blockSize - count > buffer.length) {
+                       long count = 0;
+                       while (count != nBytes) {
+                               long nRequired = nBytes - count;
+                               if (nRequired > buffer.length) {
                                        nRequired = buffer.length;
                                }
-                               out.write(buffer, 0, (int) nRequired);
-                               count += nRequired;
+                               long nRead = in.read(buffer, 0, (int) 
nRequired);
+                               if (nRead == -1) {
+                                       throw new IOException("Not enough data 
in source bucket.");
+                               }
+                               out.write(buffer, 0, (int) nRead);
+                               count += nRead;
                        }
+
+                       if (count < blockSize) {
+                               // hmmm... better to just allocate a new buffer
+                               // instead of explicitly zeroing the old one?
+                               // Zero pad to blockSize
+                               long padLength = buffer.length;
+                               if (padLength > blockSize - nBytes) {
+                                       padLength = blockSize - nBytes;
+                               }
+                               for (int i = 0; i < padLength; i++) {
+                                       buffer[i] = 0;
+                               }
+
+                               while (count != blockSize) {
+                                       long nRequired = blockSize - count;
+                                       if (blockSize - count > buffer.length) {
+                                               nRequired = buffer.length;
+                                       }
+                                       out.write(buffer, 0, (int) nRequired);
+                                       count += nRequired;
+                               }
+                       }
+               } finally {
+                       if (in != null)
+                               in.close();
+                       if (out != null)
+                               out.close();
                }
-               in.close();
-               out.close();
        }

        public static class BucketFactoryWrapper implements BucketFactory {
@@ -307,9 +312,12 @@
                if(size > Integer.MAX_VALUE) throw new OutOfMemoryError();
                byte[] data = new byte[(int)size];
                InputStream is = bucket.getInputStream();
-               DataInputStream dis = new DataInputStream(is);
-               dis.readFully(data);
-               dis.close();
+               try {
+                       DataInputStream dis = new DataInputStream(is);
+                       dis.readFully(data);
+               } finally {
+                       is.close();
+               }
                return data;
        }

@@ -323,9 +331,10 @@
        }

        public static byte[] hash(Bucket data) throws IOException {
+               InputStream is = null;
                try {
                        MessageDigest md = MessageDigest.getInstance("SHA-256");
-                       InputStream is = data.getInputStream();
+                       is = data.getInputStream();
                        long bucketLength = data.size();
                        long bytesRead = 0;
                        byte[] buf = new byte[4096];
@@ -343,6 +352,8 @@
                } catch (NoSuchAlgorithmException e) {
                        Logger.error(BucketTools.class, "No such digest: 
SHA-256 !!");
                        throw new Error("No such digest: SHA-256 !!");
+               } finally {
+                       if(is != null) is.close();
                }
        }

@@ -352,23 +363,26 @@
                if(truncateLength == 0) return;
                if(truncateLength < 0) truncateLength = Long.MAX_VALUE;
                InputStream is = decodedData.getInputStream();
-               byte[] buf = new byte[4096];
-               long moved = 0;
-               while(moved < truncateLength) {
-                       // DO NOT move the (int) inside the Math.min()! big 
numbers truncate to negative numbers.
-                       int bytes = (int) Math.min(buf.length, truncateLength - 
moved);
-                       if(bytes <= 0)
-                               throw new 
IllegalStateException("bytes="+bytes+", truncateLength="+truncateLength+", 
moved="+moved);
-                       bytes = is.read(buf, 0, bytes);
-                       if(bytes <= 0) {
-                               if(truncateLength == Long.MAX_VALUE)
-                                       break;
-                               throw new IOException("Could not move required 
quantity of data: "+bytes);
+               try {
+                       byte[] buf = new byte[4096];
+                       long moved = 0;
+                       while(moved < truncateLength) {
+                               // DO NOT move the (int) inside the Math.min()! 
big numbers truncate to negative numbers.
+                               int bytes = (int) Math.min(buf.length, 
truncateLength - moved);
+                               if(bytes <= 0)
+                                       throw new 
IllegalStateException("bytes="+bytes+", truncateLength="+truncateLength+", 
moved="+moved);
+                               bytes = is.read(buf, 0, bytes);
+                               if(bytes <= 0) {
+                                       if(truncateLength == Long.MAX_VALUE)
+                                               break;
+                                       throw new IOException("Could not move 
required quantity of data: "+bytes);
+                               }
+                               os.write(buf, 0, bytes);
+                               moved += bytes;
                        }
-                       os.write(buf, 0, bytes);
-                       moved += bytes;
+               } finally {
+                       is.close();
                }
-               is.close();
        }

        /**
@@ -392,20 +406,26 @@
                if(length % splitSize > 0) bucketCount++;
                Bucket[] buckets = new Bucket[bucketCount];
                InputStream is = origData.getInputStream();
-               DataInputStream dis = new DataInputStream(is);
-               long remainingLength = length;
-               byte[] buf = new byte[splitSize];
-               for(int i=0;i<bucketCount;i++) {
-                       int len = (int) Math.min(splitSize, remainingLength);
-                       Bucket bucket = bf.makeBucket(len);
-                       buckets[i] = bucket;
-                       dis.readFully(buf, 0, len);
-                       remainingLength -= len;
-                       OutputStream os = bucket.getOutputStream();
-                       os.write(buf, 0, len);
-                       os.close();
+               try {
+                       DataInputStream dis = new DataInputStream(is);
+                       long remainingLength = length;
+                       byte[] buf = new byte[splitSize];
+                       for(int i=0;i<bucketCount;i++) {
+                               int len = (int) Math.min(splitSize, 
remainingLength);
+                               Bucket bucket = bf.makeBucket(len);
+                               buckets[i] = bucket;
+                               dis.readFully(buf, 0, len);
+                               remainingLength -= len;
+                               OutputStream os = bucket.getOutputStream();
+                               try {
+                                       os.write(buf, 0, len);
+                               } finally {
+                                       os.close();
+                               }
+                       }
+               } finally {
+                       is.close();
                }
-               dis.close();
                return buckets;
        }
 }

Modified: trunk/freenet/src/freenet/support/FileLoggerHook.java
===================================================================
--- trunk/freenet/src/freenet/support/FileLoggerHook.java       2005-11-12 
00:21:27 UTC (rev 7532)
+++ trunk/freenet/src/freenet/support/FileLoggerHook.java       2005-11-12 
00:41:46 UTC (rev 7533)
@@ -629,7 +629,12 @@
                        // Convert the stack trace to a string.
                        ByteArrayOutputStream bos = new 
ByteArrayOutputStream(350);
                        PrintWriter bpw = new PrintWriter(bos);
-                       e.printStackTrace(bpw);
+                       try {
+                               e.printStackTrace(bpw);
+                       } catch (NullPointerException ex) {
+                               log(this, getClass(), "Got evil 
NPE-in-stack-trace bug", null, ERROR);
+                               bpw.println("[ evil NPE-in-stack-trace 
triggered ]");
+                       }
                        bpw.flush();

                        sb.append(bos.toString());

Modified: trunk/freenet/src/freenet/support/compress/GzipCompressor.java
===================================================================
--- trunk/freenet/src/freenet/support/compress/GzipCompressor.java      
2005-11-12 00:21:27 UTC (rev 7532)
+++ trunk/freenet/src/freenet/support/compress/GzipCompressor.java      
2005-11-12 00:41:46 UTC (rev 7533)
@@ -17,24 +17,32 @@

        public Bucket compress(Bucket data, BucketFactory bf, long maxLength) 
throws IOException, CompressionOutputSizeException {
                Bucket output = bf.makeBucket(-1);
-               InputStream is = data.getInputStream();
-               OutputStream os = output.getOutputStream();
-               GZIPOutputStream gos = new GZIPOutputStream(os);
-               long written = 0;
-               byte[] buffer = new byte[4096];
-               while(true) {
-                       int l = (int) Math.min(buffer.length, maxLength - 
written);
-                       int x = is.read(buffer, 0, buffer.length);
-                       if(l < x) {
-                               throw new CompressionOutputSizeException();
+               InputStream is = null;
+               OutputStream os = null;
+               GZIPOutputStream gos = null;
+               try {
+                       is = data.getInputStream();
+                       os = output.getOutputStream();
+                       gos = new GZIPOutputStream(os);
+                       long written = 0;
+                       byte[] buffer = new byte[4096];
+                       while(true) {
+                               int l = (int) Math.min(buffer.length, maxLength 
- written);
+                               int x = is.read(buffer, 0, buffer.length);
+                               if(l < x) {
+                                       throw new 
CompressionOutputSizeException();
+                               }
+                               if(x <= -1) break;
+                               if(x == 0) throw new IOException("Returned zero 
from read()");
+                               gos.write(buffer, 0, x);
+                               written += x;
                        }
-                       if(x <= -1) break;
-                       if(x == 0) throw new IOException("Returned zero from 
read()");
-                       gos.write(buffer, 0, x);
-                       written += x;
+                       gos.flush();
+               } finally {
+                       if(is != null) is.close();
+                       if(gos != null) gos.close();
+                       else if(os != null) os.close();
                }
-               is.close();
-               gos.close();
                return output;
        }



Reply via email to