Added: websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/InvalidFileNameException.java.html ============================================================================== --- websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/InvalidFileNameException.java.html (added) +++ websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/InvalidFileNameException.java.html Mon Feb 13 10:43:35 2023 @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>InvalidFileNameException.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons FileUpload</a> > <a href="index.source.html" class="el_package">org.apache.commons.fileupload</a> > <s pan class="el_source">InvalidFileNameException.java</span></div><h1>InvalidFileNameException.java</h1><pre class="source lang-java linenums">/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.fileupload; + +/** + * This exception is thrown in case of an invalid file name. + * A file name is invalid, if it contains a NUL character. + * Attackers might use this to circumvent security checks: + * For example, a malicious user might upload a file with the name + * "foo.exe\0.png". This file name might pass security checks (i.e. + * checks for the extension ".png"), while, depending on the underlying + * C library, it might create a file named "foo.exe", as the NUL + * character is the string terminator in C. + */ +public class InvalidFileNameException extends RuntimeException { + + /** + * Serial version UID, being used, if the exception + * is serialized. + */ + private static final long serialVersionUID = 7922042602454350470L; + + /** + * The file name causing the exception. + */ + private final String name; + + /** + * Creates a new instance. + * + * @param pName The file name causing the exception. + * @param pMessage A human readable error message. + */ + public InvalidFileNameException(String pName, String pMessage) { +<span class="fc" id="L49"> super(pMessage);</span> +<span class="fc" id="L50"> name = pName;</span> +<span class="fc" id="L51"> }</span> + + /** + * Returns the invalid file name. + * + * @return the invalid file name. + */ + public String getName() { +<span class="fc" id="L59"> return name;</span> + } + +} +</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.8.202204050719</span></div></body></html> \ No newline at end of file
Added: websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$IllegalBoundaryException.html ============================================================================== --- websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$IllegalBoundaryException.html (added) +++ websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$IllegalBoundaryException.html Mon Feb 13 10:43:35 2023 @@ -0,0 +1 @@ +<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>MultipartStream.IllegalBoundaryException</title><script type="text/javascript" src="../jacoco-resources/sort.js"></script></head><body onload="initialSort(['breadcrumb'])"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons FileUpload</a> > <a href="index.html" class="el_package">org.apache.commons.fileupload</a> > <span class="el_class">MultipartStream.IllegalBoundaryException</span></div><h1>MultipartStre am.IllegalBoundaryException</h1><table class="coverage" cellspacing="0" id="coveragetable"><thead><tr><td class="sortable" id="a" onclick="toggleSort(this)">Element</td><td class="down sortable bar" id="b" onclick="toggleSort(this)">Missed Instructions</td><td class="sortable ctr2" id="c" onclick="toggleSort(this)">Cov.</td><td class="sortable bar" id="d" onclick="toggleSort(this)">Missed Branches</td><td class="sortable ctr2" id="e" onclick="toggleSort(this)">Cov.</td><td class="sortable ctr1" id="f" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="g" onclick="toggleSort(this)">Cxty</td><td class="sortable ctr1" id="h" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="i" onclick="toggleSort(this)">Lines</td><td class="sortable ctr1" id="j" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="k" onclick="toggleSort(this)">Methods</td></tr></thead><tfoot><tr><td>Total</td><td class="bar">7 of 7</td><td class="ctr2">0%</td><td class= "bar">0 of 0</td><td class="ctr2">n/a</td><td class="ctr1">2</td><td class="ctr2">2</td><td class="ctr1">4</td><td class="ctr2">4</td><td class="ctr1">2</td><td class="ctr2">2</td></tr></tfoot><tbody><tr><td id="a1"><a href="MultipartStream.java.html#L806" class="el_method">MultipartStream.IllegalBoundaryException(String)</a></td><td class="bar" id="b0"><img src="../jacoco-resources/redbar.gif" width="120" height="10" title="4" alt="4"/></td><td class="ctr2" id="c0">0%</td><td class="bar" id="d0"/><td class="ctr2" id="e0">n/a</td><td class="ctr1" id="f0">1</td><td class="ctr2" id="g0">1</td><td class="ctr1" id="h0">2</td><td class="ctr2" id="i0">2</td><td class="ctr1" id="j0">1</td><td class="ctr2" id="k0">1</td></tr><tr><td id="a0"><a href="MultipartStream.java.html#L796" class="el_method">MultipartStream.IllegalBoundaryException()</a></td><td class="bar" id="b1"><img src="../jacoco-resources/redbar.gif" width="90" height="10" title="3" alt="3"/></td><td class="ctr2" id="c1">0%</td ><td class="bar" id="d1"/><td class="ctr2" id="e1">n/a</td><td class="ctr1" >id="f1">1</td><td class="ctr2" id="g1">1</td><td class="ctr1" >id="h1">2</td><td class="ctr2" id="i1">2</td><td class="ctr1" >id="j1">1</td><td class="ctr2" id="k1">1</td></tr></tbody></table><div >class="footer"><span class="right">Created with <a >href="http://www.jacoco.org/jacoco">JaCoCo</a> >0.8.8.202204050719</span></div></body></html> \ No newline at end of file Added: websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$ItemInputStream.html ============================================================================== --- websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$ItemInputStream.html (added) +++ websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$ItemInputStream.html Mon Feb 13 10:43:35 2023 @@ -0,0 +1 @@ +<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>MultipartStream.ItemInputStream</title><script type="text/javascript" src="../jacoco-resources/sort.js"></script></head><body onload="initialSort(['breadcrumb'])"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons FileUpload</a> > <a href="index.html" class="el_package">org.apache.commons.fileupload</a> > <span class="el_class">MultipartStream.ItemInputStream</span></div><h1>MultipartStream.ItemInputStream </h1><table class="coverage" cellspacing="0" id="coveragetable"><thead><tr><td class="sortable" id="a" onclick="toggleSort(this)">Element</td><td class="down sortable bar" id="b" onclick="toggleSort(this)">Missed Instructions</td><td class="sortable ctr2" id="c" onclick="toggleSort(this)">Cov.</td><td class="sortable bar" id="d" onclick="toggleSort(this)">Missed Branches</td><td class="sortable ctr2" id="e" onclick="toggleSort(this)">Cov.</td><td class="sortable ctr1" id="f" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="g" onclick="toggleSort(this)">Cxty</td><td class="sortable ctr1" id="h" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="i" onclick="toggleSort(this)">Lines</td><td class="sortable ctr1" id="j" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="k" onclick="toggleSort(this)">Methods</td></tr></thead><tfoot><tr><td>Total</td><td class="bar">56 of 349</td><td class="ctr2">83%</td><td class="bar">12 of 46</td><td class="ctr2">73%</td><td class="ctr1">11</td><td class="ctr2">34</td><td class="ctr1">16</td><td class="ctr2">81</td><td class="ctr1">2</td><td class="ctr2">11</td></tr></tfoot><tbody><tr><td id="a10"><a href="MultipartStream.java.html#L992" class="el_method">skip(long)</a></td><td class="bar" id="b0"><img src="../jacoco-resources/redbar.gif" width="40" height="10" title="37" alt="37"/></td><td class="ctr2" id="c9">0%</td><td class="bar" id="d0"><img src="../jacoco-resources/redbar.gif" width="72" height="10" title="6" alt="6"/></td><td class="ctr2" id="e6">0%</td><td class="ctr1" id="f0">4</td><td class="ctr2" id="g4">4</td><td class="ctr1" id="h0">10</td><td class="ctr2" id="i3">10</td><td class="ctr1" id="j0">1</td><td class="ctr2" id="k0">1</td></tr><tr><td id="a9"><a href="MultipartStream.java.html#L923" class="el_method">read(byte[], int, int)</a></td><td class="bar" id="b1"><img src="../jacoco-resources/redbar.gif" width="6" height="10" title="6" alt="6"/><img src="../jacoco- resources/greenbar.gif" width="53" height="10" title="49" alt="49"/></td><td class="ctr2" id="c7">89%</td><td class="bar" id="d1"><img src="../jacoco-resources/redbar.gif" width="24" height="10" title="2" alt="2"/><img src="../jacoco-resources/greenbar.gif" width="72" height="10" title="6" alt="6"/></td><td class="ctr2" id="e4">75%</td><td class="ctr1" id="f1">2</td><td class="ctr2" id="g1">5</td><td class="ctr1" id="h1">2</td><td class="ctr2" id="i1">14</td><td class="ctr1" id="j2">0</td><td class="ctr2" id="k1">1</td></tr><tr><td id="a2"><a href="MultipartStream.java.html#L961" class="el_method">close(boolean)</a></td><td class="bar" id="b2"><img src="../jacoco-resources/redbar.gif" width="6" height="10" title="6" alt="6"/><img src="../jacoco-resources/greenbar.gif" width="31" height="10" title="29" alt="29"/></td><td class="ctr2" id="c8">82%</td><td class="bar" id="d2"><img src="../jacoco-resources/redbar.gif" width="24" height="10" title="2" alt="2"/><img src="../jacoco-resource s/greenbar.gif" width="72" height="10" title="6" alt="6"/></td><td class="ctr2" id="e5">75%</td><td class="ctr1" id="f2">2</td><td class="ctr2" id="g2">5</td><td class="ctr1" id="h2">2</td><td class="ctr2" id="i2">14</td><td class="ctr1" id="j3">0</td><td class="ctr2" id="k2">1</td></tr><tr><td id="a8"><a href="MultipartStream.java.html#L897" class="el_method">read()</a></td><td class="bar" id="b3"><img src="../jacoco-resources/redbar.gif" width="4" height="10" title="4" alt="4"/><img src="../jacoco-resources/greenbar.gif" width="36" height="10" title="33" alt="33"/></td><td class="ctr2" id="c6">89%</td><td class="bar" id="d4"><img src="../jacoco-resources/redbar.gif" width="12" height="10" title="1" alt="1"/><img src="../jacoco-resources/greenbar.gif" width="84" height="10" title="7" alt="7"/></td><td class="ctr2" id="e3">87%</td><td class="ctr1" id="f3">1</td><td class="ctr2" id="g3">5</td><td class="ctr1" id="h3">1</td><td class="ctr2" id="i4">9</td><td class="ctr1" id="j4">0</td ><td class="ctr2" id="k3">1</td></tr><tr><td id="a4"><a >href="MultipartStream.java.html#L865" >class="el_method">getBytesRead()</a></td><td class="bar" id="b4"><img >src="../jacoco-resources/redbar.gif" width="3" height="10" title="3" >alt="3"/></td><td class="ctr2" id="c10">0%</td><td class="bar" id="d7"/><td >class="ctr2" id="e7">n/a</td><td class="ctr1" id="f4">1</td><td class="ctr2" >id="g7">1</td><td class="ctr1" id="h4">1</td><td class="ctr2" >id="i9">1</td><td class="ctr1" id="j1">1</td><td class="ctr2" >id="k4">1</td></tr><tr><td id="a6"><a href="MultipartStream.java.html#L1014" >class="el_method">makeAvailable()</a></td><td class="bar" id="b5"><img >src="../jacoco-resources/greenbar.gif" width="120" height="10" title="109" >alt="109"/></td><td class="ctr2" id="c0">100%</td><td class="bar" >id="d3"><img src="../jacoco-resources/redbar.gif" width="12" height="10" >title="1" alt="1"/><img src="../jacoco-resources/greenbar.gif" width="108" >height="10" title="9" alt="9"/></td><td class="ctr 2" id="e2">90%</td><td class="ctr1" id="f5">1</td><td class="ctr2" id="g0">6</td><td class="ctr1" id="h5">0</td><td class="ctr2" id="i0">18</td><td class="ctr1" id="j5">0</td><td class="ctr2" id="k5">1</td></tr><tr><td id="a3"><a href="MultipartStream.java.html#L848" class="el_method">findSeparator()</a></td><td class="bar" id="b6"><img src="../jacoco-resources/greenbar.gif" width="39" height="10" title="36" alt="36"/></td><td class="ctr2" id="c1">100%</td><td class="bar" id="d5"><img src="../jacoco-resources/greenbar.gif" width="48" height="10" title="4" alt="4"/></td><td class="ctr2" id="e0">100%</td><td class="ctr1" id="f6">0</td><td class="ctr2" id="g5">3</td><td class="ctr1" id="h6">0</td><td class="ctr2" id="i5">6</td><td class="ctr1" id="j6">0</td><td class="ctr2" id="k6">1</td></tr><tr><td id="a0"><a href="MultipartStream.java.html#L877" class="el_method">available()</a></td><td class="bar" id="b7"><img src="../jacoco-resources/greenbar.gif" width="24" height="10" title="22" alt="22"/></td><td class="ctr2" id="c2">100%</td><td class="bar" id="d6"><img src="../jacoco-resources/greenbar.gif" width="24" height="10" title="2" alt="2"/></td><td class="ctr2" id="e1">100%</td><td class="ctr1" id="f7">0</td><td class="ctr2" id="g6">2</td><td class="ctr1" id="h7">0</td><td class="ctr2" id="i6">3</td><td class="ctr1" id="j7">0</td><td class="ctr2" id="k7">1</td></tr><tr><td id="a7"><a href="MultipartStream.java.html#L840" class="el_method">MultipartStream.ItemInputStream(MultipartStream)</a></td><td class="bar" id="b8"><img src="../jacoco-resources/greenbar.gif" width="8" height="10" title="8" alt="8"/></td><td class="ctr2" id="c3">100%</td><td class="bar" id="d8"/><td class="ctr2" id="e8">n/a</td><td class="ctr1" id="f8">0</td><td class="ctr2" id="g8">1</td><td class="ctr1" id="h8">0</td><td class="ctr2" id="i7">3</td><td class="ctr1" id="j8">0</td><td class="ctr2" id="k8">1</td></tr><tr><td id="a1"><a href="MultipartStream.java.html#L950" class="el_method">clo se()</a></td><td class="bar" id="b9"><img src="../jacoco-resources/greenbar.gif" width="4" height="10" title="4" alt="4"/></td><td class="ctr2" id="c4">100%</td><td class="bar" id="d9"/><td class="ctr2" id="e9">n/a</td><td class="ctr1" id="f9">0</td><td class="ctr2" id="g9">1</td><td class="ctr1" id="h9">0</td><td class="ctr2" id="i8">2</td><td class="ctr1" id="j9">0</td><td class="ctr2" id="k9">1</td></tr><tr><td id="a5"><a href="MultipartStream.java.html#L1056" class="el_method">isClosed()</a></td><td class="bar" id="b10"><img src="../jacoco-resources/greenbar.gif" width="3" height="10" title="3" alt="3"/></td><td class="ctr2" id="c5">100%</td><td class="bar" id="d10"/><td class="ctr2" id="e10">n/a</td><td class="ctr1" id="f10">0</td><td class="ctr2" id="g10">1</td><td class="ctr1" id="h10">0</td><td class="ctr2" id="i10">1</td><td class="ctr1" id="j10">0</td><td class="ctr2" id="k10">1</td></tr></tbody></table><div class="footer"><span class="right">Created with <a href="http://w ww.jacoco.org/jacoco">JaCoCo</a> 0.8.8.202204050719</span></div></body></html> \ No newline at end of file Added: websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$MalformedStreamException.html ============================================================================== --- websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$MalformedStreamException.html (added) +++ websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$MalformedStreamException.html Mon Feb 13 10:43:35 2023 @@ -0,0 +1 @@ +<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>MultipartStream.MalformedStreamException</title><script type="text/javascript" src="../jacoco-resources/sort.js"></script></head><body onload="initialSort(['breadcrumb'])"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons FileUpload</a> > <a href="index.html" class="el_package">org.apache.commons.fileupload</a> > <span class="el_class">MultipartStream.MalformedStreamException</span></div><h1>MultipartStre am.MalformedStreamException</h1><table class="coverage" cellspacing="0" id="coveragetable"><thead><tr><td class="sortable" id="a" onclick="toggleSort(this)">Element</td><td class="down sortable bar" id="b" onclick="toggleSort(this)">Missed Instructions</td><td class="sortable ctr2" id="c" onclick="toggleSort(this)">Cov.</td><td class="sortable bar" id="d" onclick="toggleSort(this)">Missed Branches</td><td class="sortable ctr2" id="e" onclick="toggleSort(this)">Cov.</td><td class="sortable ctr1" id="f" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="g" onclick="toggleSort(this)">Cxty</td><td class="sortable ctr1" id="h" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="i" onclick="toggleSort(this)">Lines</td><td class="sortable ctr1" id="j" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="k" onclick="toggleSort(this)">Methods</td></tr></thead><tfoot><tr><td>Total</td><td class="bar">3 of 7</td><td class="ctr2">57%</td><td class ="bar">0 of 0</td><td class="ctr2">n/a</td><td class="ctr1">1</td><td class="ctr2">2</td><td class="ctr1">2</td><td class="ctr2">4</td><td class="ctr1">1</td><td class="ctr2">2</td></tr></tfoot><tbody><tr><td id="a0"><a href="MultipartStream.java.html#L766" class="el_method">MultipartStream.MalformedStreamException()</a></td><td class="bar" id="b0"><img src="../jacoco-resources/redbar.gif" width="90" height="10" title="3" alt="3"/></td><td class="ctr2" id="c1">0%</td><td class="bar" id="d0"/><td class="ctr2" id="e0">n/a</td><td class="ctr1" id="f0">1</td><td class="ctr2" id="g0">1</td><td class="ctr1" id="h0">2</td><td class="ctr2" id="i0">2</td><td class="ctr1" id="j0">1</td><td class="ctr2" id="k0">1</td></tr><tr><td id="a1"><a href="MultipartStream.java.html#L776" class="el_method">MultipartStream.MalformedStreamException(String)</a></td><td class="bar" id="b1"><img src="../jacoco-resources/greenbar.gif" width="120" height="10" title="4" alt="4"/></td><td class="ctr2" id="c0">100 %</td><td class="bar" id="d1"/><td class="ctr2" id="e1">n/a</td><td class="ctr1" id="f1">0</td><td class="ctr2" id="g1">1</td><td class="ctr1" id="h1">0</td><td class="ctr2" id="i1">2</td><td class="ctr1" id="j1">0</td><td class="ctr2" id="k1">1</td></tr></tbody></table><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.8.202204050719</span></div></body></html> \ No newline at end of file Added: websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$ProgressNotifier.html ============================================================================== --- websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$ProgressNotifier.html (added) +++ websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream$ProgressNotifier.html Mon Feb 13 10:43:35 2023 @@ -0,0 +1 @@ +<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>MultipartStream.ProgressNotifier</title><script type="text/javascript" src="../jacoco-resources/sort.js"></script></head><body onload="initialSort(['breadcrumb'])"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons FileUpload</a> > <a href="index.html" class="el_package">org.apache.commons.fileupload</a> > <span class="el_class">MultipartStream.ProgressNotifier</span></div><h1>MultipartStream.ProgressNotif ier</h1><table class="coverage" cellspacing="0" id="coveragetable"><thead><tr><td class="sortable" id="a" onclick="toggleSort(this)">Element</td><td class="down sortable bar" id="b" onclick="toggleSort(this)">Missed Instructions</td><td class="sortable ctr2" id="c" onclick="toggleSort(this)">Cov.</td><td class="sortable bar" id="d" onclick="toggleSort(this)">Missed Branches</td><td class="sortable ctr2" id="e" onclick="toggleSort(this)">Cov.</td><td class="sortable ctr1" id="f" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="g" onclick="toggleSort(this)">Cxty</td><td class="sortable ctr1" id="h" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="i" onclick="toggleSort(this)">Lines</td><td class="sortable ctr1" id="j" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="k" onclick="toggleSort(this)">Methods</td></tr></thead><tfoot><tr><td>Total</td><td class="bar">0 of 41</td><td class="ctr2">100%</td><td class="bar">0 of 2</td><td class="ctr2">100%</td><td class="ctr1">0</td><td class="ctr2">5</td><td class="ctr1">0</td><td class="ctr2">13</td><td class="ctr1">0</td><td class="ctr2">4</td></tr></tfoot><tbody><tr><td id="a3"><a href="MultipartStream.java.html#L149" class="el_method">notifyListener()</a></td><td class="bar" id="b0"><img src="../jacoco-resources/greenbar.gif" width="120" height="10" title="13" alt="13"/></td><td class="ctr2" id="c0">100%</td><td class="bar" id="d0"><img src="../jacoco-resources/greenbar.gif" width="120" height="10" title="2" alt="2"/></td><td class="ctr2" id="e0">100%</td><td class="ctr1" id="f0">0</td><td class="ctr2" id="g0">2</td><td class="ctr1" id="h0">0</td><td class="ctr2" id="i1">3</td><td class="ctr1" id="j0">0</td><td class="ctr2" id="k0">1</td></tr><tr><td id="a1"><a href="MultipartStream.java.html#L133" class="el_method">noteBytesRead(int)</a></td><td class="bar" id="b1"><img src="../jacoco-resources/greenbar.gif" width="92" height="10" title="10" alt="10"/></td><td class="ctr2" id="c1">100%</td><td class="bar" id="d1"/><td class="ctr2" id="e1">n/a</td><td class="ctr1" id="f1">0</td><td class="ctr2" id="g1">1</td><td class="ctr1" id="h1">0</td><td class="ctr2" id="i2">3</td><td class="ctr1" id="j1">0</td><td class="ctr2" id="k1">1</td></tr><tr><td id="a0"><a href="MultipartStream.java.html#L119" class="el_method">MultipartStream.ProgressNotifier(ProgressListener, long)</a></td><td class="bar" id="b2"><img src="../jacoco-resources/greenbar.gif" width="83" height="10" title="9" alt="9"/></td><td class="ctr2" id="c2">100%</td><td class="bar" id="d2"/><td class="ctr2" id="e2">n/a</td><td class="ctr1" id="f2">0</td><td class="ctr2" id="g2">1</td><td class="ctr1" id="h2">0</td><td class="ctr2" id="i0">4</td><td class="ctr1" id="j2">0</td><td class="ctr2" id="k2">1</td></tr><tr><td id="a2"><a href="MultipartStream.java.html#L141" class="el_method">noteItem()</a></td><td class="bar" id="b3"><img src="../jacoco-resources/greenbar.gif" width="83" height= "10" title="9" alt="9"/></td><td class="ctr2" id="c3">100%</td><td class="bar" id="d3"/><td class="ctr2" id="e3">n/a</td><td class="ctr1" id="f3">0</td><td class="ctr2" id="g3">1</td><td class="ctr1" id="h3">0</td><td class="ctr2" id="i3">3</td><td class="ctr1" id="j3">0</td><td class="ctr2" id="k3">1</td></tr></tbody></table><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.8.202204050719</span></div></body></html> \ No newline at end of file Added: websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream.html ============================================================================== --- websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream.html (added) +++ websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream.html Mon Feb 13 10:43:35 2023 @@ -0,0 +1 @@ +<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>MultipartStream</title><script type="text/javascript" src="../jacoco-resources/sort.js"></script></head><body onload="initialSort(['breadcrumb'])"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons FileUpload</a> > <a href="index.html" class="el_package">org.apache.commons.fileupload</a> > <span class="el_class">MultipartStream</span></div><h1>MultipartStream</h1><table class="coverage" cellspacing="0" id= "coveragetable"><thead><tr><td class="sortable" id="a" onclick="toggleSort(this)">Element</td><td class="down sortable bar" id="b" onclick="toggleSort(this)">Missed Instructions</td><td class="sortable ctr2" id="c" onclick="toggleSort(this)">Cov.</td><td class="sortable bar" id="d" onclick="toggleSort(this)">Missed Branches</td><td class="sortable ctr2" id="e" onclick="toggleSort(this)">Cov.</td><td class="sortable ctr1" id="f" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="g" onclick="toggleSort(this)">Cxty</td><td class="sortable ctr1" id="h" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="i" onclick="toggleSort(this)">Lines</td><td class="sortable ctr1" id="j" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="k" onclick="toggleSort(this)">Methods</td></tr></thead><tfoot><tr><td>Total</td><td class="bar">108 of 603</td><td class="ctr2">82%</td><td class="bar">11 of 48</td><td class="ctr2">77%</td><td class="ctr1">14</td><t d class="ctr2">44</td><td class="ctr1">32</td><td class="ctr2">138</td><td class="ctr1">5</td><td class="ctr2">20</td></tr></tfoot><tbody><tr><td id="a15"><a href="MultipartStream.java.html#L558" class="el_method">readHeaders()</a></td><td class="bar" id="b0"><img src="../jacoco-resources/redbar.gif" width="44" height="10" title="33" alt="33"/><img src="../jacoco-resources/greenbar.gif" width="57" height="10" title="43" alt="43"/></td><td class="ctr2" id="c14">56%</td><td class="bar" id="d1"><img src="../jacoco-resources/redbar.gif" width="30" height="10" title="2" alt="2"/><img src="../jacoco-resources/greenbar.gif" width="90" height="10" title="6" alt="6"/></td><td class="ctr2" id="e4">75%</td><td class="ctr1" id="f1">2</td><td class="ctr2" id="g0">5</td><td class="ctr1" id="h0">11</td><td class="ctr2" id="i0">26</td><td class="ctr1" id="j5">0</td><td class="ctr2" id="k0">1</td></tr><tr><td id="a3"><a href="MultipartStream.java.html#L715" class="el_method">findByte(byte, int)</a>< /td><td class="bar" id="b1"><img src="../jacoco-resources/redbar.gif" width="24" height="10" title="18" alt="18"/></td><td class="ctr2" id="c15">0%</td><td class="bar" id="d0"><img src="../jacoco-resources/redbar.gif" width="60" height="10" title="4" alt="4"/></td><td class="ctr2" id="e8">0%</td><td class="ctr1" id="f0">3</td><td class="ctr2" id="g5">3</td><td class="ctr1" id="h2">4</td><td class="ctr2" id="i8">4</td><td class="ctr1" id="j0">1</td><td class="ctr2" id="k1">1</td></tr><tr><td id="a13"><a href="MultipartStream.java.html#L453" class="el_method">readBoundary()</a></td><td class="bar" id="b2"><img src="../jacoco-resources/redbar.gif" width="18" height="10" title="14" alt="14"/><img src="../jacoco-resources/greenbar.gif" width="64" height="10" title="48" alt="48"/></td><td class="ctr2" id="c13">77%</td><td class="bar" id="d3"><img src="../jacoco-resources/redbar.gif" width="15" height="10" title="1" alt="1"/><img src="../jacoco-resources/greenbar.gif" width="75" height="10 " title="5" alt="5"/></td><td class="ctr2" id="e3">83%</td><td class="ctr1" id="f3">1</td><td class="ctr2" id="g2">4</td><td class="ctr1" id="h1">5</td><td class="ctr2" id="i2">18</td><td class="ctr1" id="j6">0</td><td class="ctr2" id="k2">1</td></tr><tr><td id="a8"><a href="MultipartStream.java.html#L301" class="el_method">MultipartStream(InputStream, byte[], int)</a></td><td class="bar" id="b3"><img src="../jacoco-resources/redbar.gif" width="9" height="10" title="7" alt="7"/></td><td class="ctr2" id="c16">0%</td><td class="bar" id="d9"/><td class="ctr2" id="e9">n/a</td><td class="ctr1" id="f4">1</td><td class="ctr2" id="g9">1</td><td class="ctr1" id="h3">2</td><td class="ctr2" id="i11">2</td><td class="ctr1" id="j1">1</td><td class="ctr2" id="k3">1</td></tr><tr><td id="a7"><a href="MultipartStream.java.html#L388" class="el_method">MultipartStream(InputStream, byte[])</a></td><td class="bar" id="b4"><img src="../jacoco-resources/redbar.gif" width="9" height="10" title="7" alt="7"/ ></td><td class="ctr2" id="c17">0%</td><td class="bar" id="d10"/><td >class="ctr2" id="e10">n/a</td><td class="ctr1" id="f5">1</td><td class="ctr2" >id="g10">1</td><td class="ctr1" id="h4">2</td><td class="ctr2" >id="i12">2</td><td class="ctr1" id="j2">1</td><td class="ctr2" >id="k4">1</td></tr><tr><td id="a6"><a href="MultipartStream.java.html#L279" >class="el_method">MultipartStream()</a></td><td class="bar" id="b5"><img >src="../jacoco-resources/redbar.gif" width="8" height="10" title="6" >alt="6"/></td><td class="ctr2" id="c18">0%</td><td class="bar" id="d11"/><td >class="ctr2" id="e11">n/a</td><td class="ctr1" id="f6">1</td><td class="ctr2" >id="g11">1</td><td class="ctr1" id="h5">2</td><td class="ctr2" >id="i13">2</td><td class="ctr1" id="j3">1</td><td class="ctr2" >id="k5">1</td></tr><tr><td id="a9"><a href="MultipartStream.java.html#L326" >class="el_method">MultipartStream(InputStream, byte[], int, >MultipartStream.ProgressNotifier)</a></td><td class="bar" id="b6"><img >src="../jacoco-res ources/redbar.gif" width="6" height="10" title="5" alt="5"/><img src="../jacoco-resources/greenbar.gif" width="113" height="10" title="84" alt="84"/></td><td class="ctr2" id="c9">94%</td><td class="bar" id="d4"><img src="../jacoco-resources/redbar.gif" width="15" height="10" title="1" alt="1"/><img src="../jacoco-resources/greenbar.gif" width="45" height="10" title="3" alt="3"/></td><td class="ctr2" id="e5">75%</td><td class="ctr1" id="f7">1</td><td class="ctr2" id="g6">3</td><td class="ctr1" id="h7">1</td><td class="ctr2" id="i1">19</td><td class="ctr1" id="j7">0</td><td class="ctr2" id="k6">1</td></tr><tr><td id="a18"><a href="MultipartStream.java.html#L659" class="el_method">skipPreamble()</a></td><td class="bar" id="b7"><img src="../jacoco-resources/redbar.gif" width="6" height="10" title="5" alt="5"/><img src="../jacoco-resources/greenbar.gif" width="78" height="10" title="58" alt="58"/></td><td class="ctr2" id="c10">92%</td><td class="bar" id="d12"/><td class="ctr2" id="e12">n /a</td><td class="ctr1" id="f10">0</td><td class="ctr2" id="g12">1</td><td class="ctr1" id="h6">2</td><td class="ctr2" id="i4">12</td><td class="ctr1" id="j8">0</td><td class="ctr2" id="k7">1</td></tr><tr><td id="a14"><a href="MultipartStream.java.html#L425" class="el_method">readByte()</a></td><td class="bar" id="b8"><img src="../jacoco-resources/redbar.gif" width="6" height="10" title="5" alt="5"/><img src="../jacoco-resources/greenbar.gif" width="56" height="10" title="42" alt="42"/></td><td class="ctr2" id="c11">89%</td><td class="bar" id="d2"><img src="../jacoco-resources/redbar.gif" width="30" height="10" title="2" alt="2"/><img src="../jacoco-resources/greenbar.gif" width="60" height="10" title="4" alt="4"/></td><td class="ctr2" id="e6">66%</td><td class="ctr1" id="f2">2</td><td class="ctr2" id="g3">4</td><td class="ctr1" id="h8">1</td><td class="ctr2" id="i6">8</td><td class="ctr1" id="j9">0</td><td class="ctr2" id="k8">1</td></tr><tr><td id="a16"><a href="MultipartStream.ja va.html#L508" class="el_method">setBoundary(byte[])</a></td><td class="bar" id="b9"><img src="../jacoco-resources/redbar.gif" width="6" height="10" title="5" alt="5"/><img src="../jacoco-resources/greenbar.gif" width="26" height="10" title="20" alt="20"/></td><td class="ctr2" id="c12">80%</td><td class="bar" id="d5"><img src="../jacoco-resources/redbar.gif" width="15" height="10" title="1" alt="1"/><img src="../jacoco-resources/greenbar.gif" width="15" height="10" title="1" alt="1"/></td><td class="ctr2" id="e7">50%</td><td class="ctr1" id="f8">1</td><td class="ctr2" id="g8">2</td><td class="ctr1" id="h9">1</td><td class="ctr2" id="i7">5</td><td class="ctr1" id="j10">0</td><td class="ctr2" id="k9">1</td></tr><tr><td id="a5"><a href="MultipartStream.java.html#L401" class="el_method">getHeaderEncoding()</a></td><td class="bar" id="b10"><img src="../jacoco-resources/redbar.gif" width="4" height="10" title="3" alt="3"/></td><td class="ctr2" id="c19">0%</td><td class="bar" id="d13"/><td class="ctr2" id="e13">n/a</td><td class="ctr1" id="f9">1</td><td class="ctr2" id="g13">1</td><td class="ctr1" id="h10">1</td><td class="ctr2" id="i16">1</td><td class="ctr1" id="j4">1</td><td class="ctr2" id="k10">1</td></tr><tr><td id="a19"><a href="MultipartStream.java.html#L188" class="el_method">static {...}</a></td><td class="bar" id="b11"><img src="../jacoco-resources/greenbar.gif" width="82" height="10" title="61" alt="61"/></td><td class="ctr2" id="c0">100%</td><td class="bar" id="d14"/><td class="ctr2" id="e14">n/a</td><td class="ctr1" id="f11">0</td><td class="ctr2" id="g14">1</td><td class="ctr1" id="h11">0</td><td class="ctr2" id="i9">4</td><td class="ctr1" id="j11">0</td><td class="ctr2" id="k11">1</td></tr><tr><td id="a1"><a href="MultipartStream.java.html#L521" class="el_method">computeBoundaryTable()</a></td><td class="bar" id="b12"><img src="../jacoco-resources/greenbar.gif" width="74" height="10" title="55" alt="55"/></td><td class="ctr2" id="c1">100%</td><td class ="bar" id="d7"><img src="../jacoco-resources/greenbar.gif" width="90" height="10" title="6" alt="6"/></td><td class="ctr2" id="e0">100%</td><td class="ctr1" id="f12">0</td><td class="ctr2" id="g4">4</td><td class="ctr1" id="h12">0</td><td class="ctr2" id="i3">14</td><td class="ctr1" id="j12">0</td><td class="ctr2" id="k12">1</td></tr><tr><td id="a4"><a href="MultipartStream.java.html#L734" class="el_method">findSeparator()</a></td><td class="bar" id="b13"><img src="../jacoco-resources/greenbar.gif" width="52" height="10" title="39" alt="39"/></td><td class="ctr2" id="c2">100%</td><td class="bar" id="d6"><img src="../jacoco-resources/greenbar.gif" width="120" height="10" title="8" alt="8"/></td><td class="ctr2" id="e1">100%</td><td class="ctr1" id="f13">0</td><td class="ctr2" id="g1">5</td><td class="ctr1" id="h13">0</td><td class="ctr2" id="i5">10</td><td class="ctr1" id="j13">0</td><td class="ctr2" id="k13">1</td></tr><tr><td id="a0"><a href="MultipartStream.java.html#L695" class=" el_method">arrayequals(byte[], byte[], int)</a></td><td class="bar" id="b14"><img src="../jacoco-resources/greenbar.gif" width="24" height="10" title="18" alt="18"/></td><td class="ctr2" id="c3">100%</td><td class="bar" id="d8"><img src="../jacoco-resources/greenbar.gif" width="60" height="10" title="4" alt="4"/></td><td class="ctr2" id="e2">100%</td><td class="ctr1" id="f14">0</td><td class="ctr2" id="g7">3</td><td class="ctr1" id="h14">0</td><td class="ctr2" id="i10">4</td><td class="ctr1" id="j14">0</td><td class="ctr2" id="k14">1</td></tr><tr><td id="a10"><a href="MultipartStream.java.html#L372" class="el_method">MultipartStream(InputStream, byte[], MultipartStream.ProgressNotifier)</a></td><td class="bar" id="b15"><img src="../jacoco-resources/greenbar.gif" width="9" height="10" title="7" alt="7"/></td><td class="ctr2" id="c4">100%</td><td class="bar" id="d15"/><td class="ctr2" id="e15">n/a</td><td class="ctr1" id="f15">0</td><td class="ctr2" id="g15">1</td><td class="ctr1" id= "h15">0</td><td class="ctr2" id="i14">2</td><td class="ctr1" id="j15">0</td><td class="ctr2" id="k15">1</td></tr><tr><td id="a12"><a href="MultipartStream.java.html#L622" class="el_method">readBodyData(OutputStream)</a></td><td class="bar" id="b16"><img src="../jacoco-resources/greenbar.gif" width="9" height="10" title="7" alt="7"/></td><td class="ctr2" id="c5">100%</td><td class="bar" id="d16"/><td class="ctr2" id="e16">n/a</td><td class="ctr1" id="f16">0</td><td class="ctr2" id="g16">1</td><td class="ctr1" id="h16">0</td><td class="ctr2" id="i17">1</td><td class="ctr1" id="j16">0</td><td class="ctr2" id="k16">1</td></tr><tr><td id="a11"><a href="MultipartStream.java.html#L630" class="el_method">newInputStream()</a></td><td class="bar" id="b17"><img src="../jacoco-resources/greenbar.gif" width="6" height="10" title="5" alt="5"/></td><td class="ctr2" id="c6">100%</td><td class="bar" id="d17"/><td class="ctr2" id="e17">n/a</td><td class="ctr1" id="f17">0</td><td class="ctr2" id="g17" >1</td><td class="ctr1" id="h17">0</td><td class="ctr2" id="i18">1</td><td >class="ctr1" id="j17">0</td><td class="ctr2" id="k17">1</td></tr><tr><td >id="a17"><a href="MultipartStream.java.html#L412" >class="el_method">setHeaderEncoding(String)</a></td><td class="bar" >id="b18"><img src="../jacoco-resources/greenbar.gif" width="5" height="10" >title="4" alt="4"/></td><td class="ctr2" id="c7">100%</td><td class="bar" >id="d18"/><td class="ctr2" id="e18">n/a</td><td class="ctr1" >id="f18">0</td><td class="ctr2" id="g18">1</td><td class="ctr1" >id="h18">0</td><td class="ctr2" id="i15">2</td><td class="ctr1" >id="j18">0</td><td class="ctr2" id="k18">1</td></tr><tr><td id="a2"><a >href="MultipartStream.java.html#L646" >class="el_method">discardBodyData()</a></td><td class="bar" id="b19"><img >src="../jacoco-resources/greenbar.gif" width="5" height="10" title="4" >alt="4"/></td><td class="ctr2" id="c8">100%</td><td class="bar" id="d19"/><td >class="ctr2" id="e19">n/a</td><td class="ctr1" id="f19">0</td ><td class="ctr2" id="g19">1</td><td class="ctr1" id="h19">0</td><td >class="ctr2" id="i19">1</td><td class="ctr1" id="j19">0</td><td class="ctr2" >id="k19">1</td></tr></tbody></table><div class="footer"><span >class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> >0.8.8.202204050719</span></div></body></html> \ No newline at end of file Added: websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream.java.html ============================================================================== --- websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream.java.html (added) +++ websites/production/commons/content/proper/commons-fileupload/jacoco/org.apache.commons.fileupload/MultipartStream.java.html Mon Feb 13 10:43:35 2023 @@ -0,0 +1,1062 @@ +<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>MultipartStream.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons FileUpload</a> > <a href="index.source.html" class="el_package">org.apache.commons.fileupload</a> > <span class ="el_source">MultipartStream.java</span></div><h1>MultipartStream.java</h1><pre class="source lang-java linenums">/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.fileupload; + +import static java.lang.String.format; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import org.apache.commons.fileupload.FileUploadBase.FileUploadIOException; +import org.apache.commons.fileupload.util.Closeable; +import org.apache.commons.fileupload.util.Streams; + +/** + * <p> Low level API for processing file uploads. + * + * <p> This class can be used to process data streams conforming to MIME + * 'multipart' format as defined in + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Arbitrarily + * large amounts of data in the stream can be processed under constant + * memory usage. + * + * <p> The format of the stream is defined in the following way:<br> + * + * <code> + * multipart-body := preamble 1*encapsulation close-delimiter epilogue<br> + * encapsulation := delimiter body CRLF<br> + * delimiter := "--" boundary CRLF<br> + * close-delimiter := "--" boundary "--"<br> + * preamble := &lt;ignore&gt;<br> + * epilogue := &lt;ignore&gt;<br> + * body := header-part CRLF body-part<br> + * header-part := 1*header CRLF<br> + * header := header-name ":" header-value<br> + * header-name := &lt;printable ascii characters except ":"&gt;<br> + * header-value := &lt;any ascii characters except CR &amp; LF&gt;<br> + * body-data := &lt;arbitrary data&gt;<br> + * </code> + * + * <p>Note that body-data can contain another mulipart entity. There + * is limited support for single pass processing of such nested + * streams. The nested stream is <strong>required</strong> to have a + * boundary token of the same length as the parent stream (see {@link + * #setBoundary(byte[])}). + * + * <p>Here is an example of usage of this class.<br> + * + * <pre> + * try { + * MultipartStream multipartStream = new MultipartStream(input, boundary); + * boolean nextPart = multipartStream.skipPreamble(); + * OutputStream output; + * while(nextPart) { + * String header = multipartStream.readHeaders(); + * // process headers + * // create some output stream + * multipartStream.readBodyData(output); + * nextPart = multipartStream.readBoundary(); + * } + * } catch(MultipartStream.MalformedStreamException e) { + * // the stream failed to follow required syntax + * } catch(IOException e) { + * // a read or write error occurred + * } + * </pre> + */ +public class MultipartStream { + + /** + * Internal class, which is used to invoke the + * {@link ProgressListener}. + */ + public static class ProgressNotifier { + + /** + * The listener to invoke. + */ + private final ProgressListener listener; + + /** + * Number of expected bytes, if known, or -1. + */ + private final long contentLength; + + /** + * Number of bytes, which have been read so far. + */ + private long bytesRead; + + /** + * Number of items, which have been read so far. + */ + private int items; + + /** + * Creates a new instance with the given listener + * and content length. + * + * @param pListener The listener to invoke. + * @param pContentLength The expected content length. + */ +<span class="fc" id="L119"> ProgressNotifier(ProgressListener pListener, long pContentLength) {</span> +<span class="fc" id="L120"> listener = pListener;</span> +<span class="fc" id="L121"> contentLength = pContentLength;</span> +<span class="fc" id="L122"> }</span> + + /** + * Called to indicate that bytes have been read. + * + * @param pBytes Number of bytes, which have been read. + */ + void noteBytesRead(int pBytes) { + /* Indicates, that the given number of bytes have been read from + * the input stream. + */ +<span class="fc" id="L133"> bytesRead += pBytes;</span> +<span class="fc" id="L134"> notifyListener();</span> +<span class="fc" id="L135"> }</span> + + /** + * Called to indicate, that a new file item has been detected. + */ + void noteItem() { +<span class="fc" id="L141"> ++items;</span> +<span class="fc" id="L142"> notifyListener();</span> +<span class="fc" id="L143"> }</span> + + /** + * Called for notifying the listener. + */ + private void notifyListener() { +<span class="fc bfc" id="L149" title="All 2 branches covered."> if (listener != null) {</span> +<span class="fc" id="L150"> listener.update(bytesRead, contentLength, items);</span> + } +<span class="fc" id="L152"> }</span> + + } + + // ----------------------------------------------------- Manifest constants + + /** + * The Carriage Return ASCII character value. + */ + public static final byte CR = 0x0D; + + /** + * The Line Feed ASCII character value. + */ + public static final byte LF = 0x0A; + + /** + * The dash (-) ASCII character value. + */ + public static final byte DASH = 0x2D; + + /** + * The maximum length of <code>header-part</code> that will be + * processed (10 kilobytes = 10240 bytes.). + */ + public static final int HEADER_PART_SIZE_MAX = 10240; + + /** + * The default length of the buffer used for processing a request. + */ + protected static final int DEFAULT_BUFSIZE = 4096; + + /** + * A byte sequence that marks the end of <code>header-part</code> + * (<code>CRLFCRLF</code>). + */ +<span class="fc" id="L188"> protected static final byte[] HEADER_SEPARATOR = {CR, LF, CR, LF};</span> + + /** + * A byte sequence that that follows a delimiter that will be + * followed by an encapsulation (<code>CRLF</code>). + */ +<span class="fc" id="L194"> protected static final byte[] FIELD_SEPARATOR = {CR, LF};</span> + + /** + * A byte sequence that that follows a delimiter of the last + * encapsulation in the stream (<code>--</code>). + */ +<span class="fc" id="L200"> protected static final byte[] STREAM_TERMINATOR = {DASH, DASH};</span> + + /** + * A byte sequence that precedes a boundary (<code>CRLF--</code>). + */ +<span class="fc" id="L205"> protected static final byte[] BOUNDARY_PREFIX = {CR, LF, DASH, DASH};</span> + + // ----------------------------------------------------------- Data members + + /** + * The input stream from which data is read. + */ + private final InputStream input; + + /** + * The length of the boundary token plus the leading <code>CRLF--</code>. + */ + private int boundaryLength; + + /** + * The amount of data, in bytes, that must be kept in the buffer in order + * to detect delimiters reliably. + */ + private final int keepRegion; + + /** + * The byte sequence that partitions the stream. + */ + private final byte[] boundary; + + /** + * The table for Knuth-Morris-Pratt search algorithm. + */ + private final int[] boundaryTable; + + /** + * The length of the buffer used for processing the request. + */ + private final int bufSize; + + /** + * The buffer used for processing the request. + */ + private final byte[] buffer; + + /** + * The index of first valid character in the buffer. + * <br> + * 0 <= head < bufSize + */ + private int head; + + /** + * The index of last valid character in the buffer + 1. + * <br> + * 0 <= tail <= bufSize + */ + private int tail; + + /** + * The content encoding to use when reading headers. + */ + private String headerEncoding; + + /** + * The progress notifier, if any, or null. + */ + private final ProgressNotifier notifier; + + // ----------------------------------------------------------- Constructors + + /** + * Creates a new instance. + * + * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, + * ProgressNotifier)} + */ + @Deprecated + public MultipartStream() { +<span class="nc" id="L279"> this(null, null, null);</span> +<span class="nc" id="L280"> }</span> + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer + * and no progress notifier. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * + * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, + * ProgressNotifier)}. + */ + @Deprecated + public MultipartStream(InputStream input, byte[] boundary, int bufSize) { +<span class="nc" id="L301"> this(input, boundary, bufSize, null);</span> +<span class="nc" id="L302"> }</span> + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * @param pNotifier The notifier, which is used for calling the + * progress listener, if any. + * + * @throws IllegalArgumentException If the buffer size is too small + * + * @since 1.3.1 + */ + public MultipartStream(InputStream input, + byte[] boundary, + int bufSize, +<span class="fc" id="L326"> ProgressNotifier pNotifier) {</span> + +<span class="pc bpc" id="L328" title="1 of 2 branches missed."> if (boundary == null) {</span> +<span class="nc" id="L329"> throw new IllegalArgumentException("boundary may not be null");</span> + } + // We prepend CR/LF to the boundary to chop trailing CR/LF from + // body-data tokens. +<span class="fc" id="L333"> this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length;</span> +<span class="fc bfc" id="L334" title="All 2 branches covered."> if (bufSize < this.boundaryLength + 1) {</span> +<span class="fc" id="L335"> throw new IllegalArgumentException(</span> + "The buffer size specified for the MultipartStream is too small"); + } + +<span class="fc" id="L339"> this.input = input;</span> +<span class="fc" id="L340"> this.bufSize = Math.max(bufSize, boundaryLength * 2);</span> +<span class="fc" id="L341"> this.buffer = new byte[this.bufSize];</span> +<span class="fc" id="L342"> this.notifier = pNotifier;</span> + +<span class="fc" id="L344"> this.boundary = new byte[this.boundaryLength];</span> +<span class="fc" id="L345"> this.boundaryTable = new int[this.boundaryLength + 1];</span> +<span class="fc" id="L346"> this.keepRegion = this.boundary.length;</span> + +<span class="fc" id="L348"> System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0,</span> + BOUNDARY_PREFIX.length); +<span class="fc" id="L350"> System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length,</span> + boundary.length); +<span class="fc" id="L352"> computeBoundaryTable();</span> + +<span class="fc" id="L354"> head = 0;</span> +<span class="fc" id="L355"> tail = 0;</span> +<span class="fc" id="L356"> }</span> + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param pNotifier An object for calling the progress listener, if any. + * + * + * @see #MultipartStream(InputStream, byte[], int, ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + ProgressNotifier pNotifier) { +<span class="fc" id="L372"> this(input, boundary, DEFAULT_BUFSIZE, pNotifier);</span> +<span class="fc" id="L373"> }</span> + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * + * @deprecated 1.2.1 Use {@link #MultipartStream(InputStream, byte[], int, + * ProgressNotifier)}. + */ + @Deprecated + public MultipartStream(InputStream input, + byte[] boundary) { +<span class="nc" id="L388"> this(input, boundary, DEFAULT_BUFSIZE, null);</span> +<span class="nc" id="L389"> }</span> + + // --------------------------------------------------------- Public methods + + /** + * Retrieves the character encoding used when reading the headers of an + * individual part. When not specified, or <code>null</code>, the platform + * default encoding is used. + * + * @return The encoding used to read part headers. + */ + public String getHeaderEncoding() { +<span class="nc" id="L401"> return headerEncoding;</span> + } + + /** + * Specifies the character encoding to be used when reading the headers of + * individual parts. When not specified, or <code>null</code>, the platform + * default encoding is used. + * + * @param encoding The encoding used to read part headers. + */ + public void setHeaderEncoding(String encoding) { +<span class="fc" id="L412"> headerEncoding = encoding;</span> +<span class="fc" id="L413"> }</span> + + /** + * Reads a byte from the <code>buffer</code>, and refills it as + * necessary. + * + * @return The next byte from the input stream. + * + * @throws IOException if there is no more data available. + */ + public byte readByte() throws IOException { + // Buffer depleted ? +<span class="fc bfc" id="L425" title="All 2 branches covered."> if (head == tail) {</span> +<span class="fc" id="L426"> head = 0;</span> + // Refill. +<span class="fc" id="L428"> tail = input.read(buffer, head, bufSize);</span> +<span class="pc bpc" id="L429" title="1 of 2 branches missed."> if (tail == -1) {</span> + // No more data available. +<span class="nc" id="L431"> throw new IOException("No more data is available");</span> + } +<span class="pc bpc" id="L433" title="1 of 2 branches missed."> if (notifier != null) {</span> +<span class="fc" id="L434"> notifier.noteBytesRead(tail);</span> + } + } +<span class="fc" id="L437"> return buffer[head++];</span> + } + + /** + * Skips a <code>boundary</code> token, and checks whether more + * <code>encapsulations</code> are contained in the stream. + * + * @return <code>true</code> if there are more encapsulations in + * this stream; <code>false</code> otherwise. + * + * @throws FileUploadIOException if the bytes read from the stream exceeded the size limits + * @throws MalformedStreamException if the stream ends unexpectedly or + * fails to follow required syntax. + */ + public boolean readBoundary() + throws FileUploadIOException, MalformedStreamException { +<span class="fc" id="L453"> byte[] marker = new byte[2];</span> +<span class="fc" id="L454"> boolean nextChunk = false;</span> + +<span class="fc" id="L456"> head += boundaryLength;</span> + try { +<span class="fc" id="L458"> marker[0] = readByte();</span> +<span class="fc bfc" id="L459" title="All 2 branches covered."> if (marker[0] == LF) {</span> + // Work around IE5 Mac bug with input type=image. + // Because the boundary delimiter, not including the trailing + // CRLF, must not appear within any file (RFC 2046, section + // 5.1.1), we know the missing CR is due to a buggy browser + // rather than a file containing something similar to a + // boundary. +<span class="fc" id="L466"> return true;</span> + } + +<span class="fc" id="L469"> marker[1] = readByte();</span> +<span class="fc bfc" id="L470" title="All 2 branches covered."> if (arrayequals(marker, STREAM_TERMINATOR, 2)) {</span> +<span class="fc" id="L471"> nextChunk = false;</span> +<span class="pc bpc" id="L472" title="1 of 2 branches missed."> } else if (arrayequals(marker, FIELD_SEPARATOR, 2)) {</span> +<span class="fc" id="L473"> nextChunk = true;</span> + } else { +<span class="nc" id="L475"> throw new MalformedStreamException(</span> + "Unexpected characters follow a boundary"); + } +<span class="nc" id="L478"> } catch (FileUploadIOException e) {</span> + // wraps a SizeException, re-throw as it will be unwrapped later +<span class="nc" id="L480"> throw e;</span> +<span class="nc" id="L481"> } catch (IOException e) {</span> +<span class="nc" id="L482"> throw new MalformedStreamException("Stream ended unexpectedly");</span> +<span class="fc" id="L483"> }</span> +<span class="fc" id="L484"> return nextChunk;</span> + } + + /** + * <p>Changes the boundary token used for partitioning the stream. + * + * <p>This method allows single pass processing of nested multipart + * streams. + * + * <p>The boundary token of the nested stream is <code>required</code> + * to be of the same length as the boundary token in parent stream. + * + * <p>Restoring the parent stream boundary token after processing of a + * nested stream is left to the application. + * + * @param boundary The boundary to be used for parsing of the nested + * stream. + * + * @throws IllegalBoundaryException if the <code>boundary</code> + * has a different length than the one + * being currently parsed. + */ + public void setBoundary(byte[] boundary) + throws IllegalBoundaryException { +<span class="pc bpc" id="L508" title="1 of 2 branches missed."> if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) {</span> +<span class="nc" id="L509"> throw new IllegalBoundaryException(</span> + "The length of a boundary token cannot be changed"); + } +<span class="fc" id="L512"> System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length,</span> + boundary.length); +<span class="fc" id="L514"> computeBoundaryTable();</span> +<span class="fc" id="L515"> }</span> + + /** + * Compute the table used for Knuth-Morris-Pratt search algorithm. + */ + private void computeBoundaryTable() { +<span class="fc" id="L521"> int position = 2;</span> +<span class="fc" id="L522"> int candidate = 0;</span> + +<span class="fc" id="L524"> boundaryTable[0] = -1;</span> +<span class="fc" id="L525"> boundaryTable[1] = 0;</span> + +<span class="fc bfc" id="L527" title="All 2 branches covered."> while (position <= boundaryLength) {</span> +<span class="fc bfc" id="L528" title="All 2 branches covered."> if (boundary[position - 1] == boundary[candidate]) {</span> +<span class="fc" id="L529"> boundaryTable[position] = candidate + 1;</span> +<span class="fc" id="L530"> candidate++;</span> +<span class="fc" id="L531"> position++;</span> +<span class="fc bfc" id="L532" title="All 2 branches covered."> } else if (candidate > 0) {</span> +<span class="fc" id="L533"> candidate = boundaryTable[candidate];</span> + } else { +<span class="fc" id="L535"> boundaryTable[position] = 0;</span> +<span class="fc" id="L536"> position++;</span> + } + } +<span class="fc" id="L539"> }</span> + + /** + * <p>Reads the <code>header-part</code> of the current + * <code>encapsulation</code>. + * + * <p>Headers are returned verbatim to the input stream, including the + * trailing <code>CRLF</code> marker. Parsing is left to the + * application. + * + * <p><strong>TODO</strong> allow limiting maximum header size to + * protect against abuse. + * + * @return The <code>header-part</code> of the current encapsulation. + * + * @throws FileUploadIOException if the bytes read from the stream exceeded the size limits. + * @throws MalformedStreamException if the stream ends unexpectedly. + */ + public String readHeaders() throws FileUploadIOException, MalformedStreamException { +<span class="fc" id="L558"> int i = 0;</span> + byte b; + // to support multi-byte characters +<span class="fc" id="L561"> ByteArrayOutputStream baos = new ByteArrayOutputStream();</span> +<span class="fc" id="L562"> int size = 0;</span> +<span class="fc bfc" id="L563" title="All 2 branches covered."> while (i < HEADER_SEPARATOR.length) {</span> + try { +<span class="fc" id="L565"> b = readByte();</span> +<span class="nc" id="L566"> } catch (FileUploadIOException e) {</span> + // wraps a SizeException, re-throw as it will be unwrapped later +<span class="nc" id="L568"> throw e;</span> +<span class="nc" id="L569"> } catch (IOException e) {</span> +<span class="nc" id="L570"> throw new MalformedStreamException("Stream ended unexpectedly");</span> +<span class="fc" id="L571"> }</span> +<span class="pc bpc" id="L572" title="1 of 2 branches missed."> if (++size > HEADER_PART_SIZE_MAX) {</span> +<span class="nc" id="L573"> throw new MalformedStreamException(</span> +<span class="nc" id="L574"> format("Header section has more than %s bytes (maybe it is not properly terminated)",</span> +<span class="nc" id="L575"> Integer.valueOf(HEADER_PART_SIZE_MAX)));</span> + } +<span class="fc bfc" id="L577" title="All 2 branches covered."> if (b == HEADER_SEPARATOR[i]) {</span> +<span class="fc" id="L578"> i++;</span> + } else { +<span class="fc" id="L580"> i = 0;</span> + } +<span class="fc" id="L582"> baos.write(b);</span> + } + +<span class="fc" id="L585"> String headers = null;</span> +<span class="pc bpc" id="L586" title="1 of 2 branches missed."> if (headerEncoding != null) {</span> + try { +<span class="nc" id="L588"> headers = baos.toString(headerEncoding);</span> +<span class="nc" id="L589"> } catch (UnsupportedEncodingException e) {</span> + // Fall back to platform default if specified encoding is not + // supported. +<span class="nc" id="L592"> headers = baos.toString();</span> +<span class="nc" id="L593"> }</span> + } else { +<span class="fc" id="L595"> headers = baos.toString();</span> + } + +<span class="fc" id="L598"> return headers;</span> + } + + /** + * <p>Reads <code>body-data</code> from the current + * <code>encapsulation</code> and writes its contents into the + * output <code>Stream</code>. + * + * <p>Arbitrary large amounts of data can be processed by this + * method using a constant size buffer. (see {@link + * #MultipartStream(InputStream,byte[],int, + * MultipartStream.ProgressNotifier) constructor}). + * + * @param output The <code>Stream</code> to write data into. May + * be null, in which case this method is equivalent + * to {@link #discardBodyData()}. + * + * @return the amount of data written. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int readBodyData(OutputStream output) + throws MalformedStreamException, IOException { +<span class="fc" id="L622"> return (int) Streams.copy(newInputStream(), output, false); // N.B. Streams.copy closes the input stream</span> + } + + /** + * Creates a new {@link ItemInputStream}. + * @return A new instance of {@link ItemInputStream}. + */ + ItemInputStream newInputStream() { +<span class="fc" id="L630"> return new ItemInputStream();</span> + } + + /** + * <p> Reads <code>body-data</code> from the current + * <code>encapsulation</code> and discards it. + * + * <p>Use this method to skip encapsulations you don't need or don't + * understand. + * + * @return The amount of data discarded. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int discardBodyData() throws MalformedStreamException, IOException { +<span class="fc" id="L646"> return readBodyData(null);</span> + } + + /** + * Finds the beginning of the first <code>encapsulation</code>. + * + * @return <code>true</code> if an <code>encapsulation</code> was found in + * the stream. + * + * @throws IOException if an i/o error occurs. + */ + public boolean skipPreamble() throws IOException { + // First delimiter may be not preceeded with a CRLF. +<span class="fc" id="L659"> System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2);</span> +<span class="fc" id="L660"> boundaryLength = boundary.length - 2;</span> +<span class="fc" id="L661"> computeBoundaryTable();</span> + try { + // Discard all data up to the delimiter. +<span class="fc" id="L664"> discardBodyData();</span> + + // Read boundary - if succeeded, the stream contains an + // encapsulation. +<span class="fc" id="L668"> return readBoundary();</span> +<span class="nc" id="L669"> } catch (MalformedStreamException e) {</span> +<span class="nc" id="L670"> return false;</span> + } finally { + // Restore delimiter. +<span class="fc" id="L673"> System.arraycopy(boundary, 0, boundary, 2, boundary.length - 2);</span> +<span class="fc" id="L674"> boundaryLength = boundary.length;</span> +<span class="fc" id="L675"> boundary[0] = CR;</span> +<span class="fc" id="L676"> boundary[1] = LF;</span> +<span class="fc" id="L677"> computeBoundaryTable();</span> + } + } + + /** + * Compares <code>count</code> first bytes in the arrays + * <code>a</code> and <code>b</code>. + * + * @param a The first array to compare. + * @param b The second array to compare. + * @param count How many bytes should be compared. + * + * @return <code>true</code> if <code>count</code> first bytes in arrays + * <code>a</code> and <code>b</code> are equal. + */ + public static boolean arrayequals(byte[] a, + byte[] b, + int count) { +<span class="fc bfc" id="L695" title="All 2 branches covered."> for (int i = 0; i < count; i++) {</span> +<span class="fc bfc" id="L696" title="All 2 branches covered."> if (a[i] != b[i]) {</span> +<span class="fc" id="L697"> return false;</span> + } + } +<span class="fc" id="L700"> return true;</span> + } + + /** + * Searches for a byte of specified value in the <code>buffer</code>, + * starting at the specified <code>position</code>. + * + * @param value The value to find. + * @param pos The starting position for searching. + * + * @return The position of byte found, counting from beginning of the + * <code>buffer</code>, or <code>-1</code> if not found. + */ + protected int findByte(byte value, + int pos) { +<span class="nc bnc" id="L715" title="All 2 branches missed."> for (int i = pos; i < tail; i++) {</span> +<span class="nc bnc" id="L716" title="All 2 branches missed."> if (buffer[i] == value) {</span> +<span class="nc" id="L717"> return i;</span> + } + } + +<span class="nc" id="L721"> return -1;</span> + } + + /** + * Searches for the <code>boundary</code> in the <code>buffer</code> + * region delimited by <code>head</code> and <code>tail</code>. + * + * @return The position of the boundary found, counting from the + * beginning of the <code>buffer</code>, or <code>-1</code> if + * not found. + */ + protected int findSeparator() { + +<span class="fc" id="L734"> int bufferPos = this.head;</span> +<span class="fc" id="L735"> int tablePos = 0;</span> + +<span class="fc bfc" id="L737" title="All 2 branches covered."> while (bufferPos < this.tail) {</span> +<span class="fc bfc" id="L738" title="All 4 branches covered."> while (tablePos >= 0 && buffer[bufferPos] != boundary[tablePos]) {</span> +<span class="fc" id="L739"> tablePos = boundaryTable[tablePos];</span> + } +<span class="fc" id="L741"> bufferPos++;</span> +<span class="fc" id="L742"> tablePos++;</span> +<span class="fc bfc" id="L743" title="All 2 branches covered."> if (tablePos == boundaryLength) {</span> +<span class="fc" id="L744"> return bufferPos - boundaryLength;</span> + } + } +<span class="fc" id="L747"> return -1;</span> + } + + /** + * Thrown to indicate that the input stream fails to follow the + * required syntax. + */ + public static class MalformedStreamException extends IOException { + + /** + * The UID to use when serializing this instance. + */ + private static final long serialVersionUID = 6466926458059796677L; + + /** + * Constructs a <code>MalformedStreamException</code> with no + * detail message. + */ + public MalformedStreamException() { +<span class="nc" id="L766"> super();</span> +<span class="nc" id="L767"> }</span> + + /** + * Constructs an <code>MalformedStreamException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public MalformedStreamException(String message) { +<span class="fc" id="L776"> super(message);</span> +<span class="fc" id="L777"> }</span> + + } + + /** + * Thrown upon attempt of setting an invalid boundary token. + */ + public static class IllegalBoundaryException extends IOException { + + /** + * The UID to use when serializing this instance. + */ + private static final long serialVersionUID = -161533165102632918L; + + /** + * Constructs an <code>IllegalBoundaryException</code> with no + * detail message. + */ + public IllegalBoundaryException() { +<span class="nc" id="L796"> super();</span> +<span class="nc" id="L797"> }</span> + + /** + * Constructs an <code>IllegalBoundaryException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public IllegalBoundaryException(String message) { +<span class="nc" id="L806"> super(message);</span> +<span class="nc" id="L807"> }</span> + + } + + /** + * An {@link InputStream} for reading an items contents. + */ + public class ItemInputStream extends InputStream implements Closeable { + + /** + * The number of bytes, which have been read so far. + */ + private long total; + + /** + * The number of bytes, which must be hold, because + * they might be a part of the boundary. + */ + private int pad; + + /** + * The current offset in the buffer. + */ + private int pos; + + /** + * Whether the stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + */ +<span class="fc" id="L840"> ItemInputStream() {</span> +<span class="fc" id="L841"> findSeparator();</span> +<span class="fc" id="L842"> }</span> + + /** + * Called for finding the separator. + */ + private void findSeparator() { +<span class="fc" id="L848"> pos = MultipartStream.this.findSeparator();</span> +<span class="fc bfc" id="L849" title="All 2 branches covered."> if (pos == -1) {</span> +<span class="fc bfc" id="L850" title="All 2 branches covered."> if (tail - head > keepRegion) {</span> +<span class="fc" id="L851"> pad = keepRegion;</span> + } else { +<span class="fc" id="L853"> pad = tail - head;</span> + } + } +<span class="fc" id="L856"> }</span> + + /** + * Returns the number of bytes, which have been read + * by the stream. + * + * @return Number of bytes, which have been read so far. + */ + public long getBytesRead() { +<span class="nc" id="L865"> return total;</span> + } + + /** + * Returns the number of bytes, which are currently + * available, without blocking. + * + * @throws IOException An I/O error occurs. + * @return Number of bytes in the buffer. + */ + @Override + public int available() throws IOException { +<span class="fc bfc" id="L877" title="All 2 branches covered."> if (pos == -1) {</span> +<span class="fc" id="L878"> return tail - head - pad;</span> + } +<span class="fc" id="L880"> return pos - head;</span> + } + + /** + * Offset when converting negative bytes to integers. + */ + private static final int BYTE_POSITIVE_OFFSET = 256; + + /** + * Returns the next byte in the stream. + * + * @return The next byte in the stream, as a non-negative + * integer, or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + @Override + public int read() throws IOException { +<span class="pc bpc" id="L897" title="1 of 2 branches missed."> if (closed) {</span> +<span class="nc" id="L898"> throw new FileItemStream.ItemSkippedException();</span> + } +<span class="fc bfc" id="L900" title="All 4 branches covered."> if (available() == 0 && makeAvailable() == 0) {</span> +<span class="fc" id="L901"> return -1;</span> + } +<span class="fc" id="L903"> ++total;</span> +<span class="fc" id="L904"> int b = buffer[head++];</span> +<span class="fc bfc" id="L905" title="All 2 branches covered."> if (b >= 0) {</span> +<span class="fc" id="L906"> return b;</span> + } +<span class="fc" id="L908"> return b + BYTE_POSITIVE_OFFSET;</span> + } + + /** + * Reads bytes into the given buffer. + * + * @param b The destination buffer, where to write to. + * @param off Offset of the first byte in the buffer. + * @param len Maximum number of bytes to read. + * @return Number of bytes, which have been actually read, + * or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + @Override + public int read(byte[] b, int off, int len) throws IOException { +<span class="pc bpc" id="L923" title="1 of 2 branches missed."> if (closed) {</span> +<span class="nc" id="L924"> throw new FileItemStream.ItemSkippedException();</span> + } +<span class="pc bpc" id="L926" title="1 of 2 branches missed."> if (len == 0) {</span> +<span class="nc" id="L927"> return 0;</span> + } +<span class="fc" id="L929"> int res = available();</span> +<span class="fc bfc" id="L930" title="All 2 branches covered."> if (res == 0) {</span> +<span class="fc" id="L931"> res = makeAvailable();</span> +<span class="fc bfc" id="L932" title="All 2 branches covered."> if (res == 0) {</span> +<span class="fc" id="L933"> return -1;</span> + } + } +<span class="fc" id="L936"> res = Math.min(res, len);</span> +<span class="fc" id="L937"> System.arraycopy(buffer, head, b, off, res);</span> +<span class="fc" id="L938"> head += res;</span> +<span class="fc" id="L939"> total += res;</span> +<span class="fc" id="L940"> return res;</span> + } + + /** + * Closes the input stream. + * + * @throws IOException An I/O error occurred. + */ + @Override + public void close() throws IOException { +<span class="fc" id="L950"> close(false);</span> +<span class="fc" id="L951"> }</span> + + /** + * Closes the input stream. + * + * @param pCloseUnderlying Whether to close the underlying stream + * (hard close) + * @throws IOException An I/O error occurred. + */ + public void close(boolean pCloseUnderlying) throws IOException { +<span class="fc bfc" id="L961" title="All 2 branches covered."> if (closed) {</span> +<span class="fc" id="L962"> return;</span> + } +<span class="fc bfc" id="L964" title="All 2 branches covered."> if (pCloseUnderlying) {</span> +<span class="fc" id="L965"> closed = true;</span> +<span class="fc" id="L966"> input.close();</span> + } else { + for (;;) { +<span class="fc" id="L969"> int av = available();</span> +<span class="pc bpc" id="L970" title="1 of 2 branches missed."> if (av == 0) {</span> +<span class="fc" id="L971"> av = makeAvailable();</span> +<span class="pc bpc" id="L972" title="1 of 2 branches missed."> if (av == 0) {</span> +<span class="fc" id="L973"> break;</span> + } + } +<span class="nc" id="L976"> skip(av);</span> +<span class="nc" id="L977"> }</span> + } +<span class="fc" id="L979"> closed = true;</span> +<span class="fc" id="L980"> }</span> + + /** + * Skips the given number of bytes. + * + * @param bytes Number of bytes to skip. + * @return The number of bytes, which have actually been + * skipped. + * @throws IOException An I/O error occurred. + */ + @Override + public long skip(long bytes) throws IOException { +<span class="nc bnc" id="L992" title="All 2 branches missed."> if (closed) {</span> +<span class="nc" id="L993"> throw new FileItemStream.ItemSkippedException();</span> + } +<span class="nc" id="L995"> int av = available();</span> +<span class="nc bnc" id="L996" title="All 2 branches missed."> if (av == 0) {</span> +<span class="nc" id="L997"> av = makeAvailable();</span> +<span class="nc bnc" id="L998" title="All 2 branches missed."> if (av == 0) {</span> +<span class="nc" id="L999"> return 0;</span> + } + } +<span class="nc" id="L1002"> long res = Math.min(av, bytes);</span> +<span class="nc" id="L1003"> head += res;</span> +<span class="nc" id="L1004"> return res;</span> + } + + /** + * Attempts to read more data. + * + * @return Number of available bytes + * @throws IOException An I/O error occurred. + */ + private int makeAvailable() throws IOException { +<span class="fc bfc" id="L1014" title="All 2 branches covered."> if (pos != -1) {</span> +<span class="fc" id="L1015"> return 0;</span> + } + + // Move the data to the beginning of the buffer. +<span class="fc" id="L1019"> total += tail - head - pad;</span> +<span class="fc" id="L1020"> System.arraycopy(buffer, tail - pad, buffer, 0, pad);</span> + + // Refill buffer with new data. +<span class="fc" id="L1023"> head = 0;</span> +<span class="fc" id="L1024"> tail = pad;</span> + + for (;;) { +<span class="fc" id="L1027"> int bytesRead = input.read(buffer, tail, bufSize - tail);</span> +<span class="fc bfc" id="L1028" title="All 2 branches covered."> if (bytesRead == -1) {</span> + // The last pad amount is left in the buffer. + // Boundary can't be in there so signal an error + // condition. +<span class="fc" id="L1032"> final String msg = "Stream ended unexpectedly";</span> +<span class="fc" id="L1033"> throw new MalformedStreamException(msg);</span> + } +<span class="pc bpc" id="L1035" title="1 of 2 branches missed."> if (notifier != null) {</span> +<span class="fc" id="L1036"> notifier.noteBytesRead(bytesRead);</span> + } +<span class="fc" id="L1038"> tail += bytesRead;</span> + +<span class="fc" id="L1040"> findSeparator();</span> +<span class="fc" id="L1041"> int av = available();</span> + +<span class="fc bfc" id="L1043" title="All 4 branches covered."> if (av > 0 || pos != -1) {</span> +<span class="fc" id="L1044"> return av;</span> + } +<span class="fc" id="L1046"> }</span> + } + + /** + * Returns, whether the stream is closed. + * + * @return True, if the stream is closed, otherwise false. + */ + @Override + public boolean isClosed() { +<span class="fc" id="L1056"> return closed;</span> + } + + } + +} +</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.8.202204050719</span></div></body></html> \ No newline at end of file
