|  | @@ -1467,15 +1467,38 @@ int mg_write(struct mg_connection *conn, const void *buf, size_t len) {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  int mg_printf(struct mg_connection *conn, const char *fmt, ...) {
 | 
	
		
			
				|  |  | -  char buf[MG_BUF_LEN];
 | 
	
		
			
				|  |  | +  char mem[MG_BUF_LEN], *buf = mem;
 | 
	
		
			
				|  |  |    int len;
 | 
	
		
			
				|  |  |    va_list ap;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  // Print in a local buffer first, hoping that it is large enough to
 | 
	
		
			
				|  |  | +  // hold the whole message
 | 
	
		
			
				|  |  |    va_start(ap, fmt);
 | 
	
		
			
				|  |  | -  len = mg_vsnprintf(conn, buf, sizeof(buf), fmt, ap);
 | 
	
		
			
				|  |  | +  len = vsnprintf(mem, sizeof(mem), fmt, ap);
 | 
	
		
			
				|  |  |    va_end(ap);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  return mg_write(conn, buf, (size_t)len);
 | 
	
		
			
				|  |  | +  if (len <= 0) {
 | 
	
		
			
				|  |  | +    // vsnprintf() error, give up
 | 
	
		
			
				|  |  | +    len = -1;
 | 
	
		
			
				|  |  | +    cry(conn, "%s(%s, ...): vsnprintf() error", __func__, fmt);
 | 
	
		
			
				|  |  | +  } else if (len > (int) sizeof(mem) && (buf = malloc(len + 1)) != NULL) {
 | 
	
		
			
				|  |  | +    // Local buffer is not large enough, allocate big buffer on heap
 | 
	
		
			
				|  |  | +    va_start(ap, fmt);
 | 
	
		
			
				|  |  | +    vsnprintf(buf, len + 1, fmt, ap);
 | 
	
		
			
				|  |  | +    va_end(ap);
 | 
	
		
			
				|  |  | +    len = mg_write(conn, buf, (size_t) len);
 | 
	
		
			
				|  |  | +    free(buf);
 | 
	
		
			
				|  |  | +  } else if (len > (int) sizeof(mem)) {
 | 
	
		
			
				|  |  | +    // Failed to allocate large enough buffer, give up
 | 
	
		
			
				|  |  | +    cry(conn, "%s(%s, ...): Can't allocate %d bytes, not printing anything",
 | 
	
		
			
				|  |  | +        __func__, fmt, len);
 | 
	
		
			
				|  |  | +    len = -1;
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    // Copy to the local buffer succeeded
 | 
	
		
			
				|  |  | +    len = mg_write(conn, buf, (size_t) len);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return len;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // URL-decode input buffer into destination buffer.
 |