[ https://issues.apache.org/jira/browse/MSHARED-1453?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17901466#comment-17901466 ]
ASF GitHub Bot commented on MSHARED-1453: ----------------------------------------- gnodet commented on code in PR #77: URL: https://github.com/apache/maven-archiver/pull/77#discussion_r1860568880 ########## src/main/java/org/apache/maven/shared/archiver/PomPropertiesUtil.java: ########## @@ -61,36 +60,51 @@ private boolean sameContents(Properties props, Path file) throws IOException { return fileProps.equals(props); } - private void createPropertiesFile(Properties properties, Path outputFile, boolean forceCreation) + private void createPropertiesFile(Properties unsortedProperties, Path outputFile, boolean forceCreation) throws IOException { Path outputDir = outputFile.getParent(); if (outputDir != null && !Files.isDirectory(outputDir)) { Files.createDirectories(outputDir); } - if (!forceCreation && sameContents(properties, outputFile)) { + if (!forceCreation && sameContents(unsortedProperties, outputFile)) { return; } - try (PrintWriter pw = new PrintWriter(outputFile.toFile(), StandardCharsets.ISO_8859_1.name()); - StringWriter sw = new StringWriter()) { - - properties.store(sw, null); - - List<String> lines = new ArrayList<>(); - try (BufferedReader r = new BufferedReader(new StringReader(sw.toString()))) { - String line; - while ((line = r.readLine()) != null) { - if (!line.startsWith("#")) { - lines.add(line); - } - } + // For reproducible builds, sort the properties and drop comments. + // The java.util.Properties class doesn't guarantee order so we have + // to write the file using a Writer. + Set<String> propertyNames = unsortedProperties.stringPropertyNames(); + List<String> sortedPropertyNames = new ArrayList<>(propertyNames); + Collections.sort(sortedPropertyNames); + + try (Writer out = Files.newBufferedWriter(outputFile, StandardCharsets.ISO_8859_1)) { + for (String key : sortedPropertyNames) { + out.write(escape(key)); + out.write("="); + out.write(escape(unsortedProperties.getProperty(key))); + out.write('\n'); } + } + } - Collections.sort(lines); - for (String l : lines) { - pw.println(l); + private static String escape(String s) { + StringBuilder sb = new StringBuilder(s.length()); + for (char c : s.toCharArray()) { + if (Character.isWhitespace(c) || c == '#' || c == '!' || c == '=' || c == ':') { // backslash escape + sb.append('\\'); + sb.append(c); + } else if (c < 256) { // 8859-1 Review Comment: The following test succeeds: ``` Properties p = new Properties(); p.put("foo", "aéüb"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); p.store(baos, null); String s = baos.toString(); assertTrue(s.contains("foo=a\\u00E9\\u00FCb")); ``` So non plain ascii chars should be unicode encoded. > Canonicalize properties files for reproducible builds > ----------------------------------------------------- > > Key: MSHARED-1453 > URL: https://issues.apache.org/jira/browse/MSHARED-1453 > Project: Maven Shared Components > Issue Type: Bug > Components: maven-archiver > Reporter: Elliotte Rusty Harold > Assignee: Elliotte Rusty Harold > Priority: Minor > > See discussion on https://github.com/apache/maven-archiver/pull/77/files > Briefly, properties files have non-unique representations and there's no > guarantee two JDKs from different companies and Java versions produce the > same byte-per-byte serialization. Our current code accounts for property > order and comments, but not variations in escaping (hex vs. UTF-8), separator > characters, and insignificant whitespace. -- This message was sent by Atlassian Jira (v8.20.10#820010)