diff --git a/javase/src/main/java/com/google/zxing/client/j2se/ImageReader.java b/javase/src/main/java/com/google/zxing/client/j2se/ImageReader.java index 0d7617cea..323ece0c7 100644 --- a/javase/src/main/java/com/google/zxing/client/j2se/ImageReader.java +++ b/javase/src/main/java/com/google/zxing/client/j2se/ImageReader.java @@ -21,7 +21,6 @@ import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; -import java.net.URLDecoder; /** * Encapsulates reading URIs as images. @@ -60,8 +59,7 @@ public final class ImageReader { if (base64Start < 0) { throw new IOException("Unsupported data URI encoding"); } - String base64DataEncoded = uriString.substring(base64Start + BASE64TOKEN.length()); - String base64Data = URLDecoder.decode(base64DataEncoded, "UTF-8"); + String base64Data = uriString.substring(base64Start + BASE64TOKEN.length()); byte[] imageBytes = Base64Decoder.getInstance().decode(base64Data); return ImageIO.read(new ByteArrayInputStream(imageBytes)); } diff --git a/javase/src/test/java/com/google/zxing/client/j2se/DecodeWorkerTestCase.java b/javase/src/test/java/com/google/zxing/client/j2se/DecodeWorkerTestCase.java new file mode 100644 index 000000000..83d9b959e --- /dev/null +++ b/javase/src/test/java/com/google/zxing/client/j2se/DecodeWorkerTestCase.java @@ -0,0 +1,50 @@ +/* + * Copyright 2018 ZXing authors + * + * Licensed 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 com.google.zxing.client.j2se; + +import com.beust.jcommander.JCommander; +import org.junit.Assert; +import org.junit.Test; + +import java.net.URI; +import java.util.Collections; +import java.util.LinkedList; +import java.util.Queue; + +/** + * Tests {@link DecodeWorker}. + */ +public final class DecodeWorkerTestCase extends Assert { + + private static final String IMAGE_DATA_URI = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQAAAAB/n//CAAAAkklEQVR42mP4DwQNDJjkB4" + + "E77A0M369N/d7A8CV6rjiQjPMFkWG1QPL7RVGg%2BAfREKCa/5/vA9V/nFSQ3sDwb7/KdiDJqX4dSH4pXN/A8DfyDVD2" + + "988HQPUfPVaqA0XKz%2BgD9bIk1AP1fgwvB7KlS9VBdqXbA82PT9AH2fiaH2SXGdDM71fDgeIfhIvKsbkTTAIAKYVr0N" + + "z5IloAAAAASUVORK5CYII="; + + + @Test + public void testWorker() throws Exception { + DecoderConfig config = new DecoderConfig(); + JCommander jCommander = new JCommander(config); + jCommander.parse("--pure_barcode", IMAGE_DATA_URI); + Queue inputs = new LinkedList<>(Collections.singletonList(new URI(IMAGE_DATA_URI))); + DecodeWorker worker = new DecodeWorker(config, inputs); + assertEquals(1, worker.call().intValue()); + } + +} diff --git a/javase/src/test/java/com/google/zxing/client/j2se/ImageReaderTestCase.java b/javase/src/test/java/com/google/zxing/client/j2se/ImageReaderTestCase.java index f8f3fe359..bffc96c27 100644 --- a/javase/src/test/java/com/google/zxing/client/j2se/ImageReaderTestCase.java +++ b/javase/src/test/java/com/google/zxing/client/j2se/ImageReaderTestCase.java @@ -28,7 +28,7 @@ import java.net.URI; public final class ImageReaderTestCase extends Assert { @Test - public void testFoo() throws Exception { + public void testDataURI() throws Exception { String uri = "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////w" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6" + diff --git a/zxing.appspot.com/src/main/java/com/google/zxing/web/generator/client/Generator.java b/zxing.appspot.com/src/main/java/com/google/zxing/web/generator/client/Generator.java index 53cbd4251..be7cdb228 100644 --- a/zxing.appspot.com/src/main/java/com/google/zxing/web/generator/client/Generator.java +++ b/zxing.appspot.com/src/main/java/com/google/zxing/web/generator/client/Generator.java @@ -68,10 +68,9 @@ public final class Generator implements EntryPoint { setupLeftPanel(); topPanel.getElement().setId("leftpanel"); - Widget leftPanel = topPanel; HorizontalPanel mainPanel = new HorizontalPanel(); - mainPanel.add(leftPanel); + mainPanel.add(topPanel); SimplePanel div2 = new SimplePanel(); div2.add(result); diff --git a/zxingorg/src/main/java/com/google/zxing/web/DoSFilter.java b/zxingorg/src/main/java/com/google/zxing/web/DoSFilter.java index 69686ef79..5ccf5266d 100644 --- a/zxingorg/src/main/java/com/google/zxing/web/DoSFilter.java +++ b/zxingorg/src/main/java/com/google/zxing/web/DoSFilter.java @@ -39,13 +39,17 @@ import java.util.concurrent.TimeUnit; @WebFilter({"/w/decode", "/w/chart"}) public final class DoSFilter implements Filter { + static final int MAX_ACCESS_PER_TIME = 500; + static final long ACCESS_TIME_MS = TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES); + static final int MAX_ENTRIES = 10_000; + private Timer timer; private DoSTracker sourceAddrTracker; @Override public void init(FilterConfig filterConfig) { timer = new Timer("DoSFilter"); - sourceAddrTracker = new DoSTracker(timer, 500, TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES), 10_000); + sourceAddrTracker = new DoSTracker(timer, MAX_ACCESS_PER_TIME, ACCESS_TIME_MS, MAX_ENTRIES); timer.scheduleAtFixedRate( new TimerTask() { @Override diff --git a/zxingorg/src/main/java/com/google/zxing/web/DoSTracker.java b/zxingorg/src/main/java/com/google/zxing/web/DoSTracker.java index 2254fa5aa..9884ea8af 100644 --- a/zxingorg/src/main/java/com/google/zxing/web/DoSTracker.java +++ b/zxingorg/src/main/java/com/google/zxing/web/DoSTracker.java @@ -38,7 +38,7 @@ final class DoSTracker { DoSTracker(Timer timer, final int maxAccessesPerTime, long accessTimeMS, int maxEntries) { this.maxAccessesPerTime = maxAccessesPerTime; this.numRecentAccesses = new LRUMap<>(maxEntries); - timer.scheduleAtFixedRate(new TimerTask() { + timer.schedule(new TimerTask() { @Override public void run() { synchronized (numRecentAccesses) { diff --git a/zxingorg/src/test/java/com/google/zxing/web/ChartServletRequestParametersTestCase.java b/zxingorg/src/test/java/com/google/zxing/web/ChartServletRequestParametersTestCase.java new file mode 100644 index 000000000..63ad779e5 --- /dev/null +++ b/zxingorg/src/test/java/com/google/zxing/web/ChartServletRequestParametersTestCase.java @@ -0,0 +1,42 @@ +/* + * Copyright 2018 ZXing authors + * + * Licensed 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 com.google.zxing.web; + +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import org.junit.Assert; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; + +/** + * Tests {@link ChartServletRequestParameters}. + */ +public final class ChartServletRequestParametersTestCase extends Assert { + + @Test + public void testParams() { + ChartServletRequestParameters params = + new ChartServletRequestParameters(10, 20, StandardCharsets.UTF_8, ErrorCorrectionLevel.H, 5, "foo"); + assertEquals(10, params.getWidth()); + assertEquals(20, params.getHeight()); + assertEquals(StandardCharsets.UTF_8, params.getOutputEncoding()); + assertEquals(ErrorCorrectionLevel.H, params.getEcLevel()); + assertEquals(5, params.getMargin()); + assertEquals("foo", params.getText()); + } + +} diff --git a/zxingorg/src/test/java/com/google/zxing/web/DoSFilterTestCase.java b/zxingorg/src/test/java/com/google/zxing/web/DoSFilterTestCase.java new file mode 100644 index 000000000..3fb4b7246 --- /dev/null +++ b/zxingorg/src/test/java/com/google/zxing/web/DoSFilterTestCase.java @@ -0,0 +1,48 @@ +/* + * Copyright 2018 ZXing authors + * + * Licensed 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 com.google.zxing.web; + +import org.junit.Assert; +import org.junit.Test; +import org.springframework.mock.web.MockFilterChain; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import javax.servlet.http.HttpServletResponse; + +/** + * Tests {@link DoSFilter}. + */ +public final class DoSFilterTestCase extends Assert { + + @Test + public void testRedirect() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setRequestURI("/"); + request.setRemoteAddr("1.2.3.4"); + MockHttpServletResponse response = new MockHttpServletResponse(); + DoSFilter filter = new DoSFilter(); + filter.init(null); + for (int i = 0; i < DoSFilter.MAX_ACCESS_PER_TIME; i++) { + filter.doFilter(request, response, new MockFilterChain()); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + filter.doFilter(request, response, new MockFilterChain()); + assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); + } + +} diff --git a/zxingorg/src/test/java/com/google/zxing/web/DoSTrackerTestCase.java b/zxingorg/src/test/java/com/google/zxing/web/DoSTrackerTestCase.java new file mode 100644 index 000000000..95a87d1f2 --- /dev/null +++ b/zxingorg/src/test/java/com/google/zxing/web/DoSTrackerTestCase.java @@ -0,0 +1,58 @@ +/* + * Copyright 2018 ZXing authors + * + * Licensed 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 com.google.zxing.web; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.Timer; + +/** + * Tests {@link DoSTracker}. + */ +public final class DoSTrackerTestCase extends Assert { + + @Test + public void testDoS() throws Exception { + Timer timer = new Timer(); + long timerTimeMS = 200; + DoSTracker tracker = new DoSTracker(timer, 2, timerTimeMS, 3); + assertFalse(tracker.isBanned("A")); + assertFalse(tracker.isBanned("A")); + assertTrue(tracker.isBanned("A")); + + assertFalse(tracker.isBanned("B")); + assertFalse(tracker.isBanned("C")); + assertFalse(tracker.isBanned("D")); + assertFalse(tracker.isBanned("A")); + + assertFalse(tracker.isBanned("A")); + assertTrue(tracker.isBanned("A")); + Thread.sleep(timerTimeMS * 3); + assertFalse(tracker.isBanned("A")); + + assertFalse(tracker.isBanned("A")); + assertTrue(tracker.isBanned("A")); + assertTrue(tracker.isBanned("A")); + assertTrue(tracker.isBanned("A")); + assertTrue(tracker.isBanned("A")); + assertTrue(tracker.isBanned("A")); + Thread.sleep(timerTimeMS * 2); + assertTrue(tracker.isBanned("A")); + } + +} diff --git a/zxingorg/src/test/java/com/google/zxing/web/HTTPSFilterTestCase.java b/zxingorg/src/test/java/com/google/zxing/web/HTTPSFilterTestCase.java index 6db15f912..344daf7aa 100644 --- a/zxingorg/src/test/java/com/google/zxing/web/HTTPSFilterTestCase.java +++ b/zxingorg/src/test/java/com/google/zxing/web/HTTPSFilterTestCase.java @@ -42,7 +42,6 @@ public final class HTTPSFilterTestCase extends Assert { request.setRequestURI("/path"); response = new MockHttpServletResponse(); chain = new MockFilterChain(); - } @Test diff --git a/zxingorg/src/test/java/com/google/zxing/web/LRUMapTestCase.java b/zxingorg/src/test/java/com/google/zxing/web/LRUMapTestCase.java new file mode 100644 index 000000000..af4f02c2a --- /dev/null +++ b/zxingorg/src/test/java/com/google/zxing/web/LRUMapTestCase.java @@ -0,0 +1,39 @@ +/* + * Copyright 2018 ZXing authors + * + * Licensed 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 com.google.zxing.web; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests {@link LRUMap}. + */ +public final class LRUMapTestCase extends Assert { + + @Test + public void testLRU() { + LRUMap map = new LRUMap<>(2); + map.put("foo", "bar"); + map.put("bar", "baz"); + assertEquals("bar", map.get("foo")); + assertEquals("baz", map.get("bar")); + map.put("baz", "bing"); + assertEquals("bing", map.get("baz")); + assertNull(map.get("foo")); + } + +} diff --git a/zxingorg/src/test/java/com/google/zxing/web/WelcomeFilterTestCase.java b/zxingorg/src/test/java/com/google/zxing/web/WelcomeFilterTestCase.java new file mode 100644 index 000000000..94b8d0eb4 --- /dev/null +++ b/zxingorg/src/test/java/com/google/zxing/web/WelcomeFilterTestCase.java @@ -0,0 +1,44 @@ +/* + * Copyright 2018 ZXing authors + * + * Licensed 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 com.google.zxing.web; + +import com.google.common.net.HttpHeaders; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.mock.web.MockFilterChain; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import javax.servlet.http.HttpServletResponse; + +/** + * Tests {@link WelcomeFilter}. + */ +public final class WelcomeFilterTestCase extends Assert { + + @Test + public void testRedirect() { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setRequestURI("/"); + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterChain chain = new MockFilterChain(); + new WelcomeFilter().doFilter(request, response, chain); + assertEquals(HttpServletResponse.SC_MOVED_PERMANENTLY, response.getStatus()); + assertEquals("/w/decode.jspx", response.getHeader(HttpHeaders.LOCATION)); + } + +}