RequestedModuleNames implements IRequestedModuleNames { protected void decodeModuleIds(byte[] decoded, Map<Integer, String> sparseArray, boolean hasIdListHash) throws IOException { final String sourceMethod = "decodeModuleIds"; if (isTraceLogging) { log.entering(RequestedModuleNames.class.getName(), sourceMethod, new Object[]{decoded, sparseArray}); } if (decoded != null) { boolean use32BitEncoding = hasIdListHash ? decoded[idListHash.length] == 1 : false; int start = hasIdListHash ? idListHash.length+1 : 0; int elemSize = use32BitEncoding ? 4 : 2; int[] intArray = new int[(decoded.length-start)/elemSize]; for (int i = 0; i < intArray.length; i ++) { int j = start+i*elemSize; if (use32BitEncoding) { intArray[i] = (((int)(decoded[j])&0xFF) << 24) + (((int)(decoded[j+1])&0xFF) << 16) + (((int)(decoded[j+2])&0xFF) << 8) + ((int)(decoded[j+3])&0xFF); } else { intArray[i] = (((int)(decoded[j])&0xFF) << 8) + ((int)(decoded[j+1])&0xFF); } } if (isTraceLogging) { log.finer("ids = " + Arrays.asList(intArray).toString()); } for (int i = 0, position = -1, length = 0; i < intArray.length;) { if (position == -1) { position = intArray[i++]; length = intArray[i++]; } for (int j = 0; j < length; j++) { String pluginName = null, moduleName = null; int id = intArray[i++]; if (id == 0) { id = intArray[i++]; pluginName = idList.get(id); if (pluginName == null) { throw new BadRequestException(); } id = intArray[i++]; moduleName = id != 0 ? idList.get(id) : ""; } else { moduleName = idList.get(id); } if (moduleName == null) { throw new BadRequestException(); } if (sparseArray.get(position+j) != null) { throw new BadRequestException(); } sparseArray.put(position+j, (pluginName != null ? (pluginName + "!") : "") + moduleName); } position = -1; } } if (isTraceLogging) { log.exiting(RequestedModuleNames.class.getName(), sourceMethod, sparseArray); } } RequestedModuleNames(HttpServletRequest request, List<String> idList, byte[] idListHash); @Override List<String> getDeps(); @Override List<String> getModules(); @Override List<String> getPreloads(); @Override List<String> getScripts(); @Override List<String> getExcludes(); @Override String toString(); boolean isVersionError(); String toString(boolean decode); static public Pattern NON_PATH_PROP_PATTERN; static public String PLUGIN_PREFIXES_PROP_NAME; }
@Test public void testDecodeModuleIds() throws Exception { final String[] idList = new String[0x10005]; idList[1] = "module1"; idList[2] = "module2"; idList[3] = "foo"; idList[4] = "bar"; idList[5] = "plugin"; idList[0x10003] = "bigId"; int ids[] = new int [] { 3, 1, 1, 5, 2, 2, 0, 5, 3, 10, 1, 4 }; byte hash[] = new byte[]{1, 2, 3}; byte[] bytes = new byte[ids.length*2]; for (int i = 0; i < ids.length; i++) { bytes[i*2] = (byte)(ids[i] >> 8); bytes[i*2+1] = (byte)(ids[i] & 0xFF); } byte[] encoded = ArrayUtils.addAll(ArrayUtils.addAll(hash, new byte[]{0}), bytes); System.out.println(encoded); Map<Integer, String> resultArray = new TreeMap<Integer, String>(); Ref<IConfig> configRef = new Ref<IConfig>(null); File tmpDir = new File(System.getProperty("user.dir")); IAggregator mockAggregator = TestUtils.createMockAggregator(configRef, tmpDir); Map<String, Object> requestAttributes = new HashMap<String, Object>(); Map<String, String[]> requestParameters = new HashMap<String, String[]>(); HttpServletRequest mockRequest = TestUtils.createMockRequest(mockAggregator, requestAttributes, requestParameters, null, null); EasyMock.replay(mockAggregator, mockRequest); configRef.set(new ConfigImpl(mockAggregator, URI.create(tmpDir.toURI().toString()), "{}")); requestParameters.put(AbstractHttpTransport.REQUESTEDMODULEIDS_REQPARAM, new String[]{Base64.encodeBase64URLSafeString(encoded)}); requestParameters.put(AbstractHttpTransport.REQUESTEDMODULESCOUNT_REQPARAM, new String[]{"4"}); RequestedModuleNames requestedModules = new RequestedModuleNames(mockRequest, Arrays.asList(idList), hash); requestedModules.decodeModuleIds(encoded, resultArray, true); Assert.assertEquals(4, resultArray.size()); Assert.assertEquals("module1", resultArray.get(3)); Assert.assertEquals("module2", resultArray.get(5)); Assert.assertEquals("plugin!foo", resultArray.get(6)); Assert.assertEquals("bar", resultArray.get(10)); ids = ArrayUtils.addAll(ids, new int[]{12, 1, 0x10003}); bytes = new byte[ids.length*4]; for (int i = 0; i < ids.length; i++) { bytes[i*4] = (byte)(ids[i] >> 24); bytes[i*4+1] = (byte)((ids[i] >> 16) & 0xFF); bytes[i*4+2] = (byte)((ids[i] >> 8) & 0xFF); bytes[i*4+3] = (byte)(ids[i] & 0xFF); } encoded = ArrayUtils.addAll(ArrayUtils.addAll(hash, new byte[]{1}), bytes); System.out.println(encoded); requestParameters.put(AbstractHttpTransport.REQUESTEDMODULEIDS_REQPARAM, new String[]{Base64.encodeBase64URLSafeString(encoded)}); requestParameters.put(AbstractHttpTransport.REQUESTEDMODULESCOUNT_REQPARAM, new String[]{"5"}); requestedModules = new RequestedModuleNames(mockRequest, Arrays.asList(idList), hash); resultArray = new TreeMap<Integer, String>(); requestedModules.decodeModuleIds(encoded, resultArray, true); Assert.assertEquals(5, resultArray.size()); Assert.assertEquals("module1", resultArray.get(3)); Assert.assertEquals("module2", resultArray.get(5)); Assert.assertEquals("plugin!foo", resultArray.get(6)); Assert.assertEquals("bar", resultArray.get(10)); Assert.assertEquals("bigId", resultArray.get(12)); try { encoded = ArrayUtils.addAll(new byte[]{3, 2, 1}, bytes); requestParameters.put(AbstractHttpTransport.REQUESTEDMODULEIDS_REQPARAM, new String[]{Base64.encodeBase64URLSafeString(encoded)}); requestedModules = new RequestedModuleNames(mockRequest, Arrays.asList(idList), hash); requestedModules.decodeModuleIds(encoded, new TreeMap<Integer, String>(), true); fail("Expected exception"); } catch (BadRequestException ex) { } configRef.set(new ConfigImpl(mockAggregator, URI.create(tmpDir.toURI().toString()), "{"+RequestedModuleNames.CONFIGPROP_IDLISTHASHERRMODULE+":'errModule'}")); requestedModules = new RequestedModuleNames(mockRequest, Arrays.asList(idList), hash); Assert.assertEquals("scripts:[errModule]", requestedModules.toString()); }