Skip to content

Commit

Permalink
Fix function to support large files (Issue #139)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelrsweet committed Feb 15, 2021
1 parent 16a14fd commit 57c9830
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Changes in v1.0.2
single source (Issue #125)
- The DNS-SD support functions did not handle when the Avahi daemon is not
running (Issue #129)
- The `papplClientGetForm` function did not support files larger than 64k
(Issue #139)
- Deleting and adding a printer with the same name will cause a crash
(Issue #141)
- Fixed a deadlock issue when calling the `papplPrinterSet...` functions from
Expand Down
53 changes: 44 additions & 9 deletions pappl/client-webif.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,11 @@ papplClientGetForm(
{
const char *content_type; // Content-Type header
const char *boundary; // boundary value for multi-part
char body[65536], // Message body
char *body, // Message body
*bodyptr, // Pointer into message body
*bodyend; // End of message body
size_t body_size = 0; // Size of message body
size_t body_alloc = 0, // Allocated message body size
body_size = 0; // Size of message body
ssize_t bytes; // Bytes read
int num_form = 0; // Number of form variables
http_state_t initial_state; // Initial HTTP state
Expand All @@ -166,7 +167,13 @@ papplClientGetForm(
return (0);
}

strlcpy(body, client->options, sizeof(body));
if ((body = strdup(client->options)) == NULL)
{
papplLogClient(client, PAPPL_LOGLEVEL_ERROR, "Unable to allocate memory for form data.");
*form = NULL;
return (0);
}

body_size = strlen(body);
content_type = "application/x-www-form-urlencoded";
}
Expand All @@ -175,13 +182,39 @@ papplClientGetForm(
// Read up to 2MB of data from the client...
*form = NULL;
initial_state = httpGetState(client->http);
body_alloc = 65536;

if ((body = malloc(body_alloc)) == NULL)
{
papplLogClient(client, PAPPL_LOGLEVEL_ERROR, "Unable to allocate memory for form data.");
*form = NULL;
return (0);
}

for (bodyptr = body, bodyend = body + sizeof(body); (bytes = httpRead2(client->http, bodyptr, (size_t)(bodyend - bodyptr))) > 0; bodyptr += bytes)
for (bodyptr = body, bodyend = body + body_alloc; (bytes = httpRead2(client->http, bodyptr, (size_t)(bodyend - bodyptr))) > 0; bodyptr += bytes)
{
body_size += (size_t)bytes;

if (body_size >= sizeof(body))
break;
if (body_size >= body_alloc)
{
char *temp; // Temporary pointer

if (body_alloc >= (2 * 1024 * 1024))
break;

body_alloc += 65536;
if ((temp = realloc(body, body_alloc)) == NULL)
{
papplLogClient(client, PAPPL_LOGLEVEL_ERROR, "Unable to allocate memory for form data.");
free(body);
*form = NULL;
return (0);
}

bodyptr = temp + (bodyptr - body);
bodyend = temp + body_alloc;
body = temp;
}
}

papplLogClient(client, PAPPL_LOGLEVEL_DEBUG, "Read %ld bytes of form data (%s).", (long)body_size, content_type);
Expand Down Expand Up @@ -380,6 +413,8 @@ papplClientGetForm(
}
}

free(body);

// Return whatever we got...
return (num_form);
}
Expand Down Expand Up @@ -1217,7 +1252,7 @@ papplClientHTMLPuts(
//
// This function starts a HTML form with the specified "action" path and
// includes the CSRF token as a hidden variable. If the "multipart" argument
// is `true`, the form is annotated to support file attachments up to 1MiB in
// is `true`, the form is annotated to support file attachments up to 2MiB in
// size.
//

Expand All @@ -1232,11 +1267,11 @@ papplClientHTMLStartForm(

if (multipart)
{
// When allowing file attachments, the maximum size is 1MB...
// When allowing file attachments, the maximum size is 2MB...
papplClientHTMLPrintf(client,
" <form action=\"%s\" id=\"form\" method=\"POST\" enctype=\"multipart/form-data\">\n"
" <input type=\"hidden\" name=\"session\" value=\"%s\">\n"
" <input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"65536\">\n", action, papplClientGetCSRFToken(client, token, sizeof(token)));
" <input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"2097152\">\n", action, papplClientGetCSRFToken(client, token, sizeof(token)));
}
else
{
Expand Down

0 comments on commit 57c9830

Please sign in to comment.