Unverified Commit d510f60a authored by Silvan Mosberger's avatar Silvan Mosberger Committed by GitHub
Browse files

lib.generators.toPlist: escape XML syntax in strings & keys (#356502)

parents 7042c42e d1cb670e
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ let
    split
    toJSON
    typeOf
    escapeXML
    ;

  ## -- HELPER FUNCTIONS & DEFAULTS --
@@ -548,13 +549,17 @@ in rec {

    # Inputs

    Options
    : Empty set, there may be configuration options in the future
    Structured function argument

    : escape (optional, default: `false`)
      : If this option is true, XML special characters are escaped in string values and keys

    Value
      : The value to be converted to Plist
  */
  toPlist = {}: v: let
  toPlist = {
    escape ? false
  }: v: let
    expr = ind: x:
      if x == null  then "" else
      if isBool x   then bool ind x else
@@ -568,10 +573,12 @@ in rec {

    literal = ind: x: ind + x;

    maybeEscapeXML = if escape then escapeXML else x: x;

    bool = ind: x: literal ind  (if x then "<true/>" else "<false/>");
    int = ind: x: literal ind "<integer>${toString x}</integer>";
    str = ind: x: literal ind "<string>${x}</string>";
    key = ind: x: literal ind "<key>${x}</key>";
    str = ind: x: literal ind "<string>${maybeEscapeXML x}</string>";
    key = ind: x: literal ind "<key>${maybeEscapeXML x}</key>";
    float = ind: x: literal ind "<real>${toString x}</real>";

    indent = ind: expr "\t${ind}";
@@ -597,7 +604,10 @@ in rec {
      (expr "\t${ind}" value)
    ]) x));

  in ''<?xml version="1.0" encoding="UTF-8"?>
  in
  # TODO: As discussed in #356502, deprecated functionality should be removed sometime after 25.11.
  lib.warnIf (!escape && lib.oldestSupportedReleaseIsAtLeast 2505) "Using `lib.generators.toPlist` without `escape = true` is deprecated"
  ''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
${expr "" v}
+26 −2
Original line number Diff line number Diff line
@@ -1641,7 +1641,7 @@ runTests {
    expected  = "«foo»";
  };

  testToPlist = {
  testToPlistUnescaped = {
    expr = mapAttrs (const (generators.toPlist { })) {
      value = {
        nested.values = {
@@ -1657,10 +1657,34 @@ runTests {
          emptylist = [];
          attrs = { foo = null; "foo b/ar" = "baz"; };
          emptyattrs = {};
          "keys are not <escaped>" = "and < neither are string values";
        };
      };
    };
    expected = { value = builtins.readFile ./test-to-plist-expected.plist; };
    expected = { value = builtins.readFile ./test-to-plist-unescaped-expected.plist; };
  };

  testToPlistEscaped = {
    expr = mapAttrs (const (generators.toPlist { escape = true; })) {
      value = {
        nested.values = {
          int = 42;
          float = 0.1337;
          bool = true;
          emptystring = "";
          string = "fn\${o}\"r\\d";
          newlinestring = "\n";
          path = /. + "/foo";
          null_ = null;
          list = [ 3 4 "test" ];
          emptylist = [];
          attrs = { foo = null; "foo b/ar" = "baz"; };
          emptyattrs = {};
          "keys are <escaped>" = "and < so are string values";
        };
      };
    };
    expected = { value = builtins.readFile ./test-to-plist-escaped-expected.plist; };
  };

  testToLuaEmptyAttrSet = {
+48 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>nested</key>
	<dict>
		<key>values</key>
		<dict>
			<key>attrs</key>
			<dict>
				<key>foo b/ar</key>
				<string>baz</string>
			</dict>
			<key>bool</key>
			<true/>
			<key>emptyattrs</key>
			<dict>

			</dict>
			<key>emptylist</key>
			<array>

			</array>
			<key>emptystring</key>
			<string></string>
			<key>float</key>
			<real>0.133700</real>
			<key>int</key>
			<integer>42</integer>
			<key>keys are &lt;escaped&gt;</key>
			<string>and &lt; so are string values</string>
			<key>list</key>
			<array>
				<integer>3</integer>
				<integer>4</integer>
				<string>test</string>
			</array>
			<key>newlinestring</key>
			<string>
</string>
			<key>path</key>
			<string>/foo</string>
			<key>string</key>
			<string>fn${o}&quot;r\d</string>
		</dict>
	</dict>
</dict>
</plist>
 No newline at end of file
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@
			<real>0.133700</real>
			<key>int</key>
			<integer>42</integer>
			<key>keys are not <escaped></key>
			<string>and < neither are string values</string>
			<key>list</key>
			<array>
				<integer>3</integer>