Hello community,
here is the log from the commit of package libhtp for openSUSE:Factory checked in at 2020-05-01 11:12:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libhtp (Old)
and /work/SRC/openSUSE:Factory/.libhtp.new.2738 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libhtp"
Fri May 1 11:12:33 2020 rev:4 rq:799119 version:0.5.33
Changes:
--------
--- /work/SRC/openSUSE:Factory/libhtp/libhtp.changes 2019-12-17 16:55:03.581350693 +0100
+++ /work/SRC/openSUSE:Factory/.libhtp.new.2738/libhtp.changes 2020-05-01 11:12:34.823746607 +0200
@@ -1,0 +2,8 @@
+Wed Apr 29 18:33:00 UTC 2020 - Martin Hauke
+
+- Update to version 0.5.33
+ * compression bomb protection
+ * memory handling issue found by Oss-Fuzz
+ * improve handling of anomalies in traffic
+
+-------------------------------------------------------------------
Old:
----
libhtp-0.5.32.tar.gz
New:
----
libhtp-0.5.33.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ libhtp.spec ++++++
--- /var/tmp/diff_new_pack.Ih0Qep/_old 2020-05-01 11:12:35.739748600 +0200
+++ /var/tmp/diff_new_pack.Ih0Qep/_new 2020-05-01 11:12:35.739748600 +0200
@@ -1,7 +1,7 @@
#
# spec file for package libhtp
#
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%define sover 2
%define lname %{name}%{sover}
Name: libhtp
-Version: 0.5.32
+Version: 0.5.33
Release: 0
Summary: HTTP normalizer and parser
License: BSD-3-Clause
++++++ libhtp-0.5.32.tar.gz -> libhtp-0.5.33.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/ChangeLog new/libhtp-0.5.33/ChangeLog
--- old/libhtp-0.5.32/ChangeLog 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/ChangeLog 2020-04-27 15:30:04.000000000 +0200
@@ -1,3 +1,12 @@
+0.5.33 (27 April 2020)
+----------------------
+
+- compression bomb protection
+
+- memory handling issue found by Oss-Fuzz
+
+- improve handling of anomalies in traffic
+
0.5.32 (13 December 2019)
--------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/VERSION new/libhtp-0.5.33/VERSION
--- old/libhtp-0.5.32/VERSION 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/VERSION 2020-04-27 15:30:04.000000000 +0200
@@ -1,2 +1,2 @@
# This file is intended to be sourced by sh
-PKG_VERSION=0.5.32
+PKG_VERSION=0.5.33
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/configure.ac new/libhtp-0.5.33/configure.ac
--- old/libhtp-0.5.32/configure.ac 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/configure.ac 2020-04-27 15:30:04.000000000 +0200
@@ -155,6 +155,24 @@
sinclude(m4/lib-prefix.m4)
AM_ICONV
+# iconvctl is not standard, it is defined only in GNU libiconv
+AC_MSG_CHECKING(for iconvctl)
+TMPLIBS="${LIBS}"
+LIBS="${LIBS} ${LIBICONV}"
+
+AC_TRY_LINK([#include
+ #include ],
+ [int iconv_param = 0;
+ iconv_t cd = iconv_open("","");
+ iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, &iconv_param);
+ iconv_close(cd);],
+ [ac_cv_func_iconvctl=yes])
+AC_MSG_RESULT($ac_cv_func_iconvctl)
+if test "$ac_cv_func_iconvctl" == yes; then
+ AC_DEFINE(HAVE_ICONVCTL,1,"Define to 1 if you have the `iconvctl' function.")
+fi
+LIBS="${TMPLIBS}"
+
dnl -----------------------------------------------
dnl Check and enable the GCC opts we want to use.
dnl We may need to add more checks
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/htp/htp_config.c new/libhtp-0.5.33/htp/htp_config.c
--- old/libhtp-0.5.32/htp/htp_config.c 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/htp/htp_config.c 2020-04-27 15:30:04.000000000 +0200
@@ -160,6 +160,7 @@
cfg->response_decompression_layer_limit = 2; // 2 layers seem fairly common
cfg->lzma_memlimit = HTP_LZMA_MEMLIMIT;
cfg->compression_bomb_limit = HTP_COMPRESSION_BOMB_LIMIT;
+ cfg->compression_time_limit = HTP_COMPRESSION_TIME_LIMIT_USEC;
// Default settings for URL-encoded data.
@@ -523,6 +524,16 @@
}
}
+void htp_config_set_compression_time_limit(htp_cfg_t *cfg, size_t useclimit) {
+ if (cfg == NULL) return;
+ // max limit is one second
+ if (useclimit >= 1000000) {
+ cfg->compression_time_limit = 1000000;
+ } else {
+ cfg->compression_time_limit = useclimit;
+ }
+}
+
void htp_config_set_log_level(htp_cfg_t *cfg, enum htp_log_level_t log_level) {
if (cfg == NULL) return;
cfg->log_level = log_level;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/htp/htp_config.h new/libhtp-0.5.33/htp/htp_config.h
--- old/libhtp-0.5.32/htp/htp_config.h 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/htp/htp_config.h 2020-04-27 15:30:04.000000000 +0200
@@ -443,6 +443,14 @@
void htp_config_set_compression_bomb_limit(htp_cfg_t *cfg, size_t bomblimit);
/**
+ * Configures the maximum compression bomb time LibHTP will decompress.
+ *
+ * @param[in] cfg
+ * @param[in] useclimit
+ */
+void htp_config_set_compression_time_limit(htp_cfg_t *cfg, size_t useclimit);
+
+/**
* Configures the desired log level.
*
* @param[in] cfg
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/htp/htp_config_private.h new/libhtp-0.5.33/htp/htp_config_private.h
--- old/libhtp-0.5.32/htp/htp_config_private.h 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/htp/htp_config_private.h 2020-04-27 15:30:04.000000000 +0200
@@ -348,6 +348,9 @@
/** max output size for a compression bomb. */
int32_t compression_bomb_limit;
+
+ /** max time for a decompression bomb. */
+ int32_t compression_time_limit;
};
#ifdef __cplusplus
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/htp/htp_decompressors.h new/libhtp-0.5.33/htp/htp_decompressors.h
--- old/libhtp-0.5.32/htp/htp_decompressors.h 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/htp/htp_decompressors.h 2020-04-27 15:30:04.000000000 +0200
@@ -59,6 +59,9 @@
htp_status_t (*callback)(htp_tx_data_t *);
void (*destroy)(htp_decompressor_t *);
struct htp_decompressor_t *next;
+ struct timeval time_before;
+ int32_t time_spent;
+ uint32_t nb_callbacks;
};
struct htp_decompressor_gzip_t {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/htp/htp_private.h new/libhtp-0.5.33/htp/htp_private.h
--- old/libhtp-0.5.32/htp/htp_private.h 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/htp/htp_private.h 2020-04-27 15:30:04.000000000 +0200
@@ -83,6 +83,10 @@
//deflate max ratio is about 1000
#define HTP_COMPRESSION_BOMB_RATIO 2048
#define HTP_COMPRESSION_BOMB_LIMIT 1048576
+// 0.1 second
+#define HTP_COMPRESSION_TIME_LIMIT_USEC 100000
+// test time for compression every 256 callbacks
+#define HTP_COMPRESSION_TIME_FREQ_TEST 256
#define HTP_FIELD_LIMIT_HARD 18000
#define HTP_FIELD_LIMIT_SOFT 9000
@@ -157,7 +161,7 @@
int htp_connp_is_line_folded(unsigned char *data, size_t len);
int htp_is_folding_char(int c);
-int htp_connp_is_line_terminator(htp_connp_t *connp, unsigned char *data, size_t len);
+int htp_connp_is_line_terminator(htp_connp_t *connp, unsigned char *data, size_t len, int next_no_lf);
int htp_connp_is_line_ignorable(htp_connp_t *connp, unsigned char *data, size_t len);
int htp_parse_uri(bstr *input, htp_uri_t **uri);
@@ -167,8 +171,6 @@
int htp_parse_uri_hostport(htp_connp_t *connp, bstr *input, htp_uri_t *uri);
int htp_normalize_parsed_uri(htp_tx_t *tx, htp_uri_t *parsed_uri_incomplete, htp_uri_t *parsed_uri);
bstr *htp_normalize_hostname_inplace(bstr *input);
-void htp_replace_hostname(htp_connp_t *connp, htp_uri_t *parsed_uri, bstr *hostname);
-int htp_is_uri_unreserved(unsigned char c);
int htp_decode_path_inplace(htp_tx_t *tx, bstr *path);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/htp/htp_request.c new/libhtp-0.5.33/htp/htp_request.c
--- old/libhtp-0.5.32/htp/htp_request.c 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/htp/htp_request.c 2020-04-27 15:30:04.000000000 +0200
@@ -647,7 +647,7 @@
#endif
// Should we terminate headers?
- if (htp_connp_is_line_terminator(connp, data, len)) {
+ if (htp_connp_is_line_terminator(connp, data, len, 0)) {
// Parse previous header, if any.
if (connp->in_header != NULL) {
if (connp->cfg->process_request_header(connp, bstr_ptr(connp->in_header),
@@ -816,6 +816,10 @@
htp_status_t htp_connp_REQ_LINE(htp_connp_t *connp) {
for (;;) {
// Get one byte
+ IN_PEEK_NEXT(connp);
+ if (connp->in_status == HTP_STREAM_CLOSED && connp->in_next_byte == -1) {
+ return htp_connp_REQ_LINE_complete(connp);
+ }
IN_COPY_BYTE_OR_RETURN(connp);
// Have we reached the end of the line?
@@ -869,7 +873,12 @@
while ((pos < len) && (!htp_is_space(data[pos])))
pos++;
- if (pos > mstart) {
+ if (pos <= mstart) {
+ //empty whitespace line
+ htp_status_t rc = htp_tx_req_process_body_data_ex(connp->in_tx, data, len);
+ htp_connp_req_clear_buffer(connp);
+ return rc;
+ } else {
int methodi = HTP_M_UNKNOWN;
bstr *method = bstr_dup_mem(data + mstart, pos - mstart);
if (method) {
@@ -882,9 +891,8 @@
htp_status_t rc = htp_tx_req_process_body_data_ex(connp->in_tx, data, len);
htp_connp_req_clear_buffer(connp);
return rc;
- }
+ } // else continue
}
- //else
//unread last end of line so that REQ_LINE works
if (connp->in_current_read_offset < (int64_t)len) {
connp->in_current_read_offset=0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/htp/htp_response.c new/libhtp-0.5.33/htp/htp_response.c
--- old/libhtp-0.5.32/htp/htp_response.c 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/htp/htp_response.c 2020-04-27 15:30:04.000000000 +0200
@@ -826,8 +826,13 @@
fprint_raw_data(stderr, __func__, data, len);
#endif
+ int next_no_lf = 0;
+ if (connp->out_current_read_offset < connp->out_current_len &&
+ connp->out_current_data[connp->out_current_read_offset] != LF) {
+ next_no_lf = 1;
+ }
// Should we terminate headers?
- if (htp_connp_is_line_terminator(connp, data, len)) {
+ if (htp_connp_is_line_terminator(connp, data, len, next_no_lf)) {
// Parse previous header, if any.
if (connp->out_header != NULL) {
if (connp->cfg->process_response_header(connp, bstr_ptr(connp->out_header),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/htp/htp_transaction.c new/libhtp-0.5.33/htp/htp_transaction.c
--- old/libhtp-0.5.32/htp/htp_transaction.c 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/htp/htp_transaction.c 2020-04-27 15:30:04.000000000 +0200
@@ -776,6 +776,19 @@
htp_connp_destroy_decompressors(tx->connp);
}
+static htp_status_t htp_timer_track(int32_t *time_spent, struct timeval * after, struct timeval *before) {
+ if (after->tv_sec < before->tv_sec) {
+ return HTP_ERROR;
+ } else if (after->tv_sec == before->tv_sec) {
+ if (after->tv_usec < before->tv_usec) {
+ return HTP_ERROR;
+ }
+ *time_spent += after->tv_usec - before->tv_usec;
+ } else {
+ *time_spent += (after->tv_sec - before->tv_sec) * 1000000 + after->tv_usec - before->tv_usec;
+ }
+ return HTP_OK;
+}
static htp_status_t htp_tx_res_process_body_data_decompressor_callback(htp_tx_data_t *d) {
if (d == NULL) return HTP_ERROR;
@@ -789,6 +802,23 @@
// Invoke all callbacks.
htp_status_t rc = htp_res_run_hook_body_data(d->tx->connp, d);
if (rc != HTP_OK) return HTP_ERROR;
+ d->tx->connp->out_decompressor->nb_callbacks++;
+ if (d->tx->connp->out_decompressor->nb_callbacks % HTP_COMPRESSION_TIME_FREQ_TEST == 0) {
+ struct timeval after;
+ gettimeofday(&after, NULL);
+ // sanity check for race condition if system time changed
+ if ( htp_timer_track(&d->tx->connp->out_decompressor->time_spent, &after, &d->tx->connp->out_decompressor->time_before) == HTP_OK) {
+ // updates last tracked time
+ d->tx->connp->out_decompressor->time_before = after;
+ if (d->tx->connp->out_decompressor->time_spent > d->tx->connp->cfg->compression_time_limit ) {
+ htp_log(d->tx->connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
+ "Compression bomb: spent %"PRId64" us decompressing",
+ d->tx->connp->out_decompressor->time_spent);
+ return HTP_ERROR;
+ }
+ }
+
+ }
if (d->tx->response_entity_len > d->tx->connp->cfg->compression_bomb_limit &&
d->tx->response_entity_len > HTP_COMPRESSION_BOMB_RATIO * d->tx->response_message_len) {
htp_log(d->tx->connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
@@ -834,8 +864,21 @@
if (tx->connp->out_decompressor == NULL || tx->connp->out_decompressor->decompress == NULL)
return HTP_ERROR;
+ struct timeval after;
+ gettimeofday(&tx->connp->out_decompressor->time_before, NULL);
// Send data buffer to the decompressor.
+ tx->connp->out_decompressor->nb_callbacks=0;
tx->connp->out_decompressor->decompress(tx->connp->out_decompressor, &d);
+ gettimeofday(&after, NULL);
+ // sanity check for race condition if system time changed
+ if ( htp_timer_track(&tx->connp->out_decompressor->time_spent, &after, &tx->connp->out_decompressor->time_before) == HTP_OK) {
+ if ( tx->connp->out_decompressor->time_spent > tx->connp->cfg->compression_time_limit ) {
+ htp_log(tx->connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
+ "Compression bomb: spent %"PRId64" us decompressing",
+ tx->connp->out_decompressor->time_spent);
+ return HTP_ERROR;
+ }
+ }
if (data == NULL) {
// Shut down the decompressor, if we used one.
@@ -1350,10 +1393,6 @@
* or a overly long request */
if (tx->request_method == HTP_M_UNKNOWN && tx->request_uri == NULL && tx->connp->in_state == htp_connp_REQ_LINE) {
htp_log(tx->connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request line incomplete");
-
- if (htp_connp_REQ_LINE_complete(tx->connp) != HTP_OK) {
- return HTP_ERROR;
- }
}
return HTP_OK;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/htp/htp_transcoder.c new/libhtp-0.5.33/htp/htp_transcoder.c
--- old/libhtp-0.5.32/htp/htp_transcoder.c 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/htp/htp_transcoder.c 2020-04-27 15:30:04.000000000 +0200
@@ -64,7 +64,7 @@
return HTP_ERROR;
}
- #if (_LIBICONV_VERSION >= 0x0108)
+ #if (_LIBICONV_VERSION >= 0x0108 && HAVE_ICONVCTL)
int iconv_param = 0;
iconvctl(cd, ICONV_SET_TRANSLITERATE, &iconv_param);
iconv_param = 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libhtp-0.5.32/htp/htp_util.c new/libhtp-0.5.33/htp/htp_util.c
--- old/libhtp-0.5.32/htp/htp_util.c 2019-12-13 10:30:17.000000000 +0100
+++ new/libhtp-0.5.33/htp/htp_util.c 2020-04-27 15:30:04.000000000 +0200
@@ -464,7 +464,7 @@
* @param[in] len
* @return 0 or 1
*/
-int htp_connp_is_line_terminator(htp_connp_t *connp, unsigned char *data, size_t len) {
+int htp_connp_is_line_terminator(htp_connp_t *connp, unsigned char *data, size_t len, int next_no_lf) {
// Is this the end of request headers?
switch (connp->cfg->server_personality) {
case HTP_SERVER_IIS_5_1:
@@ -481,10 +481,7 @@
}
// Only space is terminator if terminator does not follow right away
if (len == 2 && htp_is_lws(data[0]) && data[1] == LF) {
- if (connp->out_current_read_offset < connp->out_current_len &&
- connp->out_current_data[connp->out_current_read_offset] != LF) {
- return 1;
- }
+ return next_no_lf;
}
break;
}
@@ -501,7 +498,7 @@
* @return 0 or 1
*/
int htp_connp_is_line_ignorable(htp_connp_t *connp, unsigned char *data, size_t len) {
- return htp_connp_is_line_terminator(connp, data, len);
+ return htp_connp_is_line_terminator(connp, data, len, 0);
}
static htp_status_t htp_parse_port(unsigned char *data, size_t len, int *port, int *invalid) {
@@ -1860,136 +1857,6 @@
return hostname;
}
-#if 0
-
-/**
- * Replace the URI in the structure with the one provided as the parameter
- * to this function (which will typically be supplied in a Host header).
- *
- * @param[in] connp
- * @param[in] parsed_uri
- * @param[in] hostname
- */
-void htp_replace_hostname(htp_connp_t *connp, htp_uri_t *parsed_uri, bstr *hostname) {
- if (hostname == NULL) return;
-
- bstr *new_hostname = NULL;
-
- int colon = bstr_chr(hostname, ':');
- if (colon == -1) {
- // Hostname alone (no port information)
- new_hostname = bstr_dup(hostname);
- if (new_hostname == NULL) return;
- htp_normalize_hostname_inplace(new_hostname);
-
- if (parsed_uri->hostname != NULL) bstr_free(parsed_uri->hostname);
- parsed_uri->hostname = new_hostname;
- } else {
- // Hostname and port
- new_hostname = bstr_dup_ex(hostname, 0, colon);
- if (new_hostname == NULL) return;
- // TODO Handle whitespace around hostname
- htp_normalize_hostname_inplace(new_hostname);
-
- if (parsed_uri->hostname != NULL) bstr_free(parsed_uri->hostname);
- parsed_uri->hostname = new_hostname;
- parsed_uri->port_number = 0;
-
- // Port
- int port = htp_parse_positive_integer_whitespace((unsigned char *) bstr_ptr(hostname) + colon + 1,
- bstr_len(hostname) - colon - 1, 10);
- if (port < 0) {
- // Failed to parse port
- htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Invalid server port information in request");
- } else if ((port > 0) && (port < 65536)) {
- // Valid port
- if ((connp->conn->server_port != 0) && (port != connp->conn->server_port)) {
- // Port was specified in connection and is different from the TCP port
- htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Request server port=%d number differs from the actual TCP port=%d", port, connp->conn->server_port);
- } else {
- parsed_uri->port_number = port;
- }
- }
- }
-}
-
-/**
- * Is URI character reserved?
- *
- * @param[in] c
- * @return 1 if it is, 0 if it isn't
- */
-int htp_is_uri_unreserved(unsigned char c) {
- if (((c >= 0x41) && (c <= 0x5a)) ||
- ((c >= 0x61) && (c <= 0x7a)) ||
- ((c >= 0x30) && (c <= 0x39)) ||
- (c == 0x2d) || (c == 0x2e) ||
- (c == 0x5f) || (c == 0x7e)) {
- return 1;
- } else {
- return 0;
- }
-}
-
-/**
- * Decode a URL-encoded string, leaving the reserved
- * characters and invalid encodings alone.
- *
- * @param[in] s
- */
-void htp_uriencoding_normalize_inplace(bstr *s) {
- if (s == NULL) return;
-
- unsigned char *data = bstr_ptr(s);
- if (data == NULL) return;
- size_t len = bstr_len(s);
-
- size_t rpos = 0;
- size_t wpos = 0;
-
- while (rpos < len) {
- if (data[rpos] == '%') {
- if (rpos + 2 < len) {
- if (isxdigit(data[rpos + 1]) && (isxdigit(data[rpos + 2]))) {
- unsigned char c = x2c(&data[rpos + 1]);
-
- if (htp_is_uri_unreserved(c)) {
- // Leave reserved characters encoded, but convert
- // the hexadecimal digits to uppercase
- data[wpos++] = data[rpos++];
- data[wpos++] = toupper(data[rpos++]);
- data[wpos++] = toupper(data[rpos++]);
- } else {
- // Decode unreserved character
- data[wpos++] = c;
- rpos += 3;
- }
- } else {
- // Invalid URL encoding: invalid hex digits
-
- // Copy over what's there
- data[wpos++] = data[rpos++];
- data[wpos++] = toupper(data[rpos++]);
- data[wpos++] = toupper(data[rpos++]);
- }
- } else {
- // Invalid URL encoding: string too short
-
- // Copy over what's there
- data[wpos++] = data[rpos++];
- while (rpos < len) {
- data[wpos++] = toupper(data[rpos++]);
- }
- }
- } else {
- data[wpos++] = data[rpos++];
- }
- }
-
- bstr_adjust_len(s, wpos);
-}
-#endif
-
/**
* Normalize URL path. This function implements the remove dot segments algorithm
* specified in RFC 3986, section 5.2.4.
@@ -2360,21 +2227,6 @@
if (uri->query != NULL) {
bstr_add_c_noex(r, "?");
bstr_add_noex(r, uri->query);
-
- /*
- bstr *query = bstr_dup(uri->query);
- if (query == NULL) {
- bstr_free(r);
- return NULL;
- }
-
- htp_uriencoding_normalize_inplace(query);
-
- bstr_add_c_noex(r, "?");
- bstr_add_noex(r, query);
-
- bstr_free(query);
- */
}
if (uri->fragment != NULL) {