Code Monkey home page Code Monkey logo

dd-plist's Introduction

com.dd.plist - A Java library for working with property lists

Build Status

This library enables your Java application to handle property lists of various formats. It is licensed under the terms of the MIT license.

Property lists are files used to store user settings and serialized objects. They originate from the NeXSTEP programming environment and are now a basic part of the Cocoa framework (OS X and iOS) as well as the GNUstep framework.

Features

  • Read / write property lists from / to files, streams or byte arrays
  • Convert between property list formats
  • Property list contents are provided as objects from the NeXTSTEP environment (NSDictionary, NSArray, NSString, etc.)
  • Serialize native java data structures to property list objects
  • Deserialize from property list objects to native java data structures

Supported formats

  • Cocoa XML
  • Cocoa Binary (v0)
  • Cocoa / NeXSTSTEP / GNUstep ASCII

Maven support

If you use Maven and want to include the library into your project you can use the following dependency.

<dependency>
  <groupId>com.googlecode.plist</groupId>
  <artifactId>dd-plist</artifactId>
  <version>1.28</version>
</dependency>

Help

The API documentation is included in the download but can also be browsed online: JavaDoc for com.dd.plist.

If you have further questions please post them on the GitHub issue tracker or in the Discussion forum plist-discuss on Google Groups.

Usage examples

Reading

Parsing can be done with the PropertyListParser class. You can feed the PropertyListParser with a File, an InputStream or a byte array. The parse method of the PropertyListParser will parse the input and give you a NSObject as result. Generally this is a NSDictionary but it can also be a NSArray.

Note: Property lists created by NSKeyedArchiver are not yet supported

You can then navigate the contents of the property lists using the various classes extending NSObject. These are modeled in such a way as to closely resemble the respective Cocoa classes.

You can also directly convert the contained NSObject objects into native Java objects with the NSObject.toJavaObject() method. Using this method you can avoid working with NSObject instances altogether.

Writing

You can create your own property list using the various constructors of the different NSObject classes. Or you can wrap existing native Java structures with the method NSObject.wrap(Object o). Just make sure that the root object of the property list is either a NSDictionary (can be created from objects of the type Map<String, Object>) or a NSArray (can be created from object arrays).

For building an XML property list you can then call the toXMLPropertyList method on the root object of your property list. It will give you a UTF-8 String containing the property list in XML format.

If you want to have the property list in binary format use the BinaryPropertyListWriter class. It can write the binary property list directly to a file or to an OutputStream.

When you directly want to save your property list to a file, you can also use the saveAsXML or saveAsBinary methods of the PropertyListParser class.

Converting

For converting a file into another format there exist convenience methods in the PropertyListParser class: convertToXML, convertToBinary, convertToASCII and convertToGnuStepASCII.

Code snippets

Reading

try {
  File file = new File("Info.plist");
  NSDictionary rootDict = (NSDictionary)PropertyListParser.parse(file);
  String name = rootDict.objectForKey("Name").toString();
  NSObject[] parameters = ((NSArray)rootDict.objectForKey("Parameters")).getArray();
  for(NSObject param:parameters) {
    if(param.getClass().equals(NSNumber.class)) {
      NSNumber num = (NSNumber)param;
      switch(num.type()) {
        case NSNumber.BOOLEAN : {
          boolean bool = num.boolValue();
          //...
          break;
        }
        case NSNumber.INTEGER : {
          long l = num.longValue();
          //or int i = num.intValue();
          //...
          break;
        }
        case NSNumber.REAL : {
          double d = num.doubleValue();
          //...
          break;
        }
      }
    }
    // else...
  }
} catch(Exception ex) {
  ex.printStackTrace();
}

On Android

Put your property list files into the project folder res/raw to mark them as resource files. Then you can create an InputStream for that resource and pass it to the PropertyListParser.

In this example your property list file is called properties.plist.

try {
  InputStream is = getResources().openRawResource(R.raw.properties);
  NSDictionary rootDict = (NSDictionary)PropertyListParser.parse(is);
  //Continue parsing...
} catch(Exception ex) {
  //Handle exceptions...
}

Writing

//Creating the root object
NSDictionary root = new NSDictionary();

//Creation of an array of the length 2
NSArray people = new NSArray(2);

//Creation of the first object to be stored in the array
NSDictionary person1 = new NSDictionary();
//The NSDictionary will automatically wrap strings, numbers and dates in the respective NSObject subclasses
person1.put("Name", "Peter"); //This will become a NSString
//Use the Java Calendar class to get a Date object
Calendar cal = Calendar.getInstance();
cal.set(2011, 1, 13, 9, 28);
person1.put("RegistrationDate", cal.getTime()); //This will become a NSDate
person1.put("Age", 23); //This will become a NSNumber
person1.put("Photo", new NSData(new File("peter.jpg")));

//Creation of the second object to be stored in the array
NSDictionary person2 = new NSDictionary();
person2.put("Name", "Lisa");
person2.put("Age", 42);
person2.put("RegistrationDate", new NSDate("2010-09-23T12:32:42Z"));
person2.put("Photo", new NSData(new File("lisa.jpg")));

//Put the objects into the array
people.setValue(0, person1);
people.setValue(1, person2);

//Put the array into the property list
root.put("People", people);

//Save the propery list
XMLPropertyListWriter.write(root, new File("people.plist"));

dd-plist's People

Contributors

3breadt avatar anhdht avatar auties00 avatar borewit avatar christopheplat avatar cornelcreanga avatar edwardbetts avatar hannes-angst avatar ingramz avatar jabagawee avatar jpstotz avatar lumley avatar mailniranjan avatar matvore avatar randall77 avatar ryu2 avatar sanjaymsh avatar solind avatar vanniktech avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dd-plist's Issues

ParseException errorOffset from ASCIIPropertyListParser::parseQuotedString is offset by the length of the quoted string

Reproduction steps:
Purposefully try to parse a badly quoted string. For example:

{
    "Hello" = "Worl\d";
}

Expected results:
The ParseException should point errorOffset to the \d, implied by the expression this.index + ex.getErrorOffset() at

throw new ParseException(ex.getMessage(), this.index + ex.getErrorOffset());
.

Actual results:
errorOffset points to an index out of bounds because it adds ex.getErrorOffset() (the error offset within the quoted string being parsed) to this.index (the end of the quoted string being parsed).

parse exception when parse NSNumber to float

I want to parse a valut to float type.
And the value is between 0~1,so, I use a float value to store this value.
But when the value is 1, it will throw an exception Cannot map NSNumber to float.
In fact, I can not make a Variable that both in type int and float.
So, I think maybe we should change the if condition in (NSObject: deserializeNumber) function

NSArray should implement List

When I try to convert a plist to json, the structure goes to weird when It parse NSArray, I think it's the reason that it doens't implement List

Various undeclared exceptions with fuzzed input

I started fuzzing this library with https://github.com/CodeIntelligenceTesting/jazzer after originally fuzzing another library and seeing there some crashed in this projects code.

To reproduce the errors use the PropertyListParser.parse method.

The fuzzing treats all non declared exceptions as failure.
One file triggers the exception in BinaryPropertyListParser.doParse. Since normally no one would catch this exception I included it since changing this to a PropertyListFormatException could be reasonable.

plist-crash.zip

Add location information to NSObject nodes

When parsing errors occur there is just a message that something did not work out. For users it is good to know where (filename, line, column). I know it is not always possible, e.g. when some binary plist is loaded via the network as an InputStream.
But in cases where a simple text file is parsed the likelyhood of this being inspected manually is a lot higher.

Would it be possible to add a 'location' field to NSObject that contains as much data as was available when creating it?

Not clonable

There doesn't appear to be an easy way to deep clone NSDictionary or NSObject

Parsing "Simple String File Format"

I'm parsing some InfoPlist.strings files that are in "simple string file format". For example:

/* A human readable InfoPlist.strings in simple strings format */

/* The bundle name */
"CFBundleName" = "(Base) Name";
/* The bundle display name */
"CFBundleDisplayName" = "(Base) DisplayName";
/* The short version */
"CFBundleShortVersionString" = "(Base) ShortVersion";

This is basically an ASCII NSDictionary, with an implied open/close curly brace. Is there any plan to support this? Alternatively, can you suggest any way I could augment the parser to support this? I'd be happy to submit a PR, if you can point me in the right direction.

The Simple Strings File Format is described here:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html

Gradle support

I currently use the Google Code Gradle dependency: compile 'com.googlecode.plist:dd-plist:1.16'
Any plans to add Gradle support to these GitHub releases of dd-plist?

License

By any chance is this an MIT license?

XMLPropertyListParser's getDocBuilder method need not be synchronized

https://github.com/3breadt/dd-plist/blob/master/src/main/java/com/dd/plist/XMLPropertyListParser.java#L91 is a synchronized method and is causing performance problems in our peak load testing.

This method was synchronized from the first commit. (ad6ecc4#diff-2c27b48e0134dc885800b0487859238aR71). I can understand that there are initializing the docBuilderFactory variable lazily so that was the reason that method was synchronized.

With the current code, (https://github.com/3breadt/dd-plist/blob/master/src/main/java/com/dd/plist/XMLPropertyListParser.java#L49), the factory is initialized eagerly. So, the method need not be synchronized now.

PropertyListParser.determineType can only detect UTF-8 BOM

The two methods com.dd.plist.PropertyListParser.determineType(InputStream, int) and com.dd.plist.PropertyListParser.determineType(byte[]) seem to be hard-coded to the UTF-8 BOM EF BB BF.

However the parser implementation of ASCIIPropertyListParser is for example also able to handle UTF-16 and UTF-32 files, but you will never get to that point if you try to read an UTF-16 ASCII file using one of the com.dd.plist.PropertyListParser.parse(..) method as because of the BOM the determineType(String) will not work correctly so that you end up with a PropertyListFormatException.

ASCIIPropertyListParser fails to read file that contains only comment

I encountered an empty plist file in old ASCII format:

/* Localized versions of Info.plist keys */

If you use dd-plist to parse such a file you end up with the following exception:

java.lang.ArrayIndexOutOfBoundsException: 45
	at com.dd.plist.ASCIIPropertyListParser.accept(ASCIIPropertyListParser.java:267)
	at com.dd.plist.ASCIIPropertyListParser.skipWhitespacesAndComments(ASCIIPropertyListParser.java:353)
	at com.dd.plist.ASCIIPropertyListParser.parse(ASCIIPropertyListParser.java:430)
	at com.dd.plist.ASCIIPropertyListParser.parse(ASCIIPropertyListParser.java:238)
	at com.dd.plist.ASCIIPropertyListParser.parse(ASCIIPropertyListParser.java:220)
	at com.dd.plist.ASCIIPropertyListParser.parse(ASCIIPropertyListParser.java:172)
	at com.dd.plist.ASCIIPropertyListParser.parse(ASCIIPropertyListParser.java:127)

If I interpret the description of such ASCII plist files correctly the file should be valid https://en.wikipedia.org/wiki/Property_list#NeXTSTEP

At least I would have expected a ParseException instead of an ArrayIndexOutOfBoundsException

BTW: I noticed that the Unit test
https://github.com/3breadt/dd-plist/blob/master/src/test/java/com/dd/plist/test/ParseTest.java#L149-L167
contains a lot of tests that are disabled as they miss the @Test annotation. Are those tests disabled intentionally or is this a bug?

Parse <real>nan</real> failed

<dict>
	<key>DownloadPercentComplete</key>
	<real>nan</real>
	<key>IsDownloaded</key>
	<true/>
	<key>ProductKey</key>
	<string>061-21545</string>
	<key>Status</key>
	<string>Idle</string>
</dict>

It is a MDM request from Apple Macbook, when I tried to parse it, an exception throws.

java.lang.IllegalArgumentException: The given string neither represents a double, an int nor a boolean value.
	at com.dd.plist.NSNumber.<init>(NSNumber.java:138)
	at com.dd.plist.XMLPropertyListParser.parseObject(XMLPropertyListParser.java:232)
	at com.dd.plist.XMLPropertyListParser.parseObject(XMLPropertyListParser.java:215)
	at com.dd.plist.XMLPropertyListParser.parseObject(XMLPropertyListParser.java:222)
	at com.dd.plist.XMLPropertyListParser.parseObject(XMLPropertyListParser.java:215)
	at com.dd.plist.XMLPropertyListParser.parse(XMLPropertyListParser.java:193)
	at com.dd.plist.XMLPropertyListParser.parse(XMLPropertyListParser.java:154)
	at com.dd.plist.PropertyListParser.parse(PropertyListParser.java:240)
	at com.dd.plist.PropertyListParser.parse(PropertyListParser.java:217)

NSData is not converted during toJavaObject

While converting a NSDictionary to a Java Object, the type NSData is not handled in deserialisation:

java.lang.IllegalArgumentException: Cannot process NSData
        at com.dd.plist.NSObject.toJavaObject(NSObject.java:319)
        at com.dd.plist.NSObject.deserializeObject(NSObject.java:356)
        at com.dd.plist.NSObject.toJavaObject(NSObject.java:316)
        at com.dd.plist.NSObject.toJavaObject(NSObject.java:184)

It seems that the NSObject.toJavaObject does not handles NSData case. Is this intended beharvior or is this case missing?

Library Version: 1.23

OutOfMemoryError when parsing incorrect binary plist files

Hello,

Our application has to deal with a lot of plist files that usually come from unknown sources. Sometimes it's corrupted files but with a correct header.

When I run BinaryPropertyListParser on the attached sample file it will produce an OutOfMemoryError which sometimes can crash the entire application. It would be great to improve the validation part and throw an exception if incorrect header or trailer is detected:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.dd.plist.BinaryPropertyListParser.doParse(BinaryPropertyListParser.java:135)
	at com.dd.plist.BinaryPropertyListParser.parse(BinaryPropertyListParser.java:87)
	at com.dd.plist.BinaryPropertyListParser.parse(BinaryPropertyListParser.java:154)
	at com.dd.plist.BinaryPropertyListParser.parse(BinaryPropertyListParser.java:166)
	at PlistIssue.main(PlistIssue.java:10)

Code to produce:
BinaryPropertyListParser.parse(new File("sample.plist"));

Version used: 1.20

Sample file: sample.plist.zip

Thanks.

Cyclic references in binary property list cause StackOverflowError

Part of Issue #74.

NSArray, NSDictionary and NSSet contain references to child objects. If a binary property list is malformed it may contain a reference to itself or a parent NSDictionary/Array/Set. This causes a StackOverflowException in the recursive BinaryPropertyListParser.parseObject method.

Such cyclic references should be detected and parsing be aborted.

How to make PList 'date' format key start with uppercase

The Apple mdm documentation shows that profile keys need to start with uppercase, such as RemovalDate (in "date" format).
However, plist does not support specifying the key to be converted to string.
So I have to use Jackson to convert it as follows:
POJO -> Map -> NSObject -> String

public class Profile {
    @JsonProperty("RemovalDate")
    private Date removalDate;
}

Not:
POJO -> NSObject -> String

However, the 'RemovalDate' in the Map is in String format, not in Date format. It caueses a conversion error.
I got:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>RemovalDate</key>
	<string>2023-08-07T07:53:18Z</string>
</dict>
</plist>

It shuold be <date>...</date>:

	<key>RemovalDate</key>
	<date>2023-08-07T07:53:18Z</date>

Is there any solution?
Thanks.

Parse error for ZipInputStream

For FileInputstream is OK
For zFile.getInputStream(entry), Sometimes normal and sometimes is not normal
input=zFile.getInputStream(entry)
PropertyListParser.parser(input)
error:
qq 20150708135558
for reason:
debug

/**
* Reads all bytes from an InputStream and stores them in an array, up to
* a maximum count.
*
* @param in The InputStream pointing to the data that should be stored in the array.
* @return An array containing all bytes that were read from the input stream.
* @throws java.io.IOException When an IO error while reading from the input stream.
*/
protected static byte[] readAll(InputStream in) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buf = new byte[512];
int read = 512;
while (read == 512) {
read = in.read(buf);
if(read != -1)
outputStream.write(buf, 0, read);
}
return outputStream.toByteArray();
}
Will the above code truncate the input stream ? then Information is not complete.
This problem corresponding to the app : http://os-ios.liqucn.com/rj/22709.shtml

Missing support for GNUstep base64 NSData

Modern GNUstep plists have a more efficient data encoding, and it is the <[ base64data ]> format:

GNUstep source that emits the format:
https://github.com/gnustep/libs-base/blob/753c907938c2a8c4d00cf0fbe01b7e0d020f0064/Source/NSPropertyList.m#L1951-L1956 (gnustep/libs-base@9aa5d4c)

GNUstep source that parses the format:
https://github.com/gnustep/libs-base/blob/753c907938c2a8c4d00cf0fbe01b7e0d020f0064/Source/NSPropertyList.m#L1202-L1277
(gnustep/libs-base@3f2fa9d)

(I wish there is a newer documentation page for the GNUstep format, but I have been unable to locate it.)

PropertyListParser.parse(InputStream) closes InputStream for TYPE_XML

The method PropertyListParser.parse(InputStream) is documented as

Parses a property list from an InputStream. This method does not close the specified input stream.

Unfortunately the underlying Xerxes XML parser does close the InputStream.

As a workaround I wrap the InputStream to ignore close():

      PropertyListParser.parse(
          new FilterInputStream(inputStream) {
            @Override public void close() {}
          });

I see two ways to fix this bug:

  1. Update the documentation to point out that the InputStream might be closed.
  2. Update the implementation to wrap the InputStream to ignore close().

Various undeclared exceptions with fuzzed input - Part 2

Follow up run with the changes for #73. I split up the files into folders by exception type since there are more files this time due to a longer run.

The slow folder contains files which can take up to several minutes before crashing. One file will not crash. Presumably those files trigger a long running loop somewhere.

plist-crash2.zip

NSData is not compliant with Apple's XML formatting

Apple split NSdata base 64 string into multiple lines not exceeding 76 characters (including 8 whitespace-per-tab indentation).

Also, the indentation of data should be in the same level of the <data> tag.

See the patch:

From 262dccf3c55d055f7bf333b7f8e79e64358a33ca Mon Sep 17 00:00:00 2001
Date: Sun, 11 Nov 2018 11:41:40 +0200
Subject: [PATCH] Make XML output more compliant with Apple's format: NSData -
 Lines of data must be 76 characters max (unless indentation is too deep), and
 data indentation equals <data> tag indentation. toXMLPropertyList() - append
 new line at the end of XML string.

---
 src/main/java/com/dd/plist/NSData.java   | 11 +++++++++--
 src/main/java/com/dd/plist/NSObject.java |  4 +++-
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/dd/plist/NSData.java b/src/main/java/com/dd/plist/NSData.java
index 6bad76a..2a12b35 100644
--- a/src/main/java/com/dd/plist/NSData.java
+++ b/src/main/java/com/dd/plist/NSData.java
@@ -145,8 +145,15 @@ public class NSData extends NSObject {
         xml.append("<data>");
         xml.append(NSObject.NEWLINE);
         String base64 = this.getBase64EncodedData();
-        for (String line : base64.split("\n")) {
-            this.indent(xml, level + 1);
+        int indent = (level > 8) ? 8 : level;
+        int maxLen = 76 - indent * 8;
+
+        // Lines of data must be 76 characters max (unless indentation is
+        // too deep), and data indentation equals <data> tag indentation,
+        // to be compliant with Apple's format:
+        for (String line :
+            base64.split("(?<=\\G.{"+maxLen+"})")) {
+            this.indent(xml, level);
             xml.append(line);
             xml.append(NSObject.NEWLINE);
         }
diff --git a/src/main/java/com/dd/plist/NSObject.java b/src/main/java/com/dd/plist/NSObject.java
index 5a450df..8eba28c 100644
--- a/src/main/java/com/dd/plist/NSObject.java
+++ b/src/main/java/com/dd/plist/NSObject.java
@@ -100,7 +100,9 @@ public abstract class NSObject implements Cloneable {
                 .append("<plist version=\"1.0\">")
                 .append(NSObject.NEWLINE);
         this.toXML(xml, 0);
-        xml.append(NSObject.NEWLINE).append("</plist>");
+        xml
+            .append(NSObject.NEWLINE).append("</plist>")
+            .append(NSObject.NEWLINE);
         return xml.toString();
     }
 
-- 
2.17.1 (Apple Git-112)

XMLPropertyListParser UnsupportedOperationException on Android

With the version 1.19 i have this crash on Android:

Caused by: java.lang.UnsupportedOperationException: This parser does not support specification "Unknown" version "0.0"
at javax.xml.parsers.DocumentBuilderFactory.setXIncludeAware(DocumentBuilderFactory.java:471)
at com.dd.plist.XMLPropertyListParser.(XMLPropertyListParser.java:67)

Base64 Decoder Incorrectly Detects Data Value as Zip Data

Hello, and thank you for maintaining this library.

I recently encountered an issue parsing a plist contained in an iOS app. iOS creates a CodeResources file in XML Plist format, which has dictionary with an entry for each file contained in the app. The keys are the names of the files, and the values are another dictionary with file hash data for the file. For example:

...
<key>files2</key>
<dict>
	...
	<key>Base.lproj/Main.storyboardc/MainController.nib</key>
	<dict>
		<key>hash</key>
		<data>
		H4su9pQU+nD/V4ppfPwJGSNcjv8=
		</data>
		<key>hash2</key>
		<data>
		8MhWcI9M79dqHp4tTbcUBwJCeu63sn/ekQKdGAVQLUM=
		</data>
	</dict> 
	...

The data element is parsed by the Base64 encoder included in the library, which attempts to detect whether the data is in gzip format, and if so, pipes the output through a GZipInputStream. It detects whether the data is in gzip format by checking to see if the first two bytes are equal to the gzip magic number. Unfortunately, given that the hash data is effectively just a random byte array, there is a 1 in 2^16 chance that the first two bytes of the hash will happen to be equal to the gzip magic number. The "H4su9pQU+nD/V4ppfPwJGSNcjv8=" hash value above exhibits that behavior. The decoded hexdump of that byte array is

1f 8b 2e f6 94 14 fa 70 ff 57 8a 69 7c fc 09 19
23 5c 8e ff

As you can see, the first two bytes happen to be the little-endian representation of the gzip magic number: 0x8b1f. However, this isn't actual zip data, and it results in the following error:

java.util.zip.ZipException: Unsupported compression method
	at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:169)
	at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:79)
	at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:91)
	at com.dd.plist.Base64.decode(Base64.java:1315)
	at com.dd.plist.Base64.decode(Base64.java:1266)
	at com.dd.plist.NSData.<init>(NSData.java:60)
	at com.dd.plist.XMLPropertyListParser.parseObject(XMLPropertyListParser.java:224)
	at com.dd.plist.XMLPropertyListParser.parseObject(XMLPropertyListParser.java:203)
	at com.dd.plist.XMLPropertyListParser.parseObject(XMLPropertyListParser.java:203)
	at com.dd.plist.XMLPropertyListParser.parse(XMLPropertyListParser.java:181)
	at com.dd.plist.XMLPropertyListParser.parse(XMLPropertyListParser.java:142)
	at com.dd.plist.PropertyListParser.parse(PropertyListParser.java:242)
	at com.dd.plist.PropertyListParser.parse(PropertyListParser.java:219)

I'd like to be able to disable the automatic zip decoding of data values, but it's not possible via the current APIs. I'd like to propose either disabling this behavior by default -- this is the default behavior for write, and should probably be symmetrical with read. Alternatively, we could plumb in a way to disable this behavior by adding an overloaded version of the PropertyListParser.parse(...) methods and similarly the XXXPropertyListParser implementations and the NSData(String) constructor. Yet another alternate implementation would be to do further examination of the byte array structure to determine if it contains a well formed zip header data, though this would only reduce the likelyhood of the issue. If you would be willing to entertain any of these fixes, or suggest an alternate, I would be happy to submit a pull request with the implementation.

Thank you again for maintaining this library. I'd be happy to lend a hand.

NSNumber parser fails for "+infinity" and "-infinity"

Using version 1.26, downloaded from Maven Central.

The NSNumber parser throws an exception when it encounters the values "+infinity" or "-infinity". This can be verified with the following code snippet:

public static void main(String[] args) {
    var a = new NSNumber("3");
    try {
        var b = new NSNumber("+infinity");
    } catch (Exception e) {
        System.out.println(e);
    }
    try {
        var c = new NSNumber("-infinity");
    } catch (Exception e) {
        System.out.println(e);
    }
}

Output:

java.lang.IllegalArgumentException: The given string neither represents a double, an int nor a boolean value.
java.lang.IllegalArgumentException: The given string neither represents a double, an int nor a boolean value.

This causes XMLPropertyListParser.parse(...) to fail when the input contains either <real>+infinity</real> or <real>-infinity</real> but I believe both of these are valid values.

String format

Hi!

I'm parsing binary plist and get something like that:

        <dict>
            <key>$class</key>
            <string>7d0ffffffe3</string>
            <key>NS.bytes</key>
            <data>
                9jz+91kt1WmqSyfQEvv/2eDtiF0=
            </data>
        </dict>

What is a <string> format?
<data>is a base64 format.

Improper (or missing) handling of resources (FileInputStream/FileOutputStream)

The parser / writer methods receiving a File object, creates streams and never / improperly close them, causing resource leaks.

For instance:
BinaryPropertyListParser - The FileInputStream is never closed.
BinaryPropertyListWriter - The FileOutputStream is closed, but with no try\finally block.

These open files can cause all sort of weird behaviors, such as running out of file descriptors, or inability to move/delete the file after reading/writing.

It is required (since it is Java 1.5) to use the try-finally pattern to close the streams:

    InputStream is = null;
    try {
         is = new FileInputStream(file);
         // read the file
    } finally {
         if (is != null) is.close();
    }

NSArray to typed array with polymorphism

My problem is the following:

public class PayloadDto {
    private List<PayloadContentDto> payloadContent = new ArrayList<>();
}

public class PayloadContentDto {
    protected String payloadType;
}

public class A extends PayloadContentDto {
   private String aProperty;
}

public class B extends PayloadContentDto {
   private String bProperty;
}

public PayloadDto getDtoFromPListByteArray(byte[] content) {
...
    NSObject parse = PropertyListParser.parse(content);
    PayloadDto payloadDto = parse.toJavaObject(PayloadDto.class);
...
}

When calling getDtoFromPListByteArray the payloadContent list contains these types:

[
class PayloadContentDto(payloadType="aType"),
class PayloadContentDto(payloadType="bType"),
]

instead of these expected ones:

[
   class A(payloadType="aType", aProperty="a's property"),
   class B(payloadType="bType", bProperty="b's property"),
]

Is there any way to achive the proper class convertion?

Something like Jackson annotations

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "payloadType", visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = A.class, name = "aType"),
        @JsonSubTypes.Type(value = B.class, name = "bType"),
})

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.