jdk-24/test/jdk/java/util/jar/Attributes/NullAndEmptyKeysAndValues.java
Philipp Kunz 1dae61a374 8066619: Fix deprecation warnings in java.util.jar
Reviewed-by: rriggs, lancea
2018-12-21 09:54:32 -05:00

202 lines
7.7 KiB
Java

/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.jar.Attributes.Name;
import java.lang.reflect.Field;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
/**
* @test
* @bug 8066619
* @modules java.base/java.util.jar:+open
* @run testng/othervm NullAndEmptyKeysAndValues
* @summary Tests manifests with {@code null} and empty string {@code ""}
* values as section name, header name, or value in both main and named
* attributes sections.
*/
/*
* Note to future maintainer:
* In order to actually being able to test all the cases where key and values
* are null normal manifest and attributes manipulation through their public
* api is not sufficient but then there were these null checks there before
* which may or may not have had their reason and this way it's ensured that
* the behavior does not change with that respect.
* Once module isolation is enforced some test cases will not any longer be
* possible and those now tested situations will be guaranteed not to occur
* any longer at all at which point the corresponding tests can be removed
* safely without replacement unless of course another way is found inject the
* tested null values.
* Another trick to access package private class members could be to use
* deserialization or adding a new class to the same package on the classpath.
* Here is not important how the values are set to null because it shows that
* the behavior remains unchanged.
*/
public class NullAndEmptyKeysAndValues {
static final String SOME_KEY = "some-key";
static final String SOME_VALUE = "some value";
static final String NULL_TEXT = "null";
static final String EMPTY_STR = "";
static final Name EMPTY_NAME = new Name("tmp") {{
try {
Field name = Name.class.getDeclaredField("name");
name.setAccessible(true);
name.set(this, EMPTY_STR);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}};
@Test
public void testMainAttributesHeaderNameNull() throws Exception {
Manifest mf = new Manifest();
Field attr = mf.getClass().getDeclaredField("attr");
attr.setAccessible(true);
Attributes mainAtts = new Attributes() {{
super.put(null, SOME_VALUE);
}};
attr.set(mf, mainAtts);
mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0");
assertThrows(NullPointerException.class, () -> writeAndRead(mf));
}
@Test
public void testMainAttributesHeaderNameEmpty() throws Exception {
Manifest mf = new Manifest();
mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0");
mf.getMainAttributes().put(EMPTY_NAME, SOME_VALUE);
assertThrows(IOException.class, () -> writeAndRead(mf));
}
@Test
public void testMainAttributesHeaderValueNull() throws Exception {
Manifest mf = new Manifest();
Field attr = mf.getClass().getDeclaredField("attr");
attr.setAccessible(true);
Attributes mainAtts = new Attributes() {{
map.put(new Name(SOME_KEY), null);
}};
attr.set(mf, mainAtts);
mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0");
mf = writeAndRead(mf);
assertEquals(mf.getMainAttributes().getValue(SOME_KEY), NULL_TEXT);
}
@Test
public void testMainAttributesHeaderValueEmpty() throws Exception {
Manifest mf = new Manifest();
Field attr = mf.getClass().getDeclaredField("attr");
attr.setAccessible(true);
Attributes mainAtts = new Attributes() {{
map.put(new Name(SOME_KEY), EMPTY_STR);
}};
attr.set(mf, mainAtts);
mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0");
mf = writeAndRead(mf);
assertEquals(mf.getMainAttributes().getValue(SOME_KEY), EMPTY_STR);
}
@Test
public void testSectionNameNull() throws IOException {
Manifest mf = new Manifest();
mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0");
mf.getEntries().put(null, new Attributes());
mf = writeAndRead(mf);
assertNotNull(mf.getEntries().get(NULL_TEXT));
}
@Test
public void testSectionNameEmpty() throws IOException {
Manifest mf = new Manifest();
mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0");
mf.getEntries().put(EMPTY_STR, new Attributes());
mf = writeAndRead(mf);
assertNotNull(mf.getEntries().get(EMPTY_STR));
}
@Test
public void testNamedSectionHeaderNameNull() throws IOException {
Manifest mf = new Manifest();
mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0");
mf.getEntries().put(SOME_KEY, new Attributes() {{
map.put(null, SOME_VALUE);
}});
assertThrows(NullPointerException.class, () -> writeAndRead(mf));
}
@Test
public void testNamedSectionHeaderNameEmpty() throws IOException {
Manifest mf = new Manifest();
mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0");
mf.getEntries().put(SOME_KEY, new Attributes() {{
map.put(EMPTY_NAME, SOME_VALUE);
}});
assertThrows(IOException.class, () -> writeAndRead(mf));
}
@Test
public void testNamedSectionHeaderValueNull() throws IOException {
Manifest mf = new Manifest();
mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0");
mf.getEntries().put(SOME_KEY, new Attributes() {{
map.put(new Name(SOME_KEY), null);
}});
mf = writeAndRead(mf);
assertEquals(mf.getEntries().get(SOME_KEY).getValue(SOME_KEY),
NULL_TEXT);
}
@Test
public void testNamedSectionHeaderValueEmpty() throws IOException {
Manifest mf = new Manifest();
mf.getMainAttributes().put(Name.MANIFEST_VERSION, "1.0");
mf.getEntries().put(SOME_KEY, new Attributes() {{
map.put(new Name(SOME_KEY), EMPTY_STR);
}});
mf = writeAndRead(mf);
assertEquals(mf.getEntries().get(SOME_KEY).getValue(SOME_KEY),
EMPTY_STR);
}
static Manifest writeAndRead(Manifest mf) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
mf.write(out);
byte[] mfBytes = out.toByteArray();
System.out.println("-".repeat(72));
System.out.print(new String(mfBytes, UTF_8));
System.out.println("-".repeat(72));
ByteArrayInputStream in = new ByteArrayInputStream(mfBytes);
return new Manifest(in);
}
}