Some memory changes in forms.

This commit is contained in:
2025-05-31 08:36:48 -04:00
parent bfa41d20ac
commit 9ddc88d151

View File

@ -32,6 +32,8 @@
#include <string> #include <string>
#include <optional> #include <optional>
#include <boost/lexical_cast.hpp>
#include <Alepha/AutoRAII.h> #include <Alepha/AutoRAII.h>
@ -101,9 +103,9 @@ class DilloHtmlForm {
void inputMultipartAppend(std::string &data, std::string_view boundary, void inputMultipartAppend(std::string &data, std::string_view boundary,
std::string_view name, std::string_view value); std::string_view name, std::string_view value);
void filesInputMultipartAppend(std::string &data, std::string_view boundary, void filesInputMultipartAppend(std::string &data, std::string_view boundary,
std::string_view name, Dstr *file, std::string_view name, const std::string &file,
std::string_view filename); std::string_view filename);
void imageInputUrlencodeAppend(std::string &data, std::string_view name, Dstr *x, Dstr *y); void imageInputUrlencodeAppend(std::string &data, std::string_view name, std::string_view x, std::string_view y);
void imageInputMultipartAppend(std::string &data, std::string_view boundary, std::string_view name, void imageInputMultipartAppend(std::string &data, std::string_view boundary, std::string_view name,
std::string_view x, std::string_view y); std::string_view x, std::string_view y);
@ -179,7 +181,7 @@ public:
DilloHtmlInput (DilloHtmlInputType type, Embed *embed, DilloHtmlInput (DilloHtmlInputType type, Embed *embed,
const std::optional< std::string > &name, const std::optional< std::string > &init_str, bool init_val); const std::optional< std::string > &name, const std::optional< std::string > &init_str, bool init_val);
~DilloHtmlInput (); ~DilloHtmlInput ();
void appendValuesTo(Dlist *values, bool is_active_submit); void appendValuesTo(std::vector< std::string > &values, bool is_active_submit);
void reset(); void reset();
void setEnabled(bool enabled) {if (embed) embed->setEnabled(enabled); }; void setEnabled(bool enabled) {if (embed) embed->setEnabled(enabled); };
}; };
@ -241,7 +243,7 @@ public:
void ensureSelection (); void ensureSelection ();
void addOptsTo (SelectionResource *res); void addOptsTo (SelectionResource *res);
void reset (SelectionResource *res); void reset (SelectionResource *res);
void appendValuesTo (Dlist *values, SelectionResource *res); void appendValuesTo (std::vector< std::string > &values, SelectionResource *res);
}; };
/* /*
@ -1154,7 +1156,7 @@ std::optional< std::string > DilloHtmlForm::buildQueryData(DilloHtmlInput *activ
} }
if ((content_type == DILLO_HTML_ENC_URLENCODED) || (boundary != NULL)) { if ((content_type == DILLO_HTML_ENC_URLENCODED) || (boundary != NULL)) {
Dlist *values = dList_new(5); std::vector< std::string > values;
for (int i = 0; i < inputs.size(); i++) { for (int i = 0; i < inputs.size(); i++) {
auto input = inputs.at (i); auto input = inputs.at (i);
@ -1166,12 +1168,12 @@ std::optional< std::string > DilloHtmlForm::buildQueryData(DilloHtmlInput *activ
input->appendValuesTo(values, is_active_submit); input->appendValuesTo(values, is_active_submit);
if ((valcount = dList_length(values)) > 0) { if ((valcount = values.size()) > 0) {
if (input->type == DILLO_HTML_INPUT_FILE) { if (input->type == DILLO_HTML_INPUT_FILE) {
if (valcount > 1) if (valcount > 1)
MSG_WARN("multiple files per form control not supported\n"); MSG_WARN("multiple files per form control not supported\n");
Dstr *file = (Dstr *) dList_nth_data(values, 0); auto file= values.front();
dList_remove(values, file); values.erase( begin( values ) );
/* Get filename and encode it. Do not encode file contents. */ /* Get filename and encode it. Do not encode file contents. */
LabelButtonResource *lbr = LabelButtonResource *lbr =
@ -1186,33 +1188,25 @@ std::optional< std::string > DilloHtmlForm::buildQueryData(DilloHtmlInput *activ
filesInputMultipartAppend(DataStr, boundary, name.c_str(), filesInputMultipartAppend(DataStr, boundary, name.c_str(),
file, dfilename.c_str()); file, dfilename.c_str());
} }
dStr_free(file, 1);
} else if (input->type == DILLO_HTML_INPUT_INDEX) { } else if (input->type == DILLO_HTML_INPUT_INDEX) {
/* no name */ /* no name */
Dstr *val_p = (Dstr *) dList_nth_data(values, 0); auto val= std::move( values.at( 0 ) );
std::string val= val_p->str; values.erase( begin( values ) );
dList_remove(values, val_p);
dStr_free(val_p, 1);
val = encodeText(char_encoder, std::move( val )); val = encodeText(char_encoder, std::move( val ));
strUrlencodeAppend(DataStr, val.c_str()); strUrlencodeAppend(DataStr, val.c_str());
} else if (input->type == DILLO_HTML_INPUT_IMAGE) { } else if (input->type == DILLO_HTML_INPUT_IMAGE) {
Dstr *x, *y; auto x= std::move( values.at( 0 ) );
x = (Dstr *) dList_nth_data(values, 0); values.erase( begin( values ) );
dList_remove(values, x); auto y= std::move( values.at( 0 ) );
y = (Dstr *) dList_nth_data(values, 0); values.erase( begin( values ) );
dList_remove(values, y);
if (content_type == DILLO_HTML_ENC_URLENCODED) if (content_type == DILLO_HTML_ENC_URLENCODED)
imageInputUrlencodeAppend(DataStr, name, x, y); imageInputUrlencodeAppend(DataStr, name, x, y);
else if (content_type == DILLO_HTML_ENC_MULTIPART) else if (content_type == DILLO_HTML_ENC_MULTIPART)
imageInputMultipartAppend(DataStr, boundary, name, x->str, y->str); imageInputMultipartAppend(DataStr, boundary, name, x, y);
dStr_free(x, 1);
dStr_free(y, 1);
} else { } else {
for (int j = 0; j < valcount; j++) { for (int j = 0; j < valcount; j++) {
Dstr *val_p = (Dstr *) dList_nth_data(values, 0); std::string val= std::move( values.at( 0 ) );
std::string val= val_p->str; values.erase( begin( values ) );
dList_remove(values, val_p);
dStr_free(val_p, 1);
val = encodeText(char_encoder, std::move( val )); val = encodeText(char_encoder, std::move( val ));
if (content_type == DILLO_HTML_ENC_URLENCODED) if (content_type == DILLO_HTML_ENC_URLENCODED)
inputUrlencodeAppend(DataStr, name, val); inputUrlencodeAppend(DataStr, name, val);
@ -1231,7 +1225,6 @@ std::optional< std::string > DilloHtmlForm::buildQueryData(DilloHtmlInput *activ
DataStr+= "--"; DataStr+= "--";
} }
} }
dList_free(values);
} }
dFree(boundary); dFree(boundary);
if (char_encoder != (iconv_t) -1) if (char_encoder != (iconv_t) -1)
@ -1266,7 +1259,7 @@ static void generate_boundary(Dstr *boundary)
char *DilloHtmlForm::makeMultipartBoundary(iconv_t char_encoder, char *DilloHtmlForm::makeMultipartBoundary(iconv_t char_encoder,
DilloHtmlInput *active_submit) DilloHtmlInput *active_submit)
{ {
Dlist *values = dList_new(5); std::vector< std::string > values;
Dstr *DataStr = dStr_new(""); Dstr *DataStr = dStr_new("");
Dstr *boundary = dStr_new(""); Dstr *boundary = dStr_new("");
char *ret = NULL; char *ret = NULL;
@ -1292,12 +1285,10 @@ char *DilloHtmlForm::makeMultipartBoundary(iconv_t char_encoder,
dStr_append_l(DataStr, dstr.c_str(), dstr.size()); dStr_append_l(DataStr, dstr.c_str(), dstr.size());
} }
} }
int length = dList_length(values); int length = values.size();
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
Dstr *dstr_p = (Dstr *) dList_nth_data(values, 0); auto dstr= std::move( values.at( 0 ) );
std::string dstr= dstr_p->str; values.erase( begin( values ) );
dList_remove(values, dstr_p);
dStr_free(dstr_p, 1);
if (input->type != DILLO_HTML_INPUT_FILE) if (input->type != DILLO_HTML_INPUT_FILE)
dstr = encodeText(char_encoder, std::move( dstr )); dstr = encodeText(char_encoder, std::move( dstr ));
dStr_append_l(DataStr, dstr.c_str(), dstr.size()); dStr_append_l(DataStr, dstr.c_str(), dstr.size());
@ -1306,7 +1297,6 @@ char *DilloHtmlForm::makeMultipartBoundary(iconv_t char_encoder,
generate_boundary(boundary); generate_boundary(boundary);
ret = boundary->str; ret = boundary->str;
dList_free(values);
dStr_free(DataStr, 1); dStr_free(DataStr, 1);
dStr_free(boundary, (ret == NULL)); dStr_free(boundary, (ret == NULL));
return ret; return ret;
@ -1417,14 +1407,14 @@ void DilloHtmlForm::inputUrlencodeAppend(std::string &data, const std::string_vi
void DilloHtmlForm::filesInputMultipartAppend(std::string &data, void DilloHtmlForm::filesInputMultipartAppend(std::string &data,
std::string_view boundary, std::string_view boundary,
std::string_view name, std::string_view name,
Dstr *file, const std::string &file,
std::string_view filename_) std::string_view filename_)
{ {
const char *ctype, *ext; const char *ctype, *ext;
if (not name.empty()) { if (not name.empty()) {
const std::string filename{ filename_ }; const std::string filename{ filename_ };
(void)a_Misc_get_content_type_from_data(file->str, file->len, &ctype); (void)a_Misc_get_content_type_from_data(const_cast< char * >( file.data() ), file.size(), &ctype);
/* Heuristic: text/plain with ".htm[l]" extension -> text/html */ /* Heuristic: text/plain with ".htm[l]" extension -> text/html */
if ((ext = strrchr(filename.c_str(), '.')) && if ((ext = strrchr(filename.c_str(), '.')) &&
!dStrAsciiCasecmp(ctype, "text/plain") && !dStrAsciiCasecmp(ctype, "text/plain") &&
@ -1454,7 +1444,7 @@ void DilloHtmlForm::filesInputMultipartAppend(std::string &data,
+ "Content-Type: " + ctype + "\r\n" + "Content-Type: " + ctype + "\r\n"
+ "\r\n"; + "\r\n";
data+= std::string_view{ file->str, file->str + file->len }; data+= std::string_view{ file.c_str(), file.c_str() + file.size() };
data+= "\r\n--"s + std::string{ boundary }; data+= "\r\n--"s + std::string{ boundary };
} }
@ -1486,16 +1476,20 @@ void DilloHtmlForm::inputMultipartAppend(std::string &data,
/** /**
* Append an image button click position to url data using url encoding. * Append an image button click position to url data using url encoding.
*/ */
void DilloHtmlForm::imageInputUrlencodeAppend(std::string &data, const std::string_view name, Dstr *x, void DilloHtmlForm::imageInputUrlencodeAppend(std::string &data, const std::string_view name, const std::string_view x,
Dstr *y) const std::string_view y)
{ {
if (not name.empty()) { if (not name.empty()) {
strUrlencodeAppend(data, name); strUrlencodeAppend(data, name);
data+= ".x="s + x->str + "&"; data+= ".x="s;
data+= x;
data+= "&";
strUrlencodeAppend(data, name); strUrlencodeAppend(data, name);
data+= ".y="s + y->str + "&"; data+= ".y="s;
data+= y;
data+= "&";
} else } else
data+= "x="s + x->str + "&y=" + y->str + "&"; data+= "x="s + std::string{ x } + "&y=" + std::string{ y } + "&";
} }
/** /**
@ -1760,7 +1754,7 @@ void DilloHtmlInput::readFile (BrowserWindow *bw)
/** /**
* Get the values for a "successful control". * Get the values for a "successful control".
*/ */
void DilloHtmlInput::appendValuesTo(Dlist *values, bool is_active_submit) void DilloHtmlInput::appendValuesTo(std::vector< std::string > &values, bool is_active_submit)
{ {
switch (type) { switch (type) {
case DILLO_HTML_INPUT_TEXT: case DILLO_HTML_INPUT_TEXT:
@ -1769,14 +1763,14 @@ void DilloHtmlInput::appendValuesTo(Dlist *values, bool is_active_submit)
case DILLO_HTML_INPUT_HIDDEN: case DILLO_HTML_INPUT_HIDDEN:
{ {
EntryResource *entryres = (EntryResource*)embed->getResource(); EntryResource *entryres = (EntryResource*)embed->getResource();
dList_append(values, dStr_new(entryres->getText())); values.push_back(entryres->getText());
} }
break; break;
case DILLO_HTML_INPUT_TEXTAREA: case DILLO_HTML_INPUT_TEXTAREA:
{ {
MultiLineTextResource *textres = MultiLineTextResource *textres =
(MultiLineTextResource*)embed->getResource(); (MultiLineTextResource*)embed->getResource();
dList_append(values, dStr_new(textres->getText())); values.push_back(textres->getText());
} }
break; break;
case DILLO_HTML_INPUT_CHECKBOX: case DILLO_HTML_INPUT_CHECKBOX:
@ -1785,14 +1779,14 @@ void DilloHtmlInput::appendValuesTo(Dlist *values, bool is_active_submit)
ToggleButtonResource *cb_r = ToggleButtonResource *cb_r =
(ToggleButtonResource*)embed->getResource(); (ToggleButtonResource*)embed->getResource();
if (name && init_str && cb_r->isActivated()) { if (name && init_str && cb_r->isActivated()) {
dList_append(values, dStr_new(init_str.value().c_str())); values.push_back( init_str.value() );
} }
} }
break; break;
case DILLO_HTML_INPUT_SUBMIT: case DILLO_HTML_INPUT_SUBMIT:
case DILLO_HTML_INPUT_BUTTON_SUBMIT: case DILLO_HTML_INPUT_BUTTON_SUBMIT:
if (is_active_submit) if (is_active_submit)
dList_append(values, dStr_new(init_str.value_or( "" ).c_str())); values.push_back( init_str.value_or( "" ) );
break; break;
case DILLO_HTML_INPUT_SELECT: case DILLO_HTML_INPUT_SELECT:
case DILLO_HTML_INPUT_SEL_LIST: case DILLO_HTML_INPUT_SEL_LIST:
@ -1807,9 +1801,7 @@ void DilloHtmlInput::appendValuesTo(Dlist *values, bool is_active_submit)
const char *filename = lbr->getLabel(); const char *filename = lbr->getLabel();
if (filename[0] && strcmp(filename, init_str.value().c_str())) { if (filename[0] && strcmp(filename, init_str.value().c_str())) {
if (file_data) { if (file_data) {
Dstr *file = dStr_sized_new(file_data->len); values.push_back( file_data->str );
dStr_append_l(file, file_data->str, file_data->len);
dList_append(values, file);
} else { } else {
MSG("FORM file input \"%s\" not loaded.\n", filename); MSG("FORM file input \"%s\" not loaded.\n", filename);
} }
@ -1820,12 +1812,8 @@ void DilloHtmlInput::appendValuesTo(Dlist *values, bool is_active_submit)
if (is_active_submit) { if (is_active_submit) {
ComplexButtonResource *cbr = ComplexButtonResource *cbr =
(ComplexButtonResource*)embed->getResource(); (ComplexButtonResource*)embed->getResource();
Dstr *strX = dStr_new(""); values.push_back( boost::lexical_cast< std::string >( cbr->getClickX() ) );
Dstr *strY = dStr_new(""); values.push_back( boost::lexical_cast< std::string >( cbr->getClickY() ) );
dStr_sprintf(strX, "%d", cbr->getClickX());
dStr_sprintf(strY, "%d", cbr->getClickY());
dList_append(values, strX);
dList_append(values, strY);
} }
break; break;
default: default:
@ -1954,7 +1942,7 @@ void DilloHtmlSelect::reset (SelectionResource *res)
} }
} }
void DilloHtmlSelect::appendValuesTo (Dlist *values, SelectionResource *res) void DilloHtmlSelect::appendValuesTo (std::vector< std::string > &values, SelectionResource *res)
{ {
int size = opts->size (); int size = opts->size ();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@ -1963,7 +1951,7 @@ void DilloHtmlSelect::appendValuesTo (Dlist *values, SelectionResource *res)
const char *val = opt->getValue(); const char *val = opt->getValue();
if (val) if (val)
dList_append(values, dStr_new(val)); values.push_back( val );
} }
} }
} }