In the below code I have used BufferedReader and InputStreamReader inside the try and but veracode complains the security as Improper Resource Shutdown or Release (CWE ID 404)
try (final BufferedReader bsr = new BufferedReader(new InputStreamReader(Myutils.class.getClassLoader()
.getResourceAsStream("fileName.txt")))) {
String currentLine;
while ((currentLine = bsr.readLine()) != null) {
// doing some operations
}
} catch (final Exception e) {
throw new IllegalStateException("exception occurres");
}
}
Also in another class I am extending HttpServletRequestWrapper
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {
private BufferedReader reader;
#Override
public BufferedReader getReader() throws IOException {
if (null == this.reader) {
this.reader = new BufferedReader(new InputStreamReader(getInputStream(), getCharacterEncoding()));
}
return this.reader;
}
}
here in this.reader line veracode giving the Improper Resource Shutdown or Release (CWE ID 404). I think the framework (tomcat/spring) is handling this. But not sure why veracode saying this.
InputStream will be left open if an exception is thrown after opening the InputStream but before assigning the BufferedReader. In the example you've provided this can only happen if the InputStreamReader constructor throws an exception. To avoid this you can use the following code:
try (final InputStream is = Example.class.getClassLoader().getResourceAsStream("filename.txt");
final InputStreamReader inputStreamReader = new InputStreamReader(is);
final BufferedReader bsr = new BufferedReader(inputStreamReader);) {
Related
I have a problem with Interceptor in SpringBoot I am trying to read the body in a request at preHandle() method.
public class LogInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
System.out.println("Error reading the request body...");
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
System.out.println("Error closing bufferedReader...");
}
}
}
String body = stringBuilder.toString();
System.out.println("--Body--"+body);
}
}
This code print body correctly but when I try to made a POST petition with Postman I receive the following error.
I/O error while reading input message; nested exception is java.io.IOException: Stream closed
If I do the same petition witouth this code the petition works correctly.
Could anyone help to me ? Or said a better solution to intercept body ?
I have following test program to read a file from HDFS.
public class FileReader {
public static final String NAMENODE_IP = "172.32.17.209";
public static final String FILE_PATH = "/notice.html";
public static void main(String[] args) throws MalformedURLException,
IOException {
String url = "hdfs://" + NAMENODE_IP + FILE_PATH;
InputStream is = new URL(url).openStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();
while(line != null) {
System.out.println(line);
line = br.readLine();
}
}
}
It is giving java.net.MalformedURLException
Exception in thread "main" java.net.MalformedURLException: unknown protocol: hdfs
at java.net.URL.<init>(URL.java:592)
at java.net.URL.<init>(URL.java:482)
at java.net.URL.<init>(URL.java:431)
at in.ksharma.hdfs.FileReader.main(FileReader.java:29)
Register Hadoop's Url handler. Standard Url handler won't know how to handle hdfs:// scheme.
Try this:
public static void main(String[] args) throws MalformedURLException,
IOException {
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
String url = "hdfs://" + NAMENODE_IP + FILE_PATH;
InputStream is = new URL(url).openStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();
while(line != null) {
System.out.println(line);
line = br.readLine();
}
}
I get the same issue while writing a Java application for reading from hdfs on hadoop 2.6.
My solution is : Add
hadoop-2.X/share/hadoop/hdfs/hadoop-hdfs-2.X.jar to your classpath.
In our case we had to combine it with other answer:
https://stackoverflow.com/a/21118824/1549135
So firstly in our HDFS setup class (Scala code):
val hadoopConfig: Configuration = new Configuration()
hadoopConfig.set("fs.hdfs.impl", classOf[DistributedFileSystem].getName)
hadoopConfig.set("fs.file.impl", classOf[LocalFileSystem].getName)
And later, like in accepted answer:
https://stackoverflow.com/a/25971334/1549135
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory)
Try(new URL(path))
Side note:
We already had:
"org.apache.hadoop" % "hadoop-hdfs" % "2.8.0" in our dependencies and it did not help.
So Im trying to get a basic reader going so that I can work with files for an authentication process later.
The problem I am having is that I get an error on my BufferedReader line that causes my try function to throw an illegal start exception and it wont run. Eclipse is showing me an error on the semicolon at the end of the br declaration and says I should be putting a { but I can't see why that would be neccessary.
BufferedReader br = new BufferedReader(new FileReader("Assign4.txt"));
I have tried to put that there but it breaks the entire try section.
package main;
import java.io.*;
public class file_interface
{
BufferedWriter wr = new BufferedWriter(new FileWriter("target.txt"));
BufferedReader br = new BufferedReader(new FileReader("Assign4.txt"));
try
{
int count = 1;
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null)
{
sb.append(count++);
sb.append(line);
sb.append("\n");
wr.write(line);
line = br.readLine();
}
}
catch (IOException e)
{
System.err.println("Error: " + e);
}
finally
{
br.close();
wr.close();
}
}
}
Any Java sentence must be inside a method. This code is not.
The fact that BufferedWriter wr = new BufferedWriter(new FileWriter("target.txt")); works is because is declared as a default field (no scope mark was given) in your file_interface class and is being initialized. It is similar to do:
public class file_interface {
BufferedWriter wr;
public file_interface() {
wr = new BufferedWriter(new FileWriter("target.txt"));
}
}
Just create a method to hold your logic:
public class file_interface {
public void foo() {
//your code goes here...
//now this is not a field but a variable in the method
BufferedWriter wr = new BufferedWriter(new FileWriter("target.txt"));
BufferedReader br = new BufferedReader(new FileReader("Assign4.txt"));
//rest of your code...
try {
//...
} catch (...) {
//...
}
//...
}
}
Then just call your method in your client class. For example, a class with the main method:
public class AMainClass {
public static void main(String[] args) {
file_interface fi = new file_interface();
fi.foo();
}
}
Another example, a class with another method:
public class SomeClientClass {
public void bar() {
file_interface fi = new file_interface();
fi.foo();
}
}
Note: You should also follow the Java Naming Conventions, so you should rename file_interface by FileInterface or even MyFileUtil since interface word sounds more to declare an, uhm, interface.
so Im trying to write this class which is going to parse a file and read commands from it.
I want the ctor to just open the stream and do nothing else.
while I parse the file in other class methods.
But I'm getting a nullpointerexception when I try to read the file in the methods I made.
help will be apprecated :D
public class Parser {
private BufferedReader _input;
private String _command;
public Parser(String filename) throws FileNotFoundException {
FileInputStream fstream = new FileInputStream(filename);
BufferedReader _input = new BufferedReader(new InputStreamReader(fstream));
}
public boolean hasMoreCommands() throws IOException {
String line;
if ( (line = _input.readLine()) != null) {
return true;
} else {
_input.close();
return false;
}
}
public void advance() throws IOException {
String line;
do {
line = _input.readLine().trim();
} while (line.equals("") || line.substring(0,2).equals(COMMENT_SIGN));
String[] splittedLine = line.split(COMMENT_SIGN);
_command = splittedLine[0];
_command = _command.replace(" ", "");
}
my main for testing it + the exception trace
public static void main(String[] args) throws IOException {
Parser input = null;
input = new Parser("D:\\test.asm");
System.out.println( input.hasMoreCommands());
}
Exception in thread "main" java.lang.NullPointerException
at nand6.Parser.hasMoreCommands(Parser.java:40)
at nand6.Parser.main(Parser.java:116)
Have a look at this snippet of code
public Parser(String filename) throws FileNotFoundException {
FileInputStream fstream = new FileInputStream(_filename);
BufferedReader _input = new BufferedReader(new InputStreamReader(fstream));
}
Change
BufferedReader _input = new BufferedReader(new InputStreamReader(fstream));
to
_input = new BufferedReader(new InputStreamReader(fstream));
Your mistake : You are creating another local variable of type *BufferedReader _input* hence your class level variable is still null resulting in a NullPointerException
You are basically defining a new BufferedReader object called "_input" inside your constructor. You think that after calling the constructor you instantiate "_input" outside the constructor. But you are not, it refers to null. That's why you are getting NullPointerException. Just remove "BufferedReader" in front of "_input" inside your constructor, in order to refer to correct object.
I was working normally in eclipse when I got bugged by a resource leak warning in both return values inside the try block in this method:
#Override
public boolean isValid(File file) throws IOException
{
BufferedReader reader = null;
try
{
reader = new BufferedReader(new FileReader(file));
String line;
while((line = reader.readLine()) != null)
{
line = line.trim();
if(line.isEmpty())
continue;
if(line.startsWith("#") == false)
return false;
if(line.startsWith("#MLProperties"))
return true;
}
}
finally
{
try{reader.close();}catch(Exception e){}
}
return false;
}
I don't understand how it would cause resource leak since I'm declaring the reader variable outside the try scope, adding a resource inside the try block and closing it in a finally block using an other try...catch to ignore exceptions and a NullPointerException if reader is null for some reason...
From what I know, finally blocks are always executed when leaving the try...catch structure, so returning a value inside the try block would still execute the finally block before exiting the method...
This can be easily proved by:
public static String test()
{
String x = "a";
try
{
x = "b";
System.out.println("try block");
return x;
}
finally
{
System.out.println("finally block");
}
}
public static void main(String[] args)
{
System.out.println("calling test()");
String ret = test();
System.out.println("test() returned "+ret);
}
It result in:
calling test()
try block
finally block
test() returned b
Knowing all this, why is eclipse telling me Resource leak: 'reader' is not closed at this location if I'm closing it in my finally block?
Answer
I would just add to this answer that he's correct, if new BufferedReader throws an exception, an instance of FileReader would be open upon destruction by garbage collector because it wouldn't be assigned to any variable and the finally block would not close it because reader would be null.
This is how I fixed this possible leak:
#Override
public boolean isValid(File file) throws IOException
{
FileReader fileReader = null;
BufferedReader reader = null;
try
{
fileReader = new FileReader(file);
reader = new BufferedReader(fileReader);
String line;
while((line = reader.readLine()) != null)
{
line = line.trim();
if(line.isEmpty())
continue;
if(line.startsWith("#") == false)
return false;
if(line.startsWith("#MLProperties"))
return true;
}
}
finally
{
try{reader.close();}catch(Exception e){}
try{fileReader.close();}catch(Exception ee){}
}
return false;
}
There is technically a path for which the BufferedReader would not be closed: if reader.close() would throw an exception, because you catch the exception and do nothing with it. This can be verified by adding reader.close() again in your catch block:
} finally
{
try {
reader.close();
} catch (Exception e) {
reader.close();
}
}
Or by removing the try/catch in the finally:
} finally
{
reader.close();
}
This will make the warnings disappear.
Of course, it doesn't help you. If reader.close() is failing, then calling it again does not make sense. The thing is, the compiler is not smart enough to handle this. So the only sensible thing you can do is to add a #SuppressWarnings("resource") to the method.
Edit If you are using Java 7, what you can/should do is using try-with-resources functionality. This will get the warnings right, and makes you code simpler, saving you a finally block:
public boolean isValid(File file) throws IOException
{
try(BufferedReader reader = new BufferedReader(new FileReader(file)))
{
String line;
while ((line = reader.readLine()) != null)
{
line = line.trim();
if (line.isEmpty())
continue;
if (line.startsWith("#") == false)
return false;
if (line.startsWith("#MLProperties"))
return true;
}
}
return false;
}
If the BufferedReader constructor throws an exception (e.g. out of memory), you will have FileReader leaked.
//If this line throws an exception, then neither the try block
//nor the finally block will execute.
//That is a good thing, since reader would be null.
BufferedReader reader = new BufferedReader(new FileReader(aFileName));
try {
//Any exception in the try block will cause the finally block to execute
String line = null;
while ( (line = reader.readLine()) != null ) {
//process the line...
}
}
finally {
//The reader object will never be null here.
//This finally is only entered after the try block is
//entered. But, it's NOT POSSIBLE to enter the try block
//with a null reader object.
reader.close();
}
Since close() can throw an exception (why oh why did they design it that way...) I tend to use a double try
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
try {
// do stuff with reader
} finally {
reader.close();
}
} catch(IOException e) {
// handle exceptions
}
Since this idiom eliminates the try/catch within the finally block it may be enough to keep Eclipse happy.
new BufferedReader(...) can't itself throw an IOException but technically this could still leak the FileReader if the BufferedReader constructor throws a RuntimeException or Error.