mirror of
https://github.com/zxing/zxing.git
synced 2024-11-09 20:44:03 -08:00
Fix bug in decoding data URIs; Add tests in javase/, zxingorg/
This commit is contained in:
parent
e1b127c13a
commit
d907537c05
|
@ -21,7 +21,6 @@ import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URLDecoder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates reading URIs as images.
|
* Encapsulates reading URIs as images.
|
||||||
|
@ -60,8 +59,7 @@ public final class ImageReader {
|
||||||
if (base64Start < 0) {
|
if (base64Start < 0) {
|
||||||
throw new IOException("Unsupported data URI encoding");
|
throw new IOException("Unsupported data URI encoding");
|
||||||
}
|
}
|
||||||
String base64DataEncoded = uriString.substring(base64Start + BASE64TOKEN.length());
|
String base64Data = uriString.substring(base64Start + BASE64TOKEN.length());
|
||||||
String base64Data = URLDecoder.decode(base64DataEncoded, "UTF-8");
|
|
||||||
byte[] imageBytes = Base64Decoder.getInstance().decode(base64Data);
|
byte[] imageBytes = Base64Decoder.getInstance().decode(base64Data);
|
||||||
return ImageIO.read(new ByteArrayInputStream(imageBytes));
|
return ImageIO.read(new ByteArrayInputStream(imageBytes));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<URI> inputs = new LinkedList<>(Collections.singletonList(new URI(IMAGE_DATA_URI)));
|
||||||
|
DecodeWorker worker = new DecodeWorker(config, inputs);
|
||||||
|
assertEquals(1, worker.call().intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -28,7 +28,7 @@ import java.net.URI;
|
||||||
public final class ImageReaderTestCase extends Assert {
|
public final class ImageReaderTestCase extends Assert {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFoo() throws Exception {
|
public void testDataURI() throws Exception {
|
||||||
String uri =
|
String uri =
|
||||||
"data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////w" +
|
"data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////w" +
|
||||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6" +
|
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6" +
|
||||||
|
|
|
@ -68,10 +68,9 @@ public final class Generator implements EntryPoint {
|
||||||
|
|
||||||
setupLeftPanel();
|
setupLeftPanel();
|
||||||
topPanel.getElement().setId("leftpanel");
|
topPanel.getElement().setId("leftpanel");
|
||||||
Widget leftPanel = topPanel;
|
|
||||||
|
|
||||||
HorizontalPanel mainPanel = new HorizontalPanel();
|
HorizontalPanel mainPanel = new HorizontalPanel();
|
||||||
mainPanel.add(leftPanel);
|
mainPanel.add(topPanel);
|
||||||
|
|
||||||
SimplePanel div2 = new SimplePanel();
|
SimplePanel div2 = new SimplePanel();
|
||||||
div2.add(result);
|
div2.add(result);
|
||||||
|
|
|
@ -39,13 +39,17 @@ import java.util.concurrent.TimeUnit;
|
||||||
@WebFilter({"/w/decode", "/w/chart"})
|
@WebFilter({"/w/decode", "/w/chart"})
|
||||||
public final class DoSFilter implements Filter {
|
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 Timer timer;
|
||||||
private DoSTracker sourceAddrTracker;
|
private DoSTracker sourceAddrTracker;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(FilterConfig filterConfig) {
|
public void init(FilterConfig filterConfig) {
|
||||||
timer = new Timer("DoSFilter");
|
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(
|
timer.scheduleAtFixedRate(
|
||||||
new TimerTask() {
|
new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -38,7 +38,7 @@ final class DoSTracker {
|
||||||
DoSTracker(Timer timer, final int maxAccessesPerTime, long accessTimeMS, int maxEntries) {
|
DoSTracker(Timer timer, final int maxAccessesPerTime, long accessTimeMS, int maxEntries) {
|
||||||
this.maxAccessesPerTime = maxAccessesPerTime;
|
this.maxAccessesPerTime = maxAccessesPerTime;
|
||||||
this.numRecentAccesses = new LRUMap<>(maxEntries);
|
this.numRecentAccesses = new LRUMap<>(maxEntries);
|
||||||
timer.scheduleAtFixedRate(new TimerTask() {
|
timer.schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
synchronized (numRecentAccesses) {
|
synchronized (numRecentAccesses) {
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -42,7 +42,6 @@ public final class HTTPSFilterTestCase extends Assert {
|
||||||
request.setRequestURI("/path");
|
request.setRequestURI("/path");
|
||||||
response = new MockHttpServletResponse();
|
response = new MockHttpServletResponse();
|
||||||
chain = new MockFilterChain();
|
chain = new MockFilterChain();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -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<String,String> 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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue