You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2019/07/16 01:42:46 UTC
svn commit: r1863109 - in
/jackrabbit/commons/filevault-package-maven-plugin/trunk/src:
main/java/org/apache/jackrabbit/filevault/maven/packaging/
test/java/org/apache/jackrabbit/filevault/maven/packaging/
Author: tripod
Date: Tue Jul 16 01:42:46 2019
New Revision: 1863109
URL: http://svn.apache.org/viewvc?rev=1863109&view=rev
Log:
JCRVLT-324 correctly escape multiline values in the manifest (closes #25)
Added:
jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateMetadataMojoTest.java
Modified:
jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateMetadataMojo.java
Modified: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateMetadataMojo.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateMetadataMojo.java?rev=1863109&r1=1863108&r2=1863109&view=diff
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateMetadataMojo.java (original)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateMetadataMojo.java Tue Jul 16 01:42:46 2019
@@ -729,6 +729,20 @@ public class GenerateMetadataMojo extend
return dependenciesString;
}
+ /**
+ * Escapes multiline manifest values to work around bug <a href="https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8222547">JDK-8222547</a>
+ * Java itself only adds leading SPACE in case a line is longer than 72 chars.
+ *
+ * If the value contains a newline, suffix it with an additional space (continuation character)!
+ *
+ * Unfortunately although the generated manifests for such escaped values are perfectly valid according to the spec,
+ * when reading those via {@link java.util.jar.Manifest} the new lines are stripped.
+ */
+ static final String escapeManifestValue(String value) {
+ return value.replaceAll("\n", "\n ") // this covers CRLF and LF
+ .replaceAll("\r(?!\n)", "\r "); // only CR (not followed by LF)
+ }
+
private MavenArchiveConfiguration getMavenArchiveConfiguration(Properties vaultProperties, String dependenciesString) throws IOException {
if (archive == null) {
archive = new MavenArchiveConfiguration();
@@ -743,11 +757,11 @@ public class GenerateMetadataMojo extend
// TODO: split up manifest generation
PackageId id = new PackageId(group, name, version);
- archive.addManifestEntry(MF_KEY_PACKAGE_TYPE, packageType.name().toLowerCase());
- archive.addManifestEntry(MF_KEY_PACKAGE_ID, id.toString());
- archive.addManifestEntry(MF_KEY_PACKAGE_DESC, vaultProperties.getProperty("description", ""));
+ archive.addManifestEntry(MF_KEY_PACKAGE_TYPE, escapeManifestValue(packageType.name().toLowerCase()));
+ archive.addManifestEntry(MF_KEY_PACKAGE_ID, escapeManifestValue(id.toString()));
+ archive.addManifestEntry(MF_KEY_PACKAGE_DESC, escapeManifestValue(vaultProperties.getProperty("description", "")));
if (dependenciesString != null && dependenciesString.length() > 0) {
- archive.addManifestEntry(MF_KEY_PACKAGE_DEPENDENCIES, dependenciesString);
+ archive.addManifestEntry(MF_KEY_PACKAGE_DEPENDENCIES, escapeManifestValue(dependenciesString));
}
// be sure to avoid duplicates
Set<String> rts = new TreeSet<>();
@@ -756,11 +770,11 @@ public class GenerateMetadataMojo extend
}
String[] roots = rts.toArray(new String[rts.size()]);
Arrays.sort(roots);
- archive.addManifestEntry(MF_KEY_PACKAGE_ROOTS, StringUtils.join(roots, ","));
+ archive.addManifestEntry(MF_KEY_PACKAGE_ROOTS, escapeManifestValue(StringUtils.join(roots, ",")));
// import package is not yet there!
if (StringUtils.isNotEmpty(importPackage)) {
- archive.addManifestEntry(MF_KEY_IMPORT_PACKAGE, StringUtils.deleteWhitespace(importPackage));
+ archive.addManifestEntry(MF_KEY_IMPORT_PACKAGE, escapeManifestValue(StringUtils.deleteWhitespace(importPackage)));
}
}
Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateMetadataMojoTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateMetadataMojoTest.java?rev=1863109&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateMetadataMojoTest.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateMetadataMojoTest.java Tue Jul 16 01:42:46 2019
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.filevault.maven.packaging;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class GenerateMetadataMojoTest {
+
+ private static final String MANIFEST_ATTRIBUTE_NAME = "test";
+
+ @Test
+ public void testEscapeManifestValue() throws IOException {
+ assertEscapedValueWorksInManifest("Paragraph\r\rAnother paragraph");
+ assertEscapedValueWorksInManifest("single line value");
+ assertEscapedValueWorksInManifest("Paragraph\n\nAnother paragraph");
+ assertEscapedValueWorksInManifest("Paragraph\r\n\r\nAnother paragraph");
+ assertEscapedValueWorksInManifest("some very long line above 72 chars. some very long line above 72 chars. some very long line above 72 chars\n\nAnother paragraph");
+ assertEscapedValueWorksInManifest("some very long line above 72 chars. some very long line above 72 chars. some very long line above 72 chars\r\rAnother paragraph");
+ }
+
+ private void assertEscapedValueWorksInManifest(String value) throws IOException {
+ String escapedValue = GenerateMetadataMojo.escapeManifestValue(value);
+ Manifest manifest = new Manifest();
+ Attributes attributes = manifest.getMainAttributes();
+ attributes.putValue(MANIFEST_ATTRIBUTE_NAME, escapedValue);
+ attributes.putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1.0");
+
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ manifest.write(outputStream);
+ //System.out.println(new String(outputStream.toByteArray(), StandardCharsets.UTF_8));
+ try (ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray())) {
+ manifest = new Manifest(inputStream);
+ // java.util.jar.Manifest removes the new lines unfortunately from values, but maybe this gets fixed by Oracle at some point in time...
+ String actualValue = manifest.getMainAttributes().getValue(MANIFEST_ATTRIBUTE_NAME);
+ Assert.assertEquals(removeNewlines(value), unescapeContinuations(actualValue));
+ }
+ };
+
+ }
+
+ private static String removeNewlines(String value) {
+ return value.replaceAll("\n|\r", "");
+ }
+
+ /**
+ * Java's Manifest parser {@link java.util.jar.Manifest} does not correctly remove the continuation for values in the form
+ * {@code SomeText CR SPACE CR}
+ * @param value
+ * @return the given value with all {@code CR}s followed by {@code SPACE} removed
+ */
+ private static String unescapeContinuations(String value) {
+ return value.replaceAll("\r ", "");
+ }
+
+}