/* * 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. */ /* $Id$ */ package org.apache.fop; import java.io.IOException; import java.io.StringReader; import java.security.NoSuchAlgorithmException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; import org.junit.Before; import org.junit.Test; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import static org.junit.Assert.assertTrue; import org.apache.fop.util.DigestFilter; /** * Test case for digesting SAX filter. * */ public class DigestFilterTestCase { private SAXParserFactory parserFactory; @Before public void setUp() { parserFactory = SAXParserFactory.newInstance(); parserFactory.setNamespaceAware(true); } private boolean compareDigest(byte[] a, byte[] b) { if (a.length != b.length) { return false; } for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } private String digestToString(byte[] digest) { StringBuffer buffer = new StringBuffer(2 * digest.length); for (byte val : digest) { int hi = (val >> 4) & 0xF; int lo = val & 0xF; if (hi < 10) { buffer.append((char) (hi + 0x30)); } else { buffer.append((char) (hi + 0x61 - 10)); } if (lo < 10) { buffer.append((char) (lo + 0x30)); } else { buffer.append((char) (lo + 0x61 - 10)); } } return buffer.toString(); } private byte[] runTest(String input) throws NoSuchAlgorithmException, ParserConfigurationException, SAXException, IOException { XMLReader parser = parserFactory.newSAXParser().getXMLReader(); DigestFilter digestFilter = new DigestFilter("MD5"); digestFilter.setParent(parser); digestFilter.setFeature("http://xml.org/sax/features/namespaces", true); parser.setContentHandler(digestFilter); InputSource inputSource = new InputSource(new StringReader(input)); parser.parse(inputSource); return digestFilter.getDigestValue(); } @Test public final void testLineFeed() throws NoSuchAlgorithmException, ParserConfigurationException, SAXException, IOException { byte[] lfDigest = runTest("<a>\n</a>"); byte[] crlfDigest = runTest("<a>\r\n</a>"); assertTrue( "LF: " + digestToString(lfDigest) + " CRLF: " + digestToString(crlfDigest), compareDigest(lfDigest, crlfDigest)); } @Test public final void testAttributeOrder() throws NoSuchAlgorithmException, ParserConfigurationException, SAXException, IOException { byte[] sortDigest = runTest("<a a1='1' a2='2' a3='3'/>"); byte[] permutationDigest = runTest("<a a2='2' a3='3' a1='1'/>"); assertTrue( "Sort: " + digestToString(sortDigest) + " permuted: " + digestToString(permutationDigest), compareDigest(sortDigest, permutationDigest)); byte[] reverseDigest = runTest("<a a3='3' a2='2' a1='1'/>"); assertTrue( "Sort: " + digestToString(sortDigest) + " permuted: " + digestToString(reverseDigest), compareDigest(sortDigest, reverseDigest)); } @Test public final void testNamespacePrefix() throws NoSuchAlgorithmException, ParserConfigurationException, SAXException, IOException { byte[] prefix1Digest = runTest("<a:a xmlns:a='foo'/>"); byte[] prefix2Digest = runTest("<b:a xmlns:b='foo'/>"); assertTrue( "prefix1: " + digestToString(prefix1Digest) + " prefix2: " + digestToString(prefix2Digest), compareDigest(prefix1Digest, prefix2Digest)); } }