1 /*******************************************************************************
2  * Copyright (c) 2008 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.equinox.internal.security.tests.storage;
15 
16 import static org.junit.Assert.assertEquals;
17 import static org.junit.Assert.assertFalse;
18 import static org.junit.Assert.assertNotNull;
19 import static org.junit.Assert.assertNull;
20 import static org.junit.Assert.assertTrue;
21 
22 import java.io.IOException;
23 import java.net.URL;
24 import java.util.Map;
25 import org.eclipse.equinox.internal.security.storage.StorageUtils;
26 import org.eclipse.equinox.security.storage.*;
27 import org.junit.Test;
28 
29 public class SlashEncodeTest extends StorageAbstractTest {
30 
31 	final private static String[] decodedSlash = {"root", "ro/ot", "/root", "root/", "ro/ot/me", "ro//ot"};
32 	final private static String[] encodedSlash = {"root", "ro\\2fot", "\\2froot", "root\\2f", "ro\\2fot\\2fme", "ro\\2f\\2fot"};
33 
34 	final private static String[] decodedBackSlash = {"ro\\ot", "\\root", "root\\", "ro\\ot\\me", "ro\\\\ot"};
35 	final private static String[] encodedBackSlash = {"ro\\5cot", "\\5croot", "root\\5c", "ro\\5cot\\5cme", "ro\\5c\\5cot"};
36 
37 	final private static String[] decodedMixSlash = {"r/o\\ot", "r\\o/ot", "/\\root", "root\\/", "\\5cro\\2f ot"};
38 	final private static String[] encodedMixSlash = {"r\\2fo\\5cot", "r\\5co\\2fot", "\\2f\\5croot", "root\\5c\\2f", "\\5c5cro\\5c2f ot"};
39 
40 	/**
41 	 * Tests forward slash
42 	 */
43 	@Test
testForwardSlash()44 	public void testForwardSlash() {
45 		for (int i = 0; i < decodedSlash.length; i++) {
46 			String tmp = EncodingUtils.encodeSlashes(decodedSlash[i]);
47 			assertEquals(encodedSlash[i], tmp);
48 			assertEquals(decodedSlash[i], EncodingUtils.decodeSlashes(tmp));
49 		}
50 	}
51 
52 	/**
53 	 * Tests backward slash
54 	 */
55 	@Test
testBackwardSlash()56 	public void testBackwardSlash() {
57 		for (int i = 0; i < decodedBackSlash.length; i++) {
58 			String tmp = EncodingUtils.encodeSlashes(decodedBackSlash[i]);
59 			assertEquals(encodedBackSlash[i], tmp);
60 			assertEquals(decodedBackSlash[i], EncodingUtils.decodeSlashes(tmp));
61 		}
62 	}
63 
64 	/**
65 	 * Tests mixed slashes
66 	 */
67 	@Test
testMixSlash()68 	public void testMixSlash() {
69 		for (int i = 0; i < decodedMixSlash.length; i++) {
70 			String tmp = EncodingUtils.encodeSlashes(decodedMixSlash[i]);
71 			assertEquals(encodedMixSlash[i], tmp);
72 			assertEquals(decodedMixSlash[i], EncodingUtils.decodeSlashes(tmp));
73 		}
74 	}
75 
76 	/**
77 	 * Tests edge conditions: null or empty arguments
78 	 */
79 	@Test
testEdge()80 	public void testEdge() {
81 		assertNull(EncodingUtils.encodeSlashes(null));
82 		assertNull(EncodingUtils.decodeSlashes(null));
83 
84 		String encoded = EncodingUtils.encodeSlashes("");
85 		assertNotNull(encoded);
86 		assertEquals("", encoded);
87 	}
88 
getOptions()89 	protected Map<String, Object> getOptions() {
90 		// Password value really doesn't matter here; we specify it to avoid
91 		// triggering UI elements in case default password provider has the
92 		// highest priority in the tested configuration
93 		return getOptions("password1");
94 	}
95 
96 	/**
97 	 * Tests preferences node name using slash encoding
98 	 * @throws IOException
99 	 * @throws BackingStoreException
100 	 */
101 	@Test
testPreferencesWithSlashes()102 	public void testPreferencesWithSlashes() throws IOException, StorageException {
103 		URL location = getStorageLocation();
104 		assertNotNull(location);
105 		{ // block1: fill and test in memory
106 			ISecurePreferences preferences = newPreferences(location, getOptions());
107 			String safePath = EncodingUtils.encodeSlashes("ro/ot");
108 			ISecurePreferences node = preferences.node(safePath);
109 			node.put("password", "test", true);
110 
111 			assertFalse(preferences.nodeExists("ro"));
112 			assertFalse(preferences.nodeExists("ro/ot"));
113 			assertTrue(preferences.nodeExists(safePath));
114 
115 			preferences.flush();
116 			closePreferences(preferences);
117 		}
118 
119 		{ // block2: reload and check
120 			ISecurePreferences preferences = newPreferences(location, getOptions());
121 			String children[] = preferences.childrenNames();
122 			assertNotNull(children);
123 			assertEquals(children.length, 1);
124 			ISecurePreferences nodeRet = preferences.node(children[0]);
125 			String absolutePath = EncodingUtils.decodeSlashes(nodeRet.absolutePath());
126 			assertEquals("/ro/ot", absolutePath);
127 			assertEquals("test", nodeRet.get("password", null));
128 		}
129 		StorageUtils.delete(location);
130 	}
131 }
132