eclipse-archived / smarthome

Eclipse SmartHome™ project
https://www.eclipse.org/smarthome/
Eclipse Public License 2.0
861 stars 787 forks source link

MapDB Storage deserialization broken #6877

Closed maggu2810 closed 5 years ago

maggu2810 commented 5 years ago

On serialization the MapDB storage contains that part of code:

String concatValue = valueTypeName + TYPE_SEPARATOR + valueAsString;

On deserialization this part of code is used:

String[] concatValue = json.split(TYPE_SEPARATOR);
String valueTypeName = concatValue[0];
String valueAsString = concatValue[1];

IMHO this is wrong. We should use the limit parameter for the split that we do not want more then two parts. Using the current approach, I assume the deserialization of an JSON string (value as string) that looks like:

{
  "key1": "@@@",
  "key2": "@@@",
  "key3": "@@@"
}

will be splitted as well.

maggu2810 commented 5 years ago

Very simple example to reproduce:

public static void main(final String[] args) throws IOException {
    final Path tmpDir = Files.createTempDirectory(null);
    tmpDir.toFile().deleteOnExit();
    final Path userdata = tmpDir.resolve("userdata");
    userdata.toFile().mkdir();
    System.setProperty(ConfigConstants.USERDATA_DIR_PROG_ARGUMENT, userdata.toString());

    final MapDbStorageService storageService = new MapDbStorageService();
    storageService.activate();
    try {
        DeletableStorage<TestDTO> storage = storageService.getStorage("dummy");
        try {
            final TestDTO test = new TestDTO();
            test.var0 = "@@@";
            storage.put("t1", test);
            final TestDTO testRestored = storage.get("t1");
            if (testRestored != null) {
                System.out.println(test.var0 + " => " + testRestored.var0);
            } else {
                System.err.println("deserialization failed");
            }
        } finally {
            storage.delete();
        }
    } finally {
        storageService.deactivate();
    }
}

As you can seen valueAsString is not valid JSON.

The simple fix would be to change json.split(TYPE_SEPARATOR) to json.split(TYPE_SEPARATOR, 2).

After that