- From: Yves Lafon via cvs-syncmail <cvsmail@w3.org>
- Date: Mon, 22 Aug 2011 06:50:49 +0000
- To: www-validator-cvs@w3.org
Update of /sources/public/2002/css-validator/org/w3c/css/util In directory hutz:/tmp/cvs-serv11490/org/w3c/css/util Modified Files: Codecs.java Log Message: Squashed bug in form header parsing, causing form-data with extra charset parameters to be seen as invalid Index: Codecs.java =================================================================== RCS file: /sources/public/2002/css-validator/org/w3c/css/util/Codecs.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- Codecs.java 20 Sep 2007 12:07:32 -0000 1.6 +++ Codecs.java 22 Aug 2011 06:50:47 -0000 1.7 @@ -43,8 +43,8 @@ /** * This class collects various encoders and decoders. * - * @version 0.2 (bug fix 2) 23/03/1997 - * @author Ronald Tschalär + * @version 0.2 (bug fix 2) 23/03/1997 + * @author Ronald Tschalär */ public class Codecs { @@ -59,7 +59,8 @@ /** * This class isn't meant to be instantiated. */ - private Codecs() {} + private Codecs() { + } // Methods @@ -73,19 +74,19 @@ * <BR>Note: Does not handle nested encodings (yet). * <BR>Example: * <PRE> - * NVPair[] opts = Codecs.mpFormDataDecode(resp.getData(), - * resp.getHeader("Content-length"), - * "."); + * NVPair[] opts = Codecs.mpFormDataDecode(resp.getData(), + * resp.getHeader("Content-length"), + * "."); * </PRE> * Assuming the data received looked something like: * <PRE> * -----------------------------114975832116442893661388290519 * Content-Disposition: form-data; name="option" - * + * * doit * -----------------------------114975832116442893661388290519 * Content-Disposition: form-data; name="comment"; filename="comment.txt" - * + * * Gnus and Gnats are not Gnomes. * -----------------------------114975832116442893661388290519-- * </PRE> @@ -93,241 +94,240 @@ * directory, and opts would contain two elements: {"option", "doit"} * and {"comment", "comment.txt"} * - * @param data the form-data to decode. - * @param cont_type the content type header (must contain the - * boundary string). - * @return an array of name/value pairs, one for each part; - * the name is the 'name' attribute given in the - * Content-Disposition header; the value is either - * the name of the file if a filename attribute was - * found, or the contents of the part. - * @exception IOException If any file operation fails. + * @param data the form-data to decode. + * @param cont_type the content type header (must contain the + * boundary string). + * @return an array of name/value pairs, one for each part; + * the name is the 'name' attribute given in the + * Content-Disposition header; the value is either + * the name of the file if a filename attribute was + * found, or the contents of the part. + * @throws IOException If any file operation fails. */ public final static synchronized NVPair[] mpFormDataDecode(byte[] data, - String cont_type) - throws IOException { - - // Find and extract boundary string - String bndstr = getParameter("boundary", cont_type); - if (bndstr == null) { - throw new IOException("\'boundary\' parameter " + - "not found in Content-type: " + cont_type); - } + String cont_type) + throws IOException { - byte[] srtbndry = new byte[bndstr.length()+4], - boundary = new byte[bndstr.length()+6], - endbndry = new byte[bndstr.length()+6]; + // Find and extract boundary string + String bndstr = getParameter("boundary", cont_type); + if (bndstr == null) { + throw new IOException("\'boundary\' parameter " + + "not found in Content-type: " + cont_type); + } - srtbndry = ( "--" + bndstr + "\n").getBytes(); - boundary = ("\n--" + bndstr + "\n").getBytes(); - endbndry = ("\n--" + bndstr + "--" ).getBytes(); + byte[] srtbndry = new byte[bndstr.length() + 4], + boundary = new byte[bndstr.length() + 6], + endbndry = new byte[bndstr.length() + 6]; - if (debugMode) { - System.err.println("[START OF DATA]"); - printData(data); - System.err.println("[END OF DATA]"); - System.err.print( "boundary : " ); - printData(srtbndry); - System.err.println(); - printData(boundary); - System.err.println(); - printData(endbndry); - System.err.println(); - } + srtbndry = ("--" + bndstr + "\n").getBytes(); + boundary = ("\n--" + bndstr + "\n").getBytes(); + endbndry = ("\n--" + bndstr + "--").getBytes(); + if (debugMode) { + System.err.println("[START OF DATA]"); + printData(data); + System.err.println("[END OF DATA]"); + System.err.print("boundary : "); + printData(srtbndry); + System.err.println(); + printData(boundary); + System.err.println(); + printData(endbndry); + System.err.println(); + } - // slurp + // slurp - // setup search routines + // setup search routines - int[] bs = Util.compile_search(srtbndry); - int[] bc = Util.compile_search(boundary); - int[] be = Util.compile_search(endbndry); + int[] bs = Util.compile_search(srtbndry); + int[] bc = Util.compile_search(boundary); + int[] be = Util.compile_search(endbndry); - // let's start parsing the actual data + // let's start parsing the actual data - int start = Util.findStr(srtbndry, bs, data, 0, data.length); - if (start == -1) { // didn't even find the start - if (!debugMode) { - debugMode = true; - mpFormDataDecode(data, cont_type); - return null; - } else { - debugMode = false; - throw new IOException("Starting boundary not found: " + - new String(srtbndry)); - } - } + int start = Util.findStr(srtbndry, bs, data, 0, data.length); + if (start == -1) { // didn't even find the start + if (!debugMode) { + debugMode = true; + mpFormDataDecode(data, cont_type); + return null; + } else { + debugMode = false; + throw new IOException("Starting boundary not found: " + + new String(srtbndry)); + } + } - start += srtbndry.length; + start += srtbndry.length; - NVPair[] res = new NVPair[10]; - boolean done = false; - int idx; + NVPair[] res = new NVPair[10]; + boolean done = false; + int idx; - for (idx=0; !done; idx++) { - // find end of this part + for (idx = 0; !done; idx++) { + // find end of this part - int end = Util.findStr(boundary, bc, data, start, data.length); - if (end == -1) { // must be the last part - end = Util.findStr(endbndry, be, data, start, data.length); - if (end == -1) { - /* if (!debugMode) { - debugMode = true; - mpFormDataDecode(data, cont_type); - return null; - } else { - debugMode = false; - System.err.println( "[Ending boundary not found in]" ); - printData(data, start); - System.err.println( "[END DATA BOUNDARY SEARCH]"); - throw new IOException("Ending boundary not found: " + - new String(endbndry)); - */ - end = data.length -1; - while (end >= 0 && (data[end] == '\n' || data[end] == ' ')) { - end--; - } - end++; - /* } */ - } - done = true; - } + int end = Util.findStr(boundary, bc, data, start, data.length); + if (end == -1) { // must be the last part + end = Util.findStr(endbndry, be, data, start, data.length); + if (end == -1) { + /* if (!debugMode) { + debugMode = true; + mpFormDataDecode(data, cont_type); + return null; + } else { + debugMode = false; + System.err.println( "[Ending boundary not found in]" ); + printData(data, start); + System.err.println( "[END DATA BOUNDARY SEARCH]"); + throw new IOException("Ending boundary not found: " + + new String(endbndry)); + */ + end = data.length - 1; + while (end >= 0 && (data[end] == '\n' || data[end] == ' ')) { + end--; + } + end++; + /* } */ + } + done = true; + } - // parse header(s) + // parse header(s) - String hdr, lchdr, name=null, filename=null, cont_disp = null, mimeType=null; - Object value; + String hdr, lchdr, name = null, filename = null, cont_disp = null, mimeType = null; + Object value; - while (true) { - int next = findEOL(data, start) + 1; + while (true) { + int next = findEOL(data, start) + 1; - if (next-1 <= start) break; // empty line -> end of headers - hdr = new String(data, start, next-1-start); + if (next - 1 <= start) break; // empty line -> end of headers + hdr = new String(data, start, next - 1 - start); - if (debugMode) { - System.err.println( " start = " + start + - " end = " + next ); - } + if (debugMode) { + System.err.println(" start = " + start + + " end = " + next); + } - // handle line continuation - byte ch; - while (next < data.length-1 && - ((ch = data[next]) == ' ' || ch == '\t')) { - next = findEOL(data, start) + 1; - String result = new String(data, start, next-1-start); - hdr += result; - start = next; - } - start = next; + // handle line continuation + byte ch; + while (next < data.length - 1 && + ((ch = data[next]) == ' ' || ch == '\t')) { + next = findEOL(data, start) + 1; + String result = new String(data, start, next - 1 - start); + hdr += result; + start = next; + } + start = next; - if (debugMode) { - System.err.println( "hdr=" + hdr ); - System.err.println( "(New) start = " + start + - " end = " + next ); - } + if (debugMode) { + System.err.println("hdr=" + hdr); + System.err.println("(New) start = " + start + + " end = " + next); + } - lchdr = hdr.toLowerCase(); + lchdr = hdr.toLowerCase(); - if (lchdr.startsWith("content-type")) { - mimeType = lchdr.substring("content-type: ".length()); - continue; - }else if (!lchdr.startsWith("content-disposition")) continue; + if (lchdr.startsWith("content-type")) { + mimeType = lchdr.substring("content-type: ".length()); + continue; + } else if (!lchdr.startsWith("content-disposition")) continue; - int off = lchdr.indexOf("form-data", 20); + int off = lchdr.indexOf("form-data", 20); - if (off == -1) { - if (!debugMode) { - debugMode = true; - mpFormDataDecode(data, cont_type); - return null; - } else { - debugMode = false; - throw new IOException("Expected \'Content-Disposition: form-data\' in line: "+hdr); - } - } + if (off == -1) { + if (!debugMode) { + debugMode = true; + mpFormDataDecode(data, cont_type); + return null; + } else { + debugMode = false; + throw new IOException("Expected \'Content-Disposition: form-data\' in line: " + hdr); + } + } - name = getParameter("name", hdr); + name = getParameter("name", hdr); - if (debugMode) { - System.err.println( "[ADD name is " + filename + ']'); - } + if (debugMode) { + System.err.println("[ADD name is " + name + ']'); + } - if (name == null) { - if (!debugMode) { - debugMode = true; - mpFormDataDecode(data, cont_type); - return null; - } else { - debugMode = false; - throw new IOException("\'name\' parameter not found in header: "+hdr); - } - } + if (name == null) { + if (!debugMode) { + debugMode = true; + mpFormDataDecode(data, cont_type); + return null; + } else { + debugMode = false; + throw new IOException("\'name\' parameter not found in header: " + hdr); + } + } - filename = getParameter("filename", hdr); - if (debugMode) { - System.err.println( "[ADD filename is " + filename + ']'); - } - cont_disp = hdr; - } + filename = getParameter("filename", hdr); + if (debugMode) { + System.err.println("[ADD filename is " + filename + ']'); + } + cont_disp = hdr; + } - start += 1; + start += 1; - if (debugMode) { - System.err.println( "(End) start = " + start + - " end = " + end ); - } + if (debugMode) { + System.err.println("(End) start = " + start + + " end = " + end); + } - if (start > end) { - if (!debugMode) { - debugMode = true; - mpFormDataDecode(data, cont_type); - return null; - } else { - debugMode = false; - throw new IOException("End of header not found at offset "+end); - } - } + if (start > end) { + if (!debugMode) { + debugMode = true; + mpFormDataDecode(data, cont_type); + return null; + } else { + debugMode = false; + throw new IOException("End of header not found at offset " + end); + } + } - if (cont_disp == null) { - if (!debugMode) { - debugMode = true; - mpFormDataDecode(data, cont_type); - return null; - } else { - debugMode = false; - throw new IOException("Missing \'Content-Disposition\' header at offset "+start); - } - } + if (cont_disp == null) { + if (!debugMode) { + debugMode = true; + mpFormDataDecode(data, cont_type); + return null; + } else { + debugMode = false; + throw new IOException("Missing \'Content-Disposition\' header at offset " + start); + } + } - // handle data for this part + // handle data for this part - if (filename != null) { // It's a file - FakeFile file = new FakeFile(filename); + if (filename != null) { // It's a file + FakeFile file = new FakeFile(filename); - file.write(data, start, end-start); - file.setContentType(mimeType); + file.write(data, start, end - start); + file.setContentType(mimeType); - value = file; - } else { // It's simple data - value = new String(data, start, end-start); - } + value = file; + } else { // It's simple data + value = new String(data, start, end - start); + } - if (idx >= res.length) { - res = Util.resizeArray(res, idx+10); - } + if (idx >= res.length) { + res = Util.resizeArray(res, idx + 10); + } - res[idx] = new NVPair(name, value); - if(debugMode) { - System.err.println( "[ADD " + name + ',' + value + ',' - + value.getClass() + ']'); - } - start = end + boundary.length; - } + res[idx] = new NVPair(name, value); + if (debugMode) { + System.err.println("[ADD " + name + ',' + value + ',' + + value.getClass() + ']'); + } + start = end + boundary.length; + } - return Util.resizeArray(res, idx); + return Util.resizeArray(res, idx); } @@ -338,90 +338,95 @@ * expects:<BR> * ";" <var>param</var> "=" ( token | quoted-string ) * - * @param param the parameter name - * @param hdr the header value + * @param param the parameter name + * @param hdr the header value * @return the value for this parameter, or null if not found. */ public final static String getParameter(String param, String hdr) { - int pbeg, // parameter name begin - pend, // parameter name end - vbeg, // parameter value begin - vend = -1, // parameter value end - len = hdr.length(); - - param = param.trim(); - - while (true) { - // mark parameter name - if (debugMode) { - System.err.println( "[DEBUG] looks for " + param + " in " ); - System.err.println( "[" + hdr.substring(vend+1) + ']'); - } - pbeg = hdr.indexOf(';', vend+1); // get ';' - if (pbeg == -1) return null; - - while (pbeg < len-1 - && (Util.isWhiteSpace(hdr.charAt(pbeg)) || (hdr.charAt(pbeg) == ';'))) { - pbeg++; - } - if (pbeg == len-1) return null; - pend = hdr.indexOf('=', pbeg+1); // get '=' - if (pend == -1) return null; - vbeg = pend + 1; - while (Util.isWhiteSpace(hdr.charAt(--pend))); - pend++; + int pbeg, // parameter name begin + pend, // parameter name end + vbeg, // parameter value begin + vend = -1, // parameter value end + len = hdr.length(); - // mark parameter value + param = param.trim(); - while (vbeg < len && Util.isWhiteSpace(hdr.charAt(vbeg))) vbeg++; - if (vbeg == len) return null; + while (true) { + // mark parameter name + if (debugMode) { + System.err.println("[DEBUG] looks for " + param + " in "); + System.err.println("[" + hdr.substring(vend + 1) + ']'); + } + if (vend == -1) { + pbeg = hdr.indexOf(';', vend + 1); // get ';' + if (pbeg == -1) return null; + } else { + pbeg = vend+1; + } + while (pbeg < len - 1 + && (Util.isWhiteSpace(hdr.charAt(pbeg)) || (hdr.charAt(pbeg) == ';'))) { + pbeg++; + } + if (pbeg == len - 1) return null; + pend = hdr.indexOf('=', pbeg + 1); // get '=' + if (pend == -1) return null; + vbeg = pend + 1; + while (Util.isWhiteSpace(hdr.charAt(--pend))) ; + pend++; - vend = vbeg; - if (hdr.charAt(vbeg) == '\"') { // is a quoted-string - vbeg++; - vend = hdr.indexOf('\"', vbeg); - if (vend == -1) return null; - } else { // is a simple token - vend = hdr.indexOf(';', vbeg); - if (vend == -1) vend = hdr.length(); - while (Util.isWhiteSpace(hdr.charAt(--vend))) ; - vend++; - } + if (debugMode) { + System.err.println("[DEBUG] p is [" + hdr.substring(pbeg, pend) + "]"); + } + // mark parameter value - if (hdr.regionMatches(true, pbeg, param, 0, pend-pbeg)) - break; // found it - } + while (vbeg < len && Util.isWhiteSpace(hdr.charAt(vbeg))) vbeg++; + if (vbeg == len) return null; - return hdr.substring(vbeg, vend); + vend = vbeg; + if (hdr.charAt(vbeg) == '\"') { // is a quoted-string + vbeg++; + vend = hdr.indexOf('\"', vbeg); + if (vend == -1) return null; + } else { // is a simple token + vend = hdr.indexOf(';', vbeg); + if (vend == -1) vend = hdr.length(); + while (Util.isWhiteSpace(hdr.charAt(--vend))) ; + vend++; + } + if (hdr.regionMatches(true, pbeg, param, 0, pend - pbeg)) { + break; // found it + } + } + return hdr.substring(vbeg, vend); } private static void printData(byte[] data) { - printData(data, 0); + printData(data, 0); } private static void printData(byte[] data, int offset) { - for (int i = offset; i < data.length; i++) { - if (data[i] == '\n' || data[i] == '\r') { - System.err.print( "&" + ((int) data[i]) ); - System.err.println(); - } else { - System.err.print( (char) data[i] ); - } - } + for (int i = offset; i < data.length; i++) { + if (data[i] == '\n' || data[i] == '\r') { + System.err.print("&" + ((int) data[i])); + System.err.println(); + } else { + System.err.print((char) data[i]); + } + } } /** * Searches for the next LF in an array. * - * @param arr the byte array to search. - * @param off the offset at which to start the search. + * @param arr the byte array to search. + * @param off the offset at which to start the search. * @return the position of the CR or (arr.length-2) if not found */ private final static int findEOL(byte[] arr, int off) { - while (off < arr.length-1 && - !(arr[off++] == '\n')); - return off-1; + while (off < arr.length - 1 && + !(arr[off++] == '\n')) ; + return off - 1; } }
Received on Monday, 22 August 2011 06:50:51 UTC