|  | @@ -1629,6 +1629,24 @@ int mg_write(struct mg_connection *conn, const void *buf, size_t len) {
 | 
	
		
			
				|  |  |    return (int) total;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +// Alternative alloc_vprintf() for non-compliant C runtimes
 | 
	
		
			
				|  |  | +static int alloc_vprintf2(char **buf, const char *fmt, va_list ap) {
 | 
	
		
			
				|  |  | +  va_list ap_copy;
 | 
	
		
			
				|  |  | +  int size = MG_BUF_LEN;
 | 
	
		
			
				|  |  | +  int len = -1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  *buf = NULL;
 | 
	
		
			
				|  |  | +  while (len == -1) {
 | 
	
		
			
				|  |  | +    if (*buf) free(*buf);
 | 
	
		
			
				|  |  | +    *buf = malloc(size *= 4);
 | 
	
		
			
				|  |  | +    if (!*buf) break;
 | 
	
		
			
				|  |  | +    va_copy(ap_copy, ap);
 | 
	
		
			
				|  |  | +    len = vsnprintf(*buf, size, fmt, ap_copy);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return len;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  // Print message to buffer. If buffer is large enough to hold the message,
 | 
	
		
			
				|  |  |  // return buffer. If buffer is to small, allocate large enough buffer on heap,
 | 
	
		
			
				|  |  |  // and return allocated buffer.
 | 
	
	
		
			
				|  | @@ -1644,7 +1662,12 @@ static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap) {
 | 
	
		
			
				|  |  |    va_copy(ap_copy, ap);
 | 
	
		
			
				|  |  |    len = vsnprintf(NULL, 0, fmt, ap_copy);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  if (len > (int) size &&
 | 
	
		
			
				|  |  | +  if (len < 0) {
 | 
	
		
			
				|  |  | +    // C runtime is not standard compliant, vsnprintf() returned -1.
 | 
	
		
			
				|  |  | +    // Switch to alternative code path that uses incremental allocations.
 | 
	
		
			
				|  |  | +    va_copy(ap_copy, ap);
 | 
	
		
			
				|  |  | +    len = alloc_vprintf2(buf, fmt, ap);
 | 
	
		
			
				|  |  | +  } else if (len > (int) size &&
 | 
	
		
			
				|  |  |        (size = len + 1) > 0 &&
 | 
	
		
			
				|  |  |        (*buf = (char *) malloc(size)) == NULL) {
 | 
	
		
			
				|  |  |      len = -1;  // Allocation failed, mark failure
 |