DecodeServlet.java (zxing-zxing-3.4.0) | : | DecodeServlet.java (zxing-zxing-3.4.1) | ||
---|---|---|---|---|
skipping to change at line 62 | skipping to change at line 62 | |||
import java.util.ArrayList; | import java.util.ArrayList; | |||
import java.util.Arrays; | import java.util.Arrays; | |||
import java.util.Collection; | import java.util.Collection; | |||
import java.util.Collections; | import java.util.Collections; | |||
import java.util.EnumMap; | import java.util.EnumMap; | |||
import java.util.EnumSet; | import java.util.EnumSet; | |||
import java.util.Locale; | import java.util.Locale; | |||
import java.util.Map; | import java.util.Map; | |||
import java.util.ResourceBundle; | import java.util.ResourceBundle; | |||
import java.util.Timer; | import java.util.Timer; | |||
import java.util.TimerTask; | ||||
import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | |||
import java.util.logging.Level; | import java.util.logging.Level; | |||
import java.util.logging.Logger; | import java.util.logging.Logger; | |||
import java.util.regex.Pattern; | import java.util.regex.Pattern; | |||
import javax.imageio.ImageIO; | import javax.imageio.ImageIO; | |||
import javax.servlet.RequestDispatcher; | import javax.servlet.RequestDispatcher; | |||
import javax.servlet.ServletConfig; | import javax.servlet.ServletConfig; | |||
import javax.servlet.ServletContext; | import javax.servlet.ServletContext; | |||
import javax.servlet.ServletException; | import javax.servlet.ServletException; | |||
skipping to change at line 106 | skipping to change at line 105 | |||
}) | }) | |||
public final class DecodeServlet extends HttpServlet { | public final class DecodeServlet extends HttpServlet { | |||
private static final Logger log = Logger.getLogger(DecodeServlet.class.getName ()); | private static final Logger log = Logger.getLogger(DecodeServlet.class.getName ()); | |||
private static final Pattern WHITESPACE = Pattern.compile("\\s+"); | private static final Pattern WHITESPACE = Pattern.compile("\\s+"); | |||
// No real reason to let people upload more than ~64MB | // No real reason to let people upload more than ~64MB | |||
private static final long MAX_IMAGE_SIZE = 1L << 26; | private static final long MAX_IMAGE_SIZE = 1L << 26; | |||
// No real reason to deal with more than ~32 megapixels | // No real reason to deal with more than ~32 megapixels | |||
private static final int MAX_PIXELS = 1 << 25; | private static final int MAX_PIXELS = 1 << 25; | |||
private static final byte[] REMAINDER_BUFFER = new byte[1 << 16]; | ||||
private static final Map<DecodeHintType,Object> HINTS; | private static final Map<DecodeHintType,Object> HINTS; | |||
private static final Map<DecodeHintType,Object> HINTS_PURE; | private static final Map<DecodeHintType,Object> HINTS_PURE; | |||
static { | static { | |||
HINTS = new EnumMap<>(DecodeHintType.class); | HINTS = new EnumMap<>(DecodeHintType.class); | |||
HINTS.put(DecodeHintType.TRY_HARDER, Boolean.TRUE); | HINTS.put(DecodeHintType.TRY_HARDER, Boolean.TRUE); | |||
HINTS.put(DecodeHintType.POSSIBLE_FORMATS, EnumSet.allOf(BarcodeFormat.class )); | HINTS.put(DecodeHintType.POSSIBLE_FORMATS, EnumSet.allOf(BarcodeFormat.class )); | |||
HINTS_PURE = new EnumMap<>(HINTS); | HINTS_PURE = new EnumMap<>(HINTS); | |||
HINTS_PURE.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE); | HINTS_PURE.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE); | |||
} | } | |||
skipping to change at line 147 | skipping to change at line 145 | |||
log.info("Blocking URIs containing: " + blockedURLSubstrings); | log.info("Blocking URIs containing: " + blockedURLSubstrings); | |||
} | } | |||
int maxAccessPerTime = Integer.parseInt(servletConfig.getInitParameter("maxA ccessPerTime")); | int maxAccessPerTime = Integer.parseInt(servletConfig.getInitParameter("maxA ccessPerTime")); | |||
int accessTimeSec = Integer.parseInt(servletConfig.getInitParameter("accessT imeSec")); | int accessTimeSec = Integer.parseInt(servletConfig.getInitParameter("accessT imeSec")); | |||
long accessTimeMS = TimeUnit.MILLISECONDS.convert(accessTimeSec, TimeUnit.SE CONDS); | long accessTimeMS = TimeUnit.MILLISECONDS.convert(accessTimeSec, TimeUnit.SE CONDS); | |||
int maxEntries = Integer.parseInt(servletConfig.getInitParameter("maxEntries ")); | int maxEntries = Integer.parseInt(servletConfig.getInitParameter("maxEntries ")); | |||
String name = getClass().getSimpleName(); | String name = getClass().getSimpleName(); | |||
timer = new Timer(name); | timer = new Timer(name); | |||
destHostTracker = new DoSTracker(timer, name, maxAccessPerTime, accessTimeMS | destHostTracker = new DoSTracker(timer, name, maxAccessPerTime, accessTimeMS | |||
, maxEntries); | , maxEntries, null); | |||
// Hack to try to avoid odd OOM due to memory leak in JAI? | ||||
timer.scheduleAtFixedRate( | ||||
new TimerTask() { | ||||
@Override | ||||
public void run() { | ||||
System.gc(); | ||||
} | ||||
}, 0L, TimeUnit.MILLISECONDS.convert(10, TimeUnit.MINUTES)); | ||||
} | } | |||
@Override | @Override | |||
public void destroy() { | public void destroy() { | |||
if (timer != null) { | if (timer != null) { | |||
timer.cancel(); | timer.cancel(); | |||
} | } | |||
} | } | |||
@Override | @Override | |||
skipping to change at line 276 | skipping to change at line 266 | |||
// java.net.SocketException, java.net.UnknownHostException, | // java.net.SocketException, java.net.UnknownHostException, | |||
// javax.net.ssl.SSLPeerUnverifiedException, | // javax.net.ssl.SSLPeerUnverifiedException, | |||
// org.apache.http.NoHttpResponseException, | // org.apache.http.NoHttpResponseException, | |||
// org.apache.http.client.ClientProtocolException, | // org.apache.http.client.ClientProtocolException, | |||
log.info("Error " + e + " connecting to " + imageURIString); | log.info("Error " + e + " connecting to " + imageURIString); | |||
errorResponse(request, response, "badurl"); | errorResponse(request, response, "badurl"); | |||
return; | return; | |||
} | } | |||
try (InputStream is = connection.getInputStream()) { | try (InputStream is = connection.getInputStream()) { | |||
try { | if (connection.getResponseCode() != HttpServletResponse.SC_OK) { | |||
if (connection.getResponseCode() != HttpServletResponse.SC_OK) { | log.info("Unsuccessful return code " + connection.getResponseCode() + " | |||
log.info("Unsuccessful return code " + connection.getResponseCode() + | from " + imageURIString); | |||
" from " + imageURIString); | errorResponse(request, response, "badurl"); | |||
errorResponse(request, response, "badurl"); | return; | |||
return; | ||||
} | ||||
if (connection.getHeaderFieldInt(HttpHeaders.CONTENT_LENGTH, 0) > MAX_IM | ||||
AGE_SIZE) { | ||||
log.info("Too large: " + imageURIString); | ||||
errorResponse(request, response, "badimage"); | ||||
return; | ||||
} | ||||
// Assume we'll only handle image/* content types | ||||
String contentType = connection.getContentType(); | ||||
if (contentType != null && !contentType.startsWith("image/")) { | ||||
log.info("Wrong content type " + contentType + ": " + imageURIString); | ||||
errorResponse(request, response, "badimage"); | ||||
return; | ||||
} | ||||
log.info("Decoding " + imageURIString); | ||||
processStream(is, request, response); | ||||
} finally { | ||||
consumeRemainder(is); | ||||
} | } | |||
if (connection.getHeaderFieldInt(HttpHeaders.CONTENT_LENGTH, 0) > MAX_IMAG | ||||
E_SIZE) { | ||||
log.info("Too large: " + imageURIString); | ||||
errorResponse(request, response, "badimage"); | ||||
return; | ||||
} | ||||
// Assume we'll only handle image/* content types | ||||
String contentType = connection.getContentType(); | ||||
if (contentType != null && !contentType.startsWith("image/")) { | ||||
log.info("Wrong content type " + contentType + ": " + imageURIString); | ||||
errorResponse(request, response, "badimage"); | ||||
return; | ||||
} | ||||
log.info("Decoding " + imageURIString); | ||||
processStream(is, request, response); | ||||
} catch (IOException ioe) { | } catch (IOException ioe) { | |||
log.info("Error " + ioe + " processing " + imageURIString); | log.info("Error " + ioe + " processing " + imageURIString); | |||
errorResponse(request, response, "badurl"); | errorResponse(request, response, "badurl"); | |||
} finally { | } finally { | |||
connection.disconnect(); | connection.disconnect(); | |||
} | } | |||
} | } | |||
private static void consumeRemainder(InputStream is) { | ||||
try { | ||||
while (is.read(REMAINDER_BUFFER) > 0) { | ||||
// don't care about value, or collision | ||||
} | ||||
} catch (IOException | IndexOutOfBoundsException ioe) { | ||||
// sun.net.www.http.ChunkedInputStream.read is throwing IndexOutOfBoundsEx | ||||
ception | ||||
// continue | ||||
} | ||||
} | ||||
@Override | @Override | |||
protected void doPost(HttpServletRequest request, HttpServletResponse response ) | protected void doPost(HttpServletRequest request, HttpServletResponse response ) | |||
throws ServletException, IOException { | throws ServletException, IOException { | |||
Collection<Part> parts; | Collection<Part> parts; | |||
try { | try { | |||
parts = request.getParts(); | parts = request.getParts(); | |||
} catch (Exception e) { | } catch (Exception e) { | |||
// Includes IOException, InvalidContentTypeException, other parsing Illega lStateException | // Includes IOException, InvalidContentTypeException, other parsing Illega lStateException | |||
log.info(e.toString()); | log.info(e.toString()); | |||
errorResponse(request, response, "badimage"); | errorResponse(request, response, "badimage"); | |||
End of changes. 6 change blocks. | ||||
49 lines changed or deleted | 23 lines changed or added |