Beispiel #1
0
  @Override
  public long skip(long n) throws IOException {

    if (closed) {
      throw new IOException(sm.getString("inputBuffer.streamClosed"));
    }

    if (n < 0) {
      throw new IllegalArgumentException();
    }

    long nRead = 0;
    while (nRead < n) {
      if (cb.getLength() >= n) {
        cb.setOffset(cb.getStart() + (int) n);
        nRead = n;
      } else {
        nRead += cb.getLength();
        cb.setOffset(cb.getEnd());
        int toRead = 0;
        if (cb.getChars().length < (n - nRead)) {
          toRead = cb.getChars().length;
        } else {
          toRead = (int) (n - nRead);
        }
        int nb = realReadChars(cb.getChars(), 0, toRead);
        if (nb < 0) {
          break;
        }
      }
    }

    return nRead;
  }
Beispiel #2
0
  @Override
  public void mark(int readAheadLimit) throws IOException {

    if (closed) {
      throw new IOException(sm.getString("inputBuffer.streamClosed"));
    }

    if (cb.getLength() <= 0) {
      cb.setOffset(0);
      cb.setEnd(0);
    } else {
      if ((cb.getBuffer().length > (2 * size)) && (cb.getLength()) < (cb.getStart())) {
        System.arraycopy(cb.getBuffer(), cb.getStart(), cb.getBuffer(), 0, cb.getLength());
        cb.setEnd(cb.getLength());
        cb.setOffset(0);
      }
    }
    cb.setLimit(cb.getStart() + readAheadLimit + size);
    markPos = cb.getStart();
  }
Beispiel #3
0
  /**
   * Check that the URI is normalized following character decoding.
   *
   * <p>This method checks for "\", 0, "//", "/./" and "/../". This method will return false if
   * sequences that are supposed to be normalized are still present in the URI.
   *
   * @param uriMB URI to be checked (should be chars)
   */
  public static boolean checkNormalize(MessageBytes uriMB) {

    CharChunk uriCC = uriMB.getCharChunk();
    char[] c = uriCC.getChars();
    int start = uriCC.getStart();
    int end = uriCC.getEnd();

    int pos = 0;

    // Check for '\' and 0
    for (pos = start; pos < end; pos++) {
      if (c[pos] == '\\') {
        return false;
      }
      if (c[pos] == 0) {
        return false;
      }
    }

    // Check for "//"
    for (pos = start; pos < (end - 1); pos++) {
      if (c[pos] == '/') {
        if (c[pos + 1] == '/') {
          return false;
        }
      }
    }

    // Check for ending with "/." or "/.."
    if (((end - start) >= 2) && (c[end - 1] == '.')) {
      if ((c[end - 2] == '/') || ((c[end - 2] == '.') && (c[end - 3] == '/'))) {
        return false;
      }
    }

    // Check for "/./"
    if (uriCC.indexOf("/./", 0, 3, 0) >= 0) {
      return false;
    }

    // Check for "/../"
    if (uriCC.indexOf("/../", 0, 4, 0) >= 0) {
      return false;
    }

    return true;
  }
Beispiel #4
0
  /** Character conversion of the URI. */
  protected void convertURI(MessageBytes uri, Request request) throws Exception {

    ByteChunk bc = uri.getByteChunk();
    int length = bc.getLength();
    CharChunk cc = uri.getCharChunk();
    cc.allocate(length, -1);

    String enc = connector.getURIEncoding();
    if (enc != null) {
      B2CConverter conv = request.getURIConverter();
      try {
        if (conv == null) {
          conv = new B2CConverter(enc, true);
          request.setURIConverter(conv);
        } else {
          conv.recycle();
        }
      } catch (IOException e) {
        log.error("Invalid URI encoding; using HTTP default");
        connector.setURIEncoding(null);
      }
      if (conv != null) {
        try {
          conv.convert(bc, cc, true);
          uri.setChars(cc.getBuffer(), cc.getStart(), cc.getLength());
          return;
        } catch (IOException ioe) {
          // Should never happen as B2CConverter should replace
          // problematic characters
          request.getResponse().sendError(HttpServletResponse.SC_BAD_REQUEST);
        }
      }
    }

    // Default encoding: fast conversion for ISO-8859-1
    byte[] bbuf = bc.getBuffer();
    char[] cbuf = cc.getBuffer();
    int start = bc.getStart();
    for (int i = 0; i < length; i++) {
      cbuf[i] = (char) (bbuf[i + start] & 0xff);
    }
    uri.setChars(cbuf, 0, length);
  }
Beispiel #5
0
  /*
   * Removes /./ and /../ sequences from absolute URLs.
   * Code borrowed heavily from CoyoteAdapter.normalize()
   */
  private void normalize(CharChunk cc) {
    // Strip query string and/or fragment first as doing it this way makes
    // the normalization logic a lot simpler
    int truncate = cc.indexOf('?');
    if (truncate == -1) {
      truncate = cc.indexOf('#');
    }
    char[] truncateCC = null;
    if (truncate > -1) {
      truncateCC = Arrays.copyOfRange(cc.getBuffer(), cc.getStart() + truncate, cc.getEnd());
      cc.setEnd(cc.getStart() + truncate);
    }

    if (cc.endsWith("/.") || cc.endsWith("/..")) {
      try {
        cc.append('/');
      } catch (IOException e) {
        throw new IllegalArgumentException(cc.toString(), e);
      }
    }

    char[] c = cc.getChars();
    int start = cc.getStart();
    int end = cc.getEnd();
    int index = 0;
    int startIndex = 0;

    // Advance past the first three / characters (should place index just
    // scheme://host[:port]

    for (int i = 0; i < 3; i++) {
      startIndex = cc.indexOf('/', startIndex + 1);
    }

    // Remove /./
    index = startIndex;
    while (true) {
      index = cc.indexOf("/./", 0, 3, index);
      if (index < 0) {
        break;
      }
      copyChars(c, start + index, start + index + 2, end - start - index - 2);
      end = end - 2;
      cc.setEnd(end);
    }

    // Remove /../
    index = startIndex;
    int pos;
    while (true) {
      index = cc.indexOf("/../", 0, 4, index);
      if (index < 0) {
        break;
      }
      // Can't go above the server root
      if (index == startIndex) {
        throw new IllegalArgumentException();
      }
      int index2 = -1;
      for (pos = start + index - 1; (pos >= 0) && (index2 < 0); pos--) {
        if (c[pos] == (byte) '/') {
          index2 = pos;
        }
      }
      copyChars(c, start + index2, start + index + 3, end - start - index - 3);
      end = end + index2 - index - 3;
      cc.setEnd(end);
      index = index2;
    }

    // Add the query string and/or fragment (if present) back in
    if (truncateCC != null) {
      try {
        cc.append(truncateCC, 0, truncateCC.length);
      } catch (IOException ioe) {
        throw new IllegalArgumentException(ioe);
      }
    }
  }