0
\$\begingroup\$

I'm practicing saving and reading serializable objects when a friend told me serializable objects have no use in real life, that I'd better focus on JSON or XML to serialize my objects when I came across this situation:

I want to preload some FileFilters to use them in a JFileChooser dialog and I want these Filefilters to have more complicated behaviour than just file extension.

The code works fine but I've read there could be some security issues saving executable code and reading it later. Is it true? Can they be avoided?

I had to implement my own interface of Predicate due to the fact that Predicate is not Serializable.

import java.io.File;
import java.io.Serializable;

public interface MyPredicate extends Serializable {
  boolean isValid(File file);
}

This is the class that defines how the filters are going to be set (It's called List despite the fact that uses internally a Map just in case implementation changes).

import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


public class FileFilterList implements Serializable {
  private Map<String, MyPredicate> filters;

  public FileFilterList() {
    this.filters = new HashMap<>();
  }

  public FileFilterList addFilter(String string, MyPredicate predicate) {
    this.filters.put(string, predicate);
    return this;
  }

  public Iterator<Map.Entry<String, MyPredicate>> getIterator() {
    return this.filters.entrySet().iterator();
  }
}

In this little program I save a list of filters in a file

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SaveFileFilter {
  public static void main(String[] args) throws IOException {
    FileFilterList filterList = new FileFilterList();
    filterList
            .addFilter("txt, Text files", f -> f.isDirectory() || f.getName().endsWith(".txt"))
            .addFilter("Big txt, Big txt files (>1Kb)", f -> f.isDirectory() || (f.getName().endsWith(".txt") || f.length() > 1024))
            .addFilter("Small txt, Small txt file (<=1Kb)", f -> f.isDirectory() || (f.getName().endsWith(".txt") || f.length() <= 1024));
    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("filters.obj"))) {
      oos.writeObject(filterList);
    } catch (IOException ioe) {
      System.err.println("Sorry, there wa a problem saving filters");
      ioe.printStackTrace();
      throw ioe;
    }
  }
}

And this would be the main program that get the preset file filter list:

import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.io.*;

public class FileFilterUse {
  public static void main(String[] args) throws IOException, ClassNotFoundException {
    JFileChooser fileChooser = new JFileChooser();
    try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("filters.obj"))) {
      FileFilterList filterList = (FileFilterList) ois.readObject();
      filterList.getIterator().forEachRemaining(
              (entry) -> fileChooser.addChoosableFileFilter(new FileFilter() {
                @Override
                public boolean accept(File f) {
                  return entry.getValue().isValid(f);
                }

                @Override
                public String getDescription() {
                  return entry.getKey();
                }
              }));
      fileChooser.showOpenDialog(null);
    } catch (IOException ioe) {
      System.err.println("There was a problem reading filters file");
      ioe.printStackTrace();
      throw ioe;
    } catch (ClassNotFoundException cnf) {
      System.err.println("File format is not correct");
      cnf.printStackTrace();
      throw cnf;
    }
  }
}

Every java file has a package line.

I guess it is not possible to achive this serializing objects to JSON or XML, is it?

By the way, any comment about the code would be very appreciated.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ I don't think you are really asking for a code review. Rather, I think this is a general question about 1) whether serialization of lambdas presents a security issue, and 2) if there is a way to achieve the equivalent of a serialized lambda using JSON or XML. You should ask it on StackOverflow. \$\endgroup\$
    – Stephen C
    May 2 at 4:03
  • \$\begingroup\$ For future reference variable names like MyPredicate make the code seem hypothetical. The code must be real working code from a project. \$\endgroup\$
    – pacmaninbw
    May 2 at 14:04
  • \$\begingroup\$ See Holger's answer in stackoverflow.com/questions/38018415/… esp. the parts about being unreliable and having security issues. Generally, consider this a bad idea™. \$\endgroup\$
    – mtj
    May 4 at 5:21
0
\$\begingroup\$

I'm going to answer my own question. Never do this!. I have just tried saving a new Filefilter object with this filter:

.addFilter("Delete files, Delete all files",f->f.delete());

And when selected, it deletes all the files in the current directory.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.