| /* ==================================================================== |
| 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.poi.openxml4j.opc.compliance; |
| |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| |
| import org.apache.poi.openxml4j.exceptions.InvalidFormatException; |
| import org.apache.poi.openxml4j.opc.PackagePartName; |
| import org.apache.poi.openxml4j.opc.PackagingURIHelper; |
| import org.junit.Test; |
| |
| /** |
| * Test part name Open Packaging Convention compliance. |
| * |
| * (Open Packaging Convention 8.1.1 Part names) : |
| * |
| * The part name grammar is defined as follows: |
| * |
| * part_name = 1*( "/" segment ) |
| * |
| * segment = 1*( pchar ) |
| * |
| * pchar is defined in RFC 3986. |
| * |
| * The part name grammar implies the following constraints. The package |
| * implementer shall neither create any part that violates these constraints nor |
| * retrieve any data from a package as a part if the purported part name |
| * violates these constraints. |
| * |
| * A part name shall not be empty. [M1.1] |
| * |
| * A part name shall not have empty segments. [M1.3] |
| * |
| * A part name shall start with a forward slash ("/") character. [M1.4] |
| * |
| * A part name shall not have a forward slash as the last character. [M1.5] |
| * |
| * A segment shall not hold any characters other than pchar characters. [M1.6] |
| * |
| * Part segments have the following additional constraints. The package |
| * implementer shall neither create any part with a part name comprised of a |
| * segment that violates these constraints nor retrieve any data from a package |
| * as a part if the purported part name contains a segment that violates these |
| * constraints. |
| * |
| * A segment shall not contain percent-encoded forward slash ("/"), or backward |
| * slash ("\") characters. [M1.7] |
| * |
| * A segment shall not contain percent-encoded unreserved characters. [M1.8] |
| * |
| * A segment shall not end with a dot (".") character. [M1.9] |
| * |
| * A segment shall include at least one non-dot character. [M1.10] |
| * |
| * A package implementer shall neither create nor recognize a part with a part |
| * name derived from another part name by appending segments to it. [M1.11] |
| * |
| * Part name equivalence is determined by comparing part names as |
| * case-insensitive ASCII strings. [M1.12] |
| * |
| * @author Julien Chable |
| */ |
| public final class TestOPCCompliancePartName { |
| |
| /** |
| * Test some common invalid names. |
| * |
| * A segment shall not contain percent-encoded unreserved characters. [M1.8] |
| */ |
| @Test |
| public void testInvalidPartNames() { |
| String[] invalidNames = { "/", "/xml./doc.xml", "[Content_Types].xml", "//xml/." }; |
| for (String s : invalidNames) { |
| URI uri = null; |
| try { |
| uri = new URI(s); |
| } catch (URISyntaxException e) { |
| assertTrue(s.equals("[Content_Types].xml")); |
| continue; |
| } |
| assertFalse("This part name SHOULD NOT be valid: " + s, |
| PackagingURIHelper.isValidPartName(uri)); |
| } |
| } |
| |
| /** |
| * Test some common valid names. |
| */ |
| @Test |
| public void testValidPartNames() throws URISyntaxException { |
| String[] validNames = { "/xml/item1.xml", "/document.xml", |
| "/a/%D1%86.xml" }; |
| for (String s : validNames) |
| assertTrue("This part name SHOULD be valid: " + s, |
| PackagingURIHelper.isValidPartName(new URI(s))); |
| } |
| |
| /** |
| * A part name shall not be empty. [M1.1] |
| */ |
| @Test |
| public void testEmptyPartNameFailure() throws URISyntaxException { |
| try { |
| PackagingURIHelper.createPartName(new URI("")); |
| fail("A part name shall not be empty. [M1.1]"); |
| } catch (InvalidFormatException e) { |
| // Normal behaviour |
| } |
| } |
| |
| /** |
| * A part name shall not have empty segments. [M1.3] |
| * |
| * A segment shall not end with a dot ('.') character. [M1.9] |
| * |
| * A segment shall include at least one non-dot character. [M1.10] |
| */ |
| @Test |
| public void testPartNameWithInvalidSegmentsFailure() { |
| String[] invalidNames = { "//document.xml", "//word/document.xml", |
| "/word//document.rels", "/word//rels//document.rels", |
| "/xml./doc.xml", "/document.", "/./document.xml", |
| "/word/./doc.rels", "/%2F/document.xml" }; |
| try { |
| for (String s : invalidNames) |
| assertFalse( |
| "A part name shall not have empty segments. [M1.3]", |
| PackagingURIHelper.isValidPartName(new URI(s))); |
| } catch (URISyntaxException e) { |
| fail(); |
| } |
| } |
| |
| /** |
| * A segment shall not hold any characters other than ipchar (RFC 3987) characters. |
| * [M1.6]. |
| */ |
| @Test |
| public void testPartNameWithNonPCharCharacters() { |
| String[] validNames = { "/doc&.xml" }; |
| try { |
| for (String s : validNames) |
| assertTrue( |
| "A segment shall not contain non pchar characters [M1.6] : " |
| + s, PackagingURIHelper |
| .isValidPartName(new URI(s))); |
| } catch (URISyntaxException e) { |
| fail(); |
| } |
| } |
| |
| /** |
| * A segment shall not contain percent-encoded unreserved characters [M1.8]. |
| */ |
| @Test |
| public void testPartNameWithUnreservedEncodedCharactersFailure() { |
| String[] invalidNames = { "/a/docum%65nt.xml" }; |
| try { |
| for (String s : invalidNames) |
| assertFalse( |
| "A segment shall not contain percent-encoded unreserved characters [M1.8] : " |
| + s, PackagingURIHelper |
| .isValidPartName(new URI(s))); |
| } catch (URISyntaxException e) { |
| fail(); |
| } |
| } |
| |
| /** |
| * A part name shall start with a forward slash ('/') character. [M1.4] |
| */ |
| @Test |
| public void testPartNameStartsWithAForwardSlashFailure() |
| throws URISyntaxException { |
| try { |
| PackagingURIHelper.createPartName(new URI("document.xml")); |
| fail("A part name shall start with a forward slash ('/') character. [M1.4]"); |
| } catch (InvalidFormatException e) { |
| // Normal behaviour |
| } |
| } |
| |
| /** |
| * A part name shall not have a forward slash as the last character. [M1.5] |
| */ |
| @Test |
| public void testPartNameEndsWithAForwardSlashFailure() |
| throws URISyntaxException { |
| try { |
| PackagingURIHelper.createPartName(new URI("/document.xml/")); |
| fail("A part name shall not have a forward slash as the last character. [M1.5]"); |
| } catch (InvalidFormatException e) { |
| // Normal behaviour |
| } |
| } |
| |
| /** |
| * Part name equivalence is determined by comparing part names as |
| * case-insensitive ASCII strings. [M1.12] |
| */ |
| @Test |
| public void testPartNameComparaison() throws Exception { |
| String[] partName1 = { "/word/document.xml", "/docProps/core.xml", "/rels/.rels" }; |
| String[] partName2 = { "/WORD/DocUment.XML", "/docProps/core.xml", "/rels/.rels" }; |
| for (int i = 0; i < partName1.length || i < partName2.length; ++i) { |
| PackagePartName p1 = PackagingURIHelper.createPartName(partName1[i]); |
| PackagePartName p2 = PackagingURIHelper.createPartName(partName2[i]); |
| assertTrue(p1.equals(p2)); |
| assertTrue(p1.compareTo(p2) == 0); |
| assertTrue(p1.hashCode() == p2.hashCode()); |
| } |
| } |
| |
| /** |
| * Part name equivalence is determined by comparing part names as |
| * case-insensitive ASCII strings. [M1.12]. |
| * |
| * All the comparisons MUST FAIL ! |
| */ |
| @Test |
| public void testPartNameComparaisonFailure() throws Exception { |
| String[] partName1 = { "/word/document.xml", "/docProps/core.xml", "/rels/.rels" }; |
| String[] partName2 = { "/WORD/DocUment.XML2", "/docProp/core.xml", "/rels/rels" }; |
| for (int i = 0; i < partName1.length || i < partName2.length; ++i) { |
| PackagePartName p1 = PackagingURIHelper.createPartName(partName1[i]); |
| PackagePartName p2 = PackagingURIHelper.createPartName(partName2[i]); |
| assertFalse(p1.equals(p2)); |
| assertFalse(p1.compareTo(p2) == 0); |
| assertFalse(p1.hashCode() == p2.hashCode()); |
| } |
| } |
| } |