]> granicus.if.org Git - apache/commitdiff
New optional flag to enforce <CR><LF> line delimiters in ap_[r]getline,
authorWilliam A. Rowe Jr <wrowe@apache.org>
Mon, 29 Aug 2016 22:17:07 +0000 (22:17 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Mon, 29 Aug 2016 22:17:07 +0000 (22:17 +0000)
created by overloading 'int fold' (1 or 0) as 'int flags', with the same
value 1 for AP_GETLINE_FOLD (which httpd doesn't use), and a new value
2 for AP_GETLINE_CRLF

Enforce CRLF when HttpProtocolOptions Strict is in force.

Correctly introduces a new t/TEST fail.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1758304 13f79535-47bb-0310-9956-ffa450edef68

include/ap_mmn.h
include/http_protocol.h
server/protocol.c

index e0b4a35939e5732d412127ef5f51a50356cd1633..aea8507f41b36b0c56c2dc42ffab319d3871cf4f 100644 (file)
  * 20160617.1 (2.5.0-dev)  Added http_whitespace and http_methods to
  *                         core_server_config
  * 20160629.1 (2.5.0-dev)  Dropped http_whitespace from core_server_config
+ * 20160629.2 (2.5.0-dev)  Replaced fold w/multiple flags for ap_[r]getline()
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20160629
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 1                 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 2                 /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
index 07fc6e9e470f92f0b664c470614352e443731640..77c9766b60eec8cf2886c98d2449863009b23b45 100644 (file)
@@ -589,17 +589,22 @@ AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw);
  */
 AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri);
 
+#define AP_GETLINE_FOLD 1 /* Whether to merge continuation lines */
+#define AP_GETLINE_CRLF 2 /*Whether line ends must be in the form CR LF */
+
 /**
  * Get the next line of input for the request
  * @param s The buffer into which to read the line
  * @param n The size of the buffer
  * @param r The request
- * @param fold Whether to merge continuation lines
+ * @param flags Bit flag of multiple parsing options
+ *              AP_GETLINE_FOLD Whether to merge continuation lines
+ *              AP_GETLINE_CRLF Whether line ends must be in the form CR LF
  * @return The length of the line, if successful
  *         n, if the line is too big to fit in the buffer
  *         -1 for miscellaneous errors
  */
-AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold);
+AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int flags);
 
 /**
  * Get the next line of input for the request
@@ -617,7 +622,9 @@ AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold);
  * @param n The size of the buffer
  * @param read The length of the line.
  * @param r The request
- * @param fold Whether to merge continuation lines
+ * @param flags Bit flag of multiple parsing options
+ *              AP_GETLINE_FOLD Whether to merge continuation lines
+ *              AP_GETLINE_CRLF Whether line ends must be in the form CR LF
  * @param bb Working brigade to use when reading buckets
  * @return APR_SUCCESS, if successful
  *         APR_ENOSPC, if the line is too big to fit in the buffer
@@ -626,7 +633,7 @@ AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold);
 #if APR_CHARSET_EBCDIC
 AP_DECLARE(apr_status_t) ap_rgetline(char **s, apr_size_t n,
                                      apr_size_t *read,
-                                     request_rec *r, int fold,
+                                     request_rec *r, int flags,
                                      apr_bucket_brigade *bb);
 #else /* ASCII box */
 #define ap_rgetline(s, n, read, r, fold, bb) \
@@ -636,7 +643,7 @@ AP_DECLARE(apr_status_t) ap_rgetline(char **s, apr_size_t n,
 /** @see ap_rgetline */
 AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n,
                                           apr_size_t *read,
-                                          request_rec *r, int fold,
+                                          request_rec *r, int flags,
                                           apr_bucket_brigade *bb);
 
 /**
index 960d901ebda0d86f987ef17efb478abe2e3eedc2..875bcbba66eed6cd2fcadceb4795156194290341 100644 (file)
@@ -215,13 +215,15 @@ AP_DECLARE(apr_time_t) ap_rationalize_mtime(request_rec *r, apr_time_t mtime)
  */
 AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n,
                                           apr_size_t *read, request_rec *r,
-                                          int fold, apr_bucket_brigade *bb)
+                                          int flags, apr_bucket_brigade *bb)
 {
     apr_status_t rv;
     apr_bucket *e;
     apr_size_t bytes_handled = 0, current_alloc = 0;
     char *pos, *last_char = *s;
     int do_alloc = (*s == NULL), saw_eos = 0;
+    int fold = flags & AP_GETLINE_FOLD;
+    int crlf = flags & AP_GETLINE_CRLF;
 
     /*
      * Initialize last_char as otherwise a random value will be compared
@@ -327,6 +329,13 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n,
         }
     }
 
+    if (last_char <= *s || last_char[-1] != APR_ASCII_CR) {
+        *last_char = '\0';
+        bytes_handled = last_char - *s;
+        *read = bytes_handled;
+        return APR_EINVAL;
+    }
+
     /* Now NUL-terminate the string at the end of the line;
      * if the last-but-one character is a CR, terminate there */
     if (last_char > *s && last_char[-1] == APR_ASCII_CR) {
@@ -471,7 +480,7 @@ AP_DECLARE(apr_status_t) ap_rgetline(char **s, apr_size_t n,
 }
 #endif
 
-AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold)
+AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int flags)
 {
     char *tmp_s = s;
     apr_status_t rv;
@@ -479,7 +488,7 @@ AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold)
     apr_bucket_brigade *tmp_bb;
 
     tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
-    rv = ap_rgetline(&tmp_s, n, &len, r, fold, tmp_bb);
+    rv = ap_rgetline(&tmp_s, n, &len, r, flags, tmp_bb);
     apr_brigade_destroy(tmp_bb);
 
     /* Map the out-of-space condition to the old API. */
@@ -607,7 +616,7 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
          */
         r->the_request = NULL;
         rv = ap_rgetline(&(r->the_request), (apr_size_t)(r->server->limit_req_line + 2),
-                         &len, r, 0, bb);
+                         &len, r, strict ? AP_GETLINE_CRLF : 0, bb);
 
         if (rv != APR_SUCCESS) {
             r->request_time = apr_time_now();
@@ -953,7 +962,7 @@ AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb
 
         field = NULL;
         rv = ap_rgetline(&field, r->server->limit_req_fieldsize + 2,
-                         &len, r, 0, bb);
+                         &len, r, strict ? AP_GETLINE_CRLF : 0, bb);
 
         if (rv != APR_SUCCESS) {
             if (APR_STATUS_IS_TIMEUP(rv)) {