libimobiledevice / libplist

A library to handle Apple Property List format in binary or XML
https://libimobiledevice.org
GNU Lesser General Public License v2.1
532 stars 304 forks source link

`plistutil` fails to convert NextSTEP and single-line plists to binary #207

Closed L1ghtmann closed 1 year ago

L1ghtmann commented 2 years ago

First off, I want to thank you for this project and libimobiledevice in general. Time and time again I find myself using a library or tool from libimobiledevice and your hard work is greatly appreciated!


The issue: Recently I added support for plistutil in an xml/plist->bplist wrapper script I was working on and noticed that it failed to convert a few of the files I threw at it during my testing.

The files that failed included: Swift.xspec (NextSTEP):

(
        {
                Identifier = "com.apple.xcode.tools.swift.compiler";
                Type = Compiler;
                Class = "XCCompilerSpecificationSwift";
                Name = "Swift Compiler";
                Description = "Compiles Swift source code into object files.";
                Vendor = Apple;
                Version = "2.0";
                IsAbstract = NO;
                "ShowInCompilerSelectionPopup" = NO;
                InputFileGroupings = (
                        tool,
                );
                InputFileTypes = (
                        "sourcecode.swift",
                );
                "OptionConditionFlavors" = (
                        arch,
                        sdk,
                );
                "BuiltinJambaseRuleName" = ProcessSwift;
                ExecPath = "$(SWIFT_EXEC)";
                Architectures = (
                        "x86_64",
                        i386,
                        arm64,
                        armv7,
                        armv7s,
                );
                SynthesizeBuildRule = YES;
                ExecDescription = "Compile Swift source files";
                ProgressDescription = "Compiling Swift source files";
                RuleName = "Compile $(InputFile)";
                CommandOutputParser = "XCSwiftCommandOutputParser";
                "SupportsGenerateAssemblyFile" = YES;
                "SupportsGeneratePreprocessedFile" = NO;
                Options = (
                        {
                                Name = "SWIFT_EXEC";
                                Type = Path;
                                DefaultValue = swiftc;
                        },
                        {
                                Name = "SWIFT_LIBRARIES_ONLY";
                                Type = Boolean;
                                DefaultValue = NO;
                                CommandLineArgs = {
                                        YES = (
                                                "-parse-as-library",
                                        );
                                        NO = ();
                                };
                        },
                        {
                                Name = "SWIFT_ENABLE_INCREMENTAL_COMPILATION";
                                Type = Boolean;
                                DefaultValue = YES;
                                CommandLineArgs = {
                                        YES = (
                                                "-incremental",
                                        );
                                        NO = ();
                                };
                        },

                        // Hidden build setting to control whether parallel -WMO is enabled.
                        {
                                Name = "SWIFT_USE_PARALLEL_WHOLE_MODULE_OPTIMIZATION";
                                Type = Boolean;
                                DefaultValue = YES;
                        },

                        // Legacy WMO setting, still supported but this has been replaced by a unified SWIFT_OPTIMIZATION_LEVEL.
                        {
                                Name = "SWIFT_WHOLE_MODULE_OPTIMIZATION";
                                Type = Boolean;
                                DefaultValue = NO;
                                CommandLineArgs = {
                                        YES = (
                                                "-whole-module-optimization",
                                        );
                                        NO = ();
                                };
                        },
                        {
                                Name = "SWIFT_LIBRARY_PATH";
                                Type = Path;
                                DefaultValue = "";
                        },
                        {
                                Name = "SWIFT_MODULE_NAME";
                                Type = String;
                                DefaultValue = "$(PRODUCT_MODULE_NAME)";
                                CommandLineArgs = (
                                        "-module-name",
                                        "$(value)",
                                );
                        },
            {
                Name = "SWIFT_OBJC_BRIDGING_HEADER";
                Type = String;
                DefaultValue = "";
                                Category = "Code Generation";
                DisplayName = "Objective-C Bridging Header";
                                Description = "Path to the header defining the Objective-C interfaces to be exposed in Swift. [SWIFT_OBJC_BRIDGING_HEADER]";
            },
                        {
                                Name = "SWIFT_OBJC_INTERFACE_HEADER_NAME";
                                Type = String;
                                DefaultValue = "$(SWIFT_MODULE_NAME)-Swift.h";
                                Category = "Code Generation";
                                DisplayName = "Objective-C Generated Interface Header Name";
                                Description = "Name to use for the header that is generated by the Swift compiler for use in #import statements in Objective-C. [SWIFT_OBJC_INTERFACE_HEADER_NAME]";
                        },
            {
                Name = "SWIFT_INSTALL_OBJC_HEADER";
                Type = Boolean;
                DefaultValue = "YES";
                                Category = "Code Generation";
                DisplayName = "Install Objective-C Compatibility Header";
                                Description = "For frameworks, install the Objective-C compatibility header describing bridged Swift classes into the PUBLIC_HEADERS_FOLDER_PATH so they may be accessed from Objective-C code using the framework. Defaults to YES. [SWIFT_INSTALL_OBJC_HEADER]";
            },
                        {
                                Name = "SWIFT_OPTIMIZATION_LEVEL";
                                Type = Enumeration;
                                AllowedValues = (
                                        "-Onone",
                                        "-O",
                                        "-Owholemodule",
                                );
                                DefaultValue = "-O";
                                CommandLineArgs = {
                                        "-Onone" = "-Onone";
                                        "-O" = "$(__SWIFT_OPTIMIZE_OPTION_WITHOUT_SAFETY_CHECKS_$(SWIFT_DISABLE_SAFETY_CHECKS))";
                                        "-Owholemodule" = ("$(__SWIFT_OPTIMIZE_OPTION_WITHOUT_SAFETY_CHECKS_$(SWIFT_DISABLE_SAFETY_CHECKS))", "-whole-module-optimization");
                                        "<<otherwise>>" = "$(value)";
                                };
                                Category = "Code Generation";
                                DisplayName = "Optimization Level";
                        },
                        {
                                Name = "SWIFT_DISABLE_SAFETY_CHECKS";
                                Type = Boolean;
                                DefaultValue = NO;
                                Category = "Code Generation";
                                DisplayName = "Disable Safety Checks";
                                Description = "Disable runtime safety checks when optimizing. [SWIFT_DISABLE_SAFETY_CHECKS]";
                        },
                        {
                                Name = "__SWIFT_OPTIMIZE_OPTION_WITHOUT_SAFETY_CHECKS_YES";
                                Type = String;
                                DefaultValue = "-Ounchecked";
                        },
                        {
                                Name = "__SWIFT_OPTIMIZE_OPTION_WITHOUT_SAFETY_CHECKS_NO";
                                Type = String;
                                DefaultValue = "-O";
                        },
                        {
                                Name = "SWIFT_STDLIB";
                                Type = String;
                                DefaultValue = "swiftCore";
                        },
                        {
                                Name = "SWIFT_INCLUDE_PATHS";
                                Type = PathList;
                                "FlattenRecursiveSearchPathsInValue" = Yes;
                                Category = "Search Paths";
                DisplayName = "Import Paths";
                Description = "A list of paths to be searched by the Swift compiler for additional Swift modules. [SWIFT_INCLUDE_PATHS]";
                        },
                        {
                                Name = "FRAMEWORK_SEARCH_PATHS";
                                Type = PathList;
                                "FlattenRecursiveSearchPathsInValue" = Yes;
                        },
                        {
                                Name = "OTHER_SWIFT_FLAGS";
                                Type = StringList;
                                CommandLineArgs = (
                                        "$(value)",
                                );
                                Category = "Custom Flags";
                DisplayName = "Other Swift Flags";
                Description = "A list of additional flags to pass to the Swift compiler. [OTHER_SWIFT_FLAGS]";
                        },
                        {
                                Name = SDKROOT;
                                Type = Path;
                                CommandLineFlag = "-sdk";
                        },
            {
                Name = "SWIFT_DEPLOYMENT_TARGET";
                Type = String;
                DefaultValue = "$($(DEPLOYMENT_TARGET_SETTING_NAME))";
                CommandLineArgs = ( "-target", "$(CURRENT_ARCH)-apple-$(SWIFT_PLATFORM_TARGET_PREFIX)$(value)" );
            },
                        {
                                Name = "GCC_GENERATE_DEBUGGING_SYMBOLS";
                                Type = Boolean;
                                CommandLineArgs = {
                                        YES = (
                                                "-g",
                                        );
                                        NO = ();
                                };
                        },
                        {
                                Name = "CLANG_MODULE_CACHE_PATH";
                                Type = Path;
                                CommandLineFlag = "-module-cache-path";
                        },
            {
                Name = "SWIFT_SERIALIZE_DEBUGGING_OPTIONS";
                Type = Boolean;
                DefaultValue = YES;
                                CommandLineArgs = {
                                        YES = ( "-Xfrontend", "-serialize-debugging-options" );
                                        NO  = ();
                                };
            },
                        {
                                Name = "SWIFT_ENABLE_APP_EXTENSION";
                                Type = Boolean;
                                DefaultValue = "$(APPLICATION_EXTENSION_API_ONLY)";
                                CommandLineArgs = {
                                        YES = ( "-application-extension" );
                                        NO  = ();
                                };
                                // NOTE: These arguments are passed to *Clang*.
                                AdditionalLinkerArgs = {
                                        YES = ( "-fapplication-extension" );
                                        NO = ();
                                };
                        },
                        {
                                Name = "SWIFT_MIGRATE_CODE";
                                Type = Boolean;
                                CommandLineArgs = {
                                        YES = (
                        "-update-code",
                                        );
                                        NO = ();
                                };
                        },

                        {
                                Name = "CLANG_COVERAGE_MAPPING";
                                Type = Boolean;
                                DefaultValue = NO;
                                AdditionalLinkerArgs = {
                                        NO = ();
                                        YES = (
                                                "-fprofile-instr-generate",
                                        );
                                };
                                CommandLineArgs = {
                                        YES = (
                                                "-profile-coverage-mapping",
                                                "-profile-generate",
                                        );
                                        NO = ();
                                };
                        },

            // Generate bitcode options
            {
                Name = "SWIFT_BITCODE_GENERATION_MODE";
                Type = Enumeration;
                AllowedValues = (
                    marker,
                    bitcode,
                );
                DefaultValue = "$(BITCODE_GENERATION_MODE)";
                                Architectures = ( arm64, armv7, armv7s, armv7k );
                                Condition = "$(ENABLE_BITCODE) == YES";
                                CommandLineArgs = {
                    marker = (
                        "-embed-bitcode-marker",
                    );
                                        bitcode = (
                                                "-embed-bitcode",
                                        );
                                };
                // Not visible in the build settings editor
            },

            // Testing options
            {
                Name = "SWIFT_ENABLE_TESTABILITY";
                Type = Boolean;
                DefaultValue = "$(ENABLE_TESTABILITY)";
                                CommandLineArgs = {
                                        YES = (
                                                "-enable-testing",
                                        );
                                        NO = ();
                                };
                // Not visible in the build settings editor
            },

                );
        },
)

Localizable.strings (Also NextSTEP (?))

"Applications" = "Applications";
"System Applications" = "System Applications";
"User Applications" = "User Applications";
"Hidden Applications" = "Hidden Applications";

Vinyl.plist (Single-line format (?))

{ Filter = { Bundles = ( "com.apple.springboard" ); }; }

Note: I'm not 100% on the format classifications I gave to the files above.

The errors: Swift.xspec: ERROR: Could not parse plist data (-3) Localizable.strings: ERROR: Could not parse plist data (-3) Vinyl.plist: ERROR: Failed to convert plist data (-1)

Upon running plistutil -i filename.extension -f bin -o filename.extension with plistutil version plistutil 2.2.0-88-g7d2cdc6-dirty on Linux (WSL).

nikias commented 2 years ago

This doesn't work because NextSTEP plist format is not supported by libplist. I am planning to add support for it (like I recently added JSON support) but I don't know when it will be finished.

L1ghtmann commented 2 years ago

Gotcha. Appreciate the response!

L1ghtmann commented 1 year ago

Tested and confirmed working on all aforementioned test cases. You're the man, Nikias. Thanks so much for your continued work on this awesome project!

Fixed by https://github.com/libimobiledevice/libplist/commit/60d291941fadb72b66d11502710add5899e21a2d