URL code uses more C++ string bits.
This commit is contained in:
177
src/form.cc
177
src/form.cc
@ -95,17 +95,17 @@ class DilloHtmlForm {
|
||||
std::optional< std::string > buildQueryData(DilloHtmlInput *active_submit);
|
||||
char *makeMultipartBoundary(iconv_t char_encoder,
|
||||
DilloHtmlInput *active_submit);
|
||||
Dstr *encodeText(iconv_t char_encoder, Dstr **input);
|
||||
void strUrlencodeAppend(std::string &dstr, const char *str);
|
||||
void inputUrlencodeAppend(std::string &data, const char *name, const char *value);
|
||||
void inputMultipartAppend(std::string &data, const char *boundary,
|
||||
const char *name, const char *value);
|
||||
void filesInputMultipartAppend(std::string &data, const char *boundary,
|
||||
const char *name, Dstr *file,
|
||||
const char *filename);
|
||||
void imageInputUrlencodeAppend(std::string &data, Dstr *name, Dstr *x, Dstr *y);
|
||||
void imageInputMultipartAppend(std::string &data, const char *boundary, Dstr *name,
|
||||
Dstr *x, Dstr *y);
|
||||
std::string encodeText(iconv_t char_encoder, std::string &&input);
|
||||
void strUrlencodeAppend(std::string &dstr, std::string_view str);
|
||||
void inputUrlencodeAppend(std::string &data, std::string_view name, std::string_view value);
|
||||
void inputMultipartAppend(std::string &data, std::string_view boundary,
|
||||
std::string_view name, std::string_view value);
|
||||
void filesInputMultipartAppend(std::string &data, std::string_view boundary,
|
||||
std::string_view name, Dstr *file,
|
||||
std::string_view filename);
|
||||
void imageInputUrlencodeAppend(std::string &data, std::string_view name, Dstr *x, Dstr *y);
|
||||
void imageInputMultipartAppend(std::string &data, std::string_view boundary, std::string_view name,
|
||||
std::string_view x, std::string_view y);
|
||||
|
||||
public: //BUG: for now everything is public
|
||||
DilloHtmlMethod method;
|
||||
@ -1174,11 +1174,11 @@ std::optional< std::string > DilloHtmlForm::buildQueryData(DilloHtmlInput *activ
|
||||
|
||||
for (int i = 0; i < inputs.size(); i++) {
|
||||
auto input = inputs.at (i);
|
||||
Dstr *name = dStr_new(input->name);
|
||||
std::string name= input->name ? input->name : "";
|
||||
bool is_active_submit = (input.get() == active_submit);
|
||||
int valcount;
|
||||
|
||||
name = encodeText(char_encoder, &name);
|
||||
name = encodeText(char_encoder, std::move( name ));
|
||||
|
||||
input->appendValuesTo(values, is_active_submit);
|
||||
|
||||
@ -1197,20 +1197,20 @@ std::optional< std::string > DilloHtmlForm::buildQueryData(DilloHtmlInput *activ
|
||||
const char *p = strrchr(filename, '/');
|
||||
if (p)
|
||||
filename = p + 1; /* don't reveal path */
|
||||
Dstr *dfilename = dStr_new(filename);
|
||||
dfilename = encodeText(char_encoder, &dfilename);
|
||||
filesInputMultipartAppend(DataStr, boundary, name->str,
|
||||
file, dfilename->str);
|
||||
dStr_free(dfilename, 1);
|
||||
std::string dfilename = filename;
|
||||
dfilename = encodeText(char_encoder, std::move( dfilename ));
|
||||
filesInputMultipartAppend(DataStr, boundary, name.c_str(),
|
||||
file, dfilename.c_str());
|
||||
}
|
||||
dStr_free(file, 1);
|
||||
} else if (input->type == DILLO_HTML_INPUT_INDEX) {
|
||||
/* no name */
|
||||
Dstr *val = (Dstr *) dList_nth_data(values, 0);
|
||||
dList_remove(values, val);
|
||||
val = encodeText(char_encoder, &val);
|
||||
strUrlencodeAppend(DataStr, val->str);
|
||||
dStr_free(val, 1);
|
||||
Dstr *val_p = (Dstr *) dList_nth_data(values, 0);
|
||||
std::string val= val_p->str;
|
||||
dList_remove(values, val_p);
|
||||
dStr_free(val_p, 1);
|
||||
val = encodeText(char_encoder, std::move( val ));
|
||||
strUrlencodeAppend(DataStr, val.c_str());
|
||||
} else if (input->type == DILLO_HTML_INPUT_IMAGE) {
|
||||
Dstr *x, *y;
|
||||
x = (Dstr *) dList_nth_data(values, 0);
|
||||
@ -1220,24 +1220,24 @@ std::optional< std::string > DilloHtmlForm::buildQueryData(DilloHtmlInput *activ
|
||||
if (content_type == DILLO_HTML_ENC_URLENCODED)
|
||||
imageInputUrlencodeAppend(DataStr, name, x, y);
|
||||
else if (content_type == DILLO_HTML_ENC_MULTIPART)
|
||||
imageInputMultipartAppend(DataStr, boundary, name, x, y);
|
||||
imageInputMultipartAppend(DataStr, boundary, name, x->str, y->str);
|
||||
dStr_free(x, 1);
|
||||
dStr_free(y, 1);
|
||||
} else {
|
||||
for (int j = 0; j < valcount; j++) {
|
||||
Dstr *val = (Dstr *) dList_nth_data(values, 0);
|
||||
dList_remove(values, val);
|
||||
val = encodeText(char_encoder, &val);
|
||||
Dstr *val_p = (Dstr *) dList_nth_data(values, 0);
|
||||
std::string val= val_p->str;
|
||||
dList_remove(values, val_p);
|
||||
dStr_free(val_p, 1);
|
||||
val = encodeText(char_encoder, std::move( val ));
|
||||
if (content_type == DILLO_HTML_ENC_URLENCODED)
|
||||
inputUrlencodeAppend(DataStr, name->str, val->str);
|
||||
inputUrlencodeAppend(DataStr, name, val);
|
||||
else if (content_type == DILLO_HTML_ENC_MULTIPART)
|
||||
inputMultipartAppend(DataStr, boundary, name->str,
|
||||
val->str);
|
||||
dStr_free(val, 1);
|
||||
inputMultipartAppend(DataStr, boundary, name,
|
||||
val);
|
||||
}
|
||||
}
|
||||
}
|
||||
dStr_free(name, 1);
|
||||
}
|
||||
if( not DataStr.empty() ) {
|
||||
if (content_type == DILLO_HTML_ENC_URLENCODED) {
|
||||
@ -1289,36 +1289,34 @@ char *DilloHtmlForm::makeMultipartBoundary(iconv_t char_encoder,
|
||||
|
||||
/* fill DataStr with names, filenames, and values */
|
||||
for (int i = 0; i < inputs.size(); i++) {
|
||||
Dstr *dstr;
|
||||
auto input = inputs.at (i);
|
||||
bool is_active_submit = (input.get() == active_submit);
|
||||
input->appendValuesTo(values, is_active_submit);
|
||||
|
||||
if (input->name) {
|
||||
dstr = dStr_new(input->name);
|
||||
dstr = encodeText(char_encoder, &dstr);
|
||||
dStr_append_l(DataStr, dstr->str, dstr->len);
|
||||
dStr_free(dstr, 1);
|
||||
std::string dstr= input->name;;
|
||||
dstr = encodeText(char_encoder, std::move( dstr ));
|
||||
dStr_append_l(DataStr, dstr.c_str(), dstr.size());
|
||||
}
|
||||
if (input->type == DILLO_HTML_INPUT_FILE) {
|
||||
LabelButtonResource *lbr =
|
||||
(LabelButtonResource*)input->embed->getResource();
|
||||
const char *filename = lbr->getLabel();
|
||||
if (filename[0] && strcmp(filename, input->init_str)) {
|
||||
dstr = dStr_new(filename);
|
||||
dstr = encodeText(char_encoder, &dstr);
|
||||
dStr_append_l(DataStr, dstr->str, dstr->len);
|
||||
dStr_free(dstr, 1);
|
||||
std::string dstr = filename;
|
||||
dstr = encodeText(char_encoder, std::move( dstr ));
|
||||
dStr_append_l(DataStr, dstr.c_str(), dstr.size());
|
||||
}
|
||||
}
|
||||
int length = dList_length(values);
|
||||
for (int i = 0; i < length; i++) {
|
||||
dstr = (Dstr *) dList_nth_data(values, 0);
|
||||
dList_remove(values, dstr);
|
||||
Dstr *dstr_p = (Dstr *) dList_nth_data(values, 0);
|
||||
std::string dstr= dstr_p->str;
|
||||
dList_remove(values, dstr_p);
|
||||
dStr_free(dstr_p, 1);
|
||||
if (input->type != DILLO_HTML_INPUT_FILE)
|
||||
dstr = encodeText(char_encoder, &dstr);
|
||||
dStr_append_l(DataStr, dstr->str, dstr->len);
|
||||
dStr_free(dstr, 1);
|
||||
dstr = encodeText(char_encoder, std::move( dstr ));
|
||||
dStr_append_l(DataStr, dstr.c_str(), dstr.size());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1335,7 +1333,7 @@ char *DilloHtmlForm::makeMultipartBoundary(iconv_t char_encoder,
|
||||
* Return value: same input Dstr if no encoding is needed.
|
||||
* new Dstr when encoding (input Dstr is freed).
|
||||
*/
|
||||
Dstr *DilloHtmlForm::encodeText(iconv_t char_encoder, Dstr **input)
|
||||
std::string DilloHtmlForm::encodeText(iconv_t char_encoder, std::string &&input)
|
||||
{
|
||||
int rc = 0;
|
||||
Dstr *output;
|
||||
@ -1345,12 +1343,12 @@ Dstr *DilloHtmlForm::encodeText(iconv_t char_encoder, Dstr **input)
|
||||
size_t inLeft, outRoom;
|
||||
bool bad_chars = false;
|
||||
|
||||
if ((char_encoder == (iconv_t) -1) || *input == NULL || (*input)->len == 0)
|
||||
return *input;
|
||||
if ((char_encoder == (iconv_t) -1) || input.empty())
|
||||
return input;
|
||||
|
||||
output = dStr_new("");
|
||||
inPtr = (*input)->str;
|
||||
inLeft = (*input)->len;
|
||||
inPtr = input.data();
|
||||
inLeft = input.size();
|
||||
buffer = dNew(char, bufsize);
|
||||
|
||||
while ((rc != EINVAL) && (inLeft > 0)) {
|
||||
@ -1394,19 +1392,21 @@ Dstr *DilloHtmlForm::encodeText(iconv_t char_encoder, Dstr **input)
|
||||
}
|
||||
|
||||
dFree(buffer);
|
||||
dStr_free(*input, 1);
|
||||
|
||||
return output;
|
||||
std::string rv= output->str;
|
||||
dStr_free( output, 1 );
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Urlencode 'str' and append it to 'dstr'
|
||||
*/
|
||||
void DilloHtmlForm::strUrlencodeAppend(std::string &dstr, const char *str)
|
||||
void DilloHtmlForm::strUrlencodeAppend(std::string &dstr, std::string_view str_)
|
||||
{
|
||||
const std::string str{ str_ };
|
||||
auto encoded= Alepha::AutoRAII
|
||||
{
|
||||
[&]{ return a_Url_encode_hex_str(str); },
|
||||
[&]{ return a_Url_encode_hex_str(str.c_str()); },
|
||||
dFree
|
||||
};
|
||||
dstr+= encoded;
|
||||
@ -1415,10 +1415,10 @@ void DilloHtmlForm::strUrlencodeAppend(std::string &dstr, const char *str)
|
||||
/**
|
||||
* Append a name-value pair to url data using url encoding.
|
||||
*/
|
||||
void DilloHtmlForm::inputUrlencodeAppend(std::string &data, const char *name,
|
||||
const char *value)
|
||||
void DilloHtmlForm::inputUrlencodeAppend(std::string &data, const std::string_view name,
|
||||
const std::string_view value)
|
||||
{
|
||||
if (name && name[0]) {
|
||||
if (not name.empty()) {
|
||||
strUrlencodeAppend(data, name);
|
||||
data+= '=';
|
||||
strUrlencodeAppend(data, value);
|
||||
@ -1431,17 +1431,18 @@ void DilloHtmlForm::inputUrlencodeAppend(std::string &data, const char *name,
|
||||
* Currently only accepts one file.
|
||||
*/
|
||||
void DilloHtmlForm::filesInputMultipartAppend(std::string &data,
|
||||
const char *boundary,
|
||||
const char *name,
|
||||
std::string_view boundary,
|
||||
std::string_view name,
|
||||
Dstr *file,
|
||||
const char *filename)
|
||||
std::string_view filename_)
|
||||
{
|
||||
const char *ctype, *ext;
|
||||
|
||||
if (name && name[0]) {
|
||||
if (not name.empty()) {
|
||||
const std::string filename{ filename_ };
|
||||
(void)a_Misc_get_content_type_from_data(file->str, file->len, &ctype);
|
||||
/* Heuristic: text/plain with ".htm[l]" extension -> text/html */
|
||||
if ((ext = strrchr(filename, '.')) &&
|
||||
if ((ext = strrchr(filename.c_str(), '.')) &&
|
||||
!dStrAsciiCasecmp(ctype, "text/plain") &&
|
||||
(!dStrAsciiCasecmp(ext, ".html") || !dStrAsciiCasecmp(ext, ".htm"))){
|
||||
ctype = "text/html";
|
||||
@ -1452,7 +1453,7 @@ void DilloHtmlForm::filesInputMultipartAppend(std::string &data,
|
||||
data+= boundary;
|
||||
}
|
||||
data+= "\r\n"s
|
||||
+ "Content-Disposition: form-data; name=\"" + name +"\"; "
|
||||
+ "Content-Disposition: form-data; name=\"" + std::string{ name } +"\"; "
|
||||
+ "filename=\"";
|
||||
/*
|
||||
* Replace the characters that are the most likely to damage things.
|
||||
@ -1460,7 +1461,7 @@ void DilloHtmlForm::filesInputMultipartAppend(std::string &data,
|
||||
* but HTML5/Ian Hickson/his Google masters are, as of late 2012,
|
||||
* evidently standing in opposition to all of that for some reason.
|
||||
*/
|
||||
for (int i = 0; char c = filename[i]; i++) {
|
||||
for (int i = 0; char c = filename.at(i); i++) {
|
||||
if (c == '\"' || c == '\r' || c == '\n')
|
||||
c = '_';
|
||||
data+= c;
|
||||
@ -1471,7 +1472,7 @@ void DilloHtmlForm::filesInputMultipartAppend(std::string &data,
|
||||
|
||||
data+= std::string_view{ file->str, file->str + file->len };
|
||||
|
||||
data+= "\r\n--"s + boundary;
|
||||
data+= "\r\n--"s + std::string{ boundary };
|
||||
}
|
||||
}
|
||||
|
||||
@ -1479,35 +1480,35 @@ void DilloHtmlForm::filesInputMultipartAppend(std::string &data,
|
||||
* Append a name-value pair to url data using multipart encoding.
|
||||
*/
|
||||
void DilloHtmlForm::inputMultipartAppend(std::string &data,
|
||||
const char *boundary,
|
||||
const char *name,
|
||||
const char *value)
|
||||
std::string_view boundary,
|
||||
std::string_view name,
|
||||
std::string_view value)
|
||||
{
|
||||
if (name && name[0]) {
|
||||
if (not name.empty()) {
|
||||
if (data.empty()) {
|
||||
data+= "--";
|
||||
data+= boundary;
|
||||
}
|
||||
data+=
|
||||
"\r\n"s
|
||||
+ "Content-Disposition: form-data; name=\"" + name + "\"\r\n"
|
||||
+ "Content-Disposition: form-data; name=\"" + std::string{ name } + "\"\r\n"
|
||||
+ "\r\n"
|
||||
+ value + "\r\n"
|
||||
+ std::string{ value } + "\r\n"
|
||||
+ "--"
|
||||
+ boundary;
|
||||
+ std::string{ boundary };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append an image button click position to url data using url encoding.
|
||||
*/
|
||||
void DilloHtmlForm::imageInputUrlencodeAppend(std::string &data, Dstr *name, Dstr *x,
|
||||
void DilloHtmlForm::imageInputUrlencodeAppend(std::string &data, const std::string_view name, Dstr *x,
|
||||
Dstr *y)
|
||||
{
|
||||
if (name->len) {
|
||||
strUrlencodeAppend(data, name->str);
|
||||
if (not name.empty()) {
|
||||
strUrlencodeAppend(data, name);
|
||||
data+= ".x="s + x->str + "&";
|
||||
strUrlencodeAppend(data, name->str);
|
||||
strUrlencodeAppend(data, name);
|
||||
data+= ".y="s + y->str + "&";
|
||||
} else
|
||||
data+= "x="s + x->str + "&y=" + y->str + "&";
|
||||
@ -1516,20 +1517,22 @@ void DilloHtmlForm::imageInputUrlencodeAppend(std::string &data, Dstr *name, Dst
|
||||
/**
|
||||
* Append an image button click position to url data using multipart encoding.
|
||||
*/
|
||||
void DilloHtmlForm::imageInputMultipartAppend(std::string &data, const char *boundary,
|
||||
Dstr *name, Dstr *x, Dstr *y)
|
||||
void DilloHtmlForm::imageInputMultipartAppend(std::string &data, const std::string_view boundary,
|
||||
const std::string_view name_, const std::string_view x_, const std::string_view y_)
|
||||
{
|
||||
int orig_len = name->len;
|
||||
std::string name{ name_ };
|
||||
const std::string x{ x_ };
|
||||
const std::string y{ y_ };
|
||||
int orig_len = name.size();
|
||||
|
||||
if (orig_len)
|
||||
dStr_append_c(name, '.');
|
||||
dStr_append_c(name, 'x');
|
||||
name+= '.';
|
||||
name+= 'x';
|
||||
|
||||
inputMultipartAppend(data, boundary, name->str, x->str);
|
||||
dStr_truncate(name, name->len - 1);
|
||||
dStr_append_c(name, 'y');
|
||||
inputMultipartAppend(data, boundary, name->str, y->str);
|
||||
dStr_truncate(name, orig_len);
|
||||
inputMultipartAppend(data, boundary, name.c_str(), x.c_str());
|
||||
name.pop_back();
|
||||
name+= 'y';
|
||||
inputMultipartAppend(data, boundary, name.c_str(), y.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user