Ver código fonte

Alternative to mg_upload (Step 40/?)

bel 9 anos atrás
pai
commit
4977dd237d
1 arquivos alterados com 24 adições e 7 exclusões
  1. 24 7
      src/handle_form.inl

+ 24 - 7
src/handle_form.inl

@@ -463,6 +463,18 @@ mg_handle_form_data(struct mg_connection *conn,
 		boundary = content_type + 30;
 		bl = strlen(boundary);
 
+		if (bl + 800 > sizeof(buf)) {
+			/* Sanity check:  The algorithm can not work if bl >= sizeof(buf),
+			 * and it will not work effectively, if the buf is only a few byte
+			 * larger than bl, or it buf can not hold the multipart header
+			 * plus the boundary.
+			 * Check some reasonable number here, that should be fulfilled by
+			 * any reasonable request from every browser. If it is not
+			 * fulfilled, it might be a hand-made request, intended to
+			 * interfere with the algorithm. */
+			return 0;
+		}
+
 		for (;;) {
 
 			r = mg_read(conn,
@@ -542,8 +554,7 @@ mg_handle_form_data(struct mg_connection *conn,
 				fend = strchr(fbeg, '\"');
 				if (!fend) {
 					/* Malformed request (the filename field is optional, but if
-					 * it
-					 * exists, it needs to be terminated correctly). */
+					 * it exists, it needs to be terminated correctly). */
 					return 0;
 				}
 
@@ -595,7 +606,14 @@ mg_handle_form_data(struct mg_connection *conn,
 					while (!next) {
 						/* Store the entire buffer */
 						if (fstore) {
+							/* Set "towrite" to the number of bytes available
+							 * in the buffer */
 							towrite = (size_t)(buf - hend - 4 + buf_fill);
+							/* Subtract the boundary length, to deal with
+							 * cases the boundary is only partially stored
+							 * in the buffer. */
+							towrite -= bl + 4;
+
 							n = (size_t)fwrite(hend + 4, 1, towrite, fstore);
 							if ((n != towrite) || (ferror(fstore))) {
 								mg_cry(conn,
@@ -606,6 +624,10 @@ mg_handle_form_data(struct mg_connection *conn,
 								fstore = NULL;
 								remove_bad_file(conn, path);
 							}
+
+							memmove(buf, hend + 4 + towrite, bl + 4);
+							buf_fill = bl + 4;
+							hend = buf - 4;
 						}
 
 						/* Read new data */
@@ -630,11 +652,6 @@ mg_handle_form_data(struct mg_connection *conn,
 							 * next "--" */
 							next = strstr(next + 1, "\r\n--");
 						}
-
-						/* TODO (high): handle boundaries split between two
-						   chunks
-						   part of the chunk here, part of the chunk yet unread
-						 */
 					}
 
 					if (fstore) {