Another set of local ownership down.

This commit is contained in:
2025-04-24 00:12:13 -04:00
parent 6af638059b
commit 265ac2aa9a
3 changed files with 73 additions and 96 deletions

View File

@ -447,7 +447,6 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
DilloHtmlInputType inp_type;
Resource *resource = NULL;
Embed *embed = NULL;
char *value, *name, *type, *init_str, *placeholder = NULL;
const char *attrbuf, *label;
bool init_val = false;
ResourceFactory *factory;
@ -464,61 +463,62 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
factory = HT2LT(html)->getResourceFactory();
/* Get 'value', 'name' and 'type' */
value = a_Html_get_attr_wdef(html, tag, tagsize, "value", NULL);
name = a_Html_get_attr_wdef(html, tag, tagsize, "name", NULL);
type = a_Html_get_attr_wdef(html, tag, tagsize, "type", "");
auto value = a_Html_get_attr_wdef(html, tag, tagsize, "value", NULL);
auto name = a_Html_get_attr_wdef(html, tag, tagsize, "name", NULL);
auto type = a_Html_get_attr_wdef(html, tag, tagsize, "type", "");
std::optional< std::string > init_str;
std::optional< std::string > placeholder;
init_str = NULL;
inp_type = DILLO_HTML_INPUT_UNKNOWN;
if (!dStrAsciiCasecmp(type, "password")) {
if (!dStrAsciiCasecmp(type.value().c_str(), "password")) {
inp_type = DILLO_HTML_INPUT_PASSWORD;
placeholder = a_Html_get_attr_wdef(html, tag,tagsize,"placeholder",NULL);
attrbuf = a_Html_get_attr(html, tag, tagsize, "size");
int size = Html_input_get_size(html, attrbuf);
resource = factory->createEntryResource (size, true, NULL, placeholder);
resource = factory->createEntryResource (size, true, NULL, placeholder.value().c_str());
init_str = value;
} else if (!dStrAsciiCasecmp(type, "checkbox")) {
} else if (!dStrAsciiCasecmp(type.value().c_str(), "checkbox")) {
inp_type = DILLO_HTML_INPUT_CHECKBOX;
resource = factory->createCheckButtonResource(false);
init_val = (a_Html_get_attr(html, tag, tagsize, "checked") != NULL);
init_str = (value) ? value : dStrdup("on");
} else if (!dStrAsciiCasecmp(type, "radio")) {
init_str = value.value_or( "on" );
} else if (!dStrAsciiCasecmp(type.value().c_str(), "radio")) {
inp_type = DILLO_HTML_INPUT_RADIO;
RadioButtonResource *rb_r = NULL;
std::shared_ptr input = Html_get_radio_input(html, name);
std::shared_ptr input = Html_get_radio_input(html, name ? name.value().c_str() : nullptr);
if (input)
rb_r = (RadioButtonResource*) input->embed->getResource();
resource = factory->createRadioButtonResource(rb_r, false);
init_val = (a_Html_get_attr(html, tag, tagsize, "checked") != NULL);
init_str = value;
} else if (!dStrAsciiCasecmp(type, "hidden")) {
} else if (!dStrAsciiCasecmp(type.value().c_str(), "hidden")) {
inp_type = DILLO_HTML_INPUT_HIDDEN;
init_str = value;
int size = Html_input_get_size(html, NULL);
resource = factory->createEntryResource(size, false, name, NULL);
} else if (!dStrAsciiCasecmp(type, "submit")) {
resource = factory->createEntryResource(size, false, name ? name.value().c_str() : nullptr, NULL);
} else if (!dStrAsciiCasecmp(type.value().c_str(), "submit")) {
inp_type = DILLO_HTML_INPUT_SUBMIT;
init_str = (value) ? value : dStrdup("submit");
resource = factory->createLabelButtonResource(init_str);
} else if (!dStrAsciiCasecmp(type, "reset")) {
init_str = value.value_or("submit");
resource = factory->createLabelButtonResource(init_str.value().c_str());
} else if (!dStrAsciiCasecmp(type.value().c_str(), "reset")) {
inp_type = DILLO_HTML_INPUT_RESET;
init_str = (value) ? value : dStrdup("Reset");
resource = factory->createLabelButtonResource(init_str);
} else if (!dStrAsciiCasecmp(type, "image")) {
init_str = value.value_or( "Reset" );
resource = factory->createLabelButtonResource(init_str.value().c_str());
} else if (!dStrAsciiCasecmp(type.value().c_str(), "image")) {
if (URL_FLAGS(html->base_url) & URL_SpamSafe) {
/* Don't request the image; make a text submit button instead */
inp_type = DILLO_HTML_INPUT_SUBMIT;
attrbuf = a_Html_get_attr(html, tag, tagsize, "alt");
label = attrbuf ? attrbuf : value ? value : name ? name : "Submit";
init_str = dStrdup(label);
resource = factory->createLabelButtonResource(init_str);
label = attrbuf ? attrbuf : value.value_or( name.value_or( "Submit" ) ).c_str();
init_str = label;
resource = factory->createLabelButtonResource(init_str.value().c_str());
} else {
inp_type = DILLO_HTML_INPUT_IMAGE;
/* use a dw_image widget */
embed = Html_input_image(html, tag, tagsize);
init_str = value;
}
} else if (!dStrAsciiCasecmp(type, "file")) {
} else if (!dStrAsciiCasecmp(type.value().c_str(), "file")) {
bool valid = true;
if (html->InFlags & IN_FORM) {
DilloHtmlForm *form = html->getCurrentForm();
@ -536,14 +536,14 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
}
if (valid) {
inp_type = DILLO_HTML_INPUT_FILE;
init_str = dStrdup("File selector");
resource = factory->createLabelButtonResource(init_str);
init_str = "File selector";
resource = factory->createLabelButtonResource(init_str.value().c_str());
}
} else if (!dStrAsciiCasecmp(type, "button")) {
} else if (!dStrAsciiCasecmp(type.value().c_str(), "button")) {
inp_type = DILLO_HTML_INPUT_BUTTON;
if (value) {
init_str = value;
resource = factory->createLabelButtonResource(init_str);
resource = factory->createLabelButtonResource(init_str.value().c_str());
}
} else {
/* Text input, which also is the default */
@ -551,15 +551,15 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
placeholder = a_Html_get_attr_wdef(html, tag,tagsize,"placeholder",NULL);
attrbuf = a_Html_get_attr(html, tag, tagsize, "size");
int size = Html_input_get_size(html, attrbuf);
resource = factory->createEntryResource(size, false, NULL, placeholder);
resource = factory->createEntryResource(size, false, NULL, placeholder.value().c_str());
init_str = value;
}
if (resource)
embed = new Embed (resource);
if (inp_type != DILLO_HTML_INPUT_UNKNOWN) {
Html_add_input(html, inp_type, embed, name,
(init_str) ? init_str : "", init_val);
Html_add_input(html, inp_type, embed, name ? name.value().c_str() : nullptr,
init_str.value_or( "" ).c_str(), init_val);
}
if (embed != NULL && inp_type != DILLO_HTML_INPUT_IMAGE &&
@ -587,12 +587,6 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
}
HT2TB(html)->addWidget (embed, html->backgroundStyle());
}
dFree(type);
dFree(name);
if (init_str != value)
dFree(init_str);
dFree(placeholder);
dFree(value);
}
/**
@ -754,7 +748,7 @@ void Html_tag_open_select(DilloHtml *html, const char *tag, int tagsize)
html->InFlags |= IN_SELECT;
html->InFlags &= ~IN_OPTION;
char *name = a_Html_get_attr_wdef(html, tag, tagsize, "name", NULL);
auto name = a_Html_get_attr_wdef(html, tag, tagsize, "name", NULL);
ResourceFactory *factory = HT2LT(html)->getResourceFactory ();
DilloHtmlInputType type;
SelectionResource *res;
@ -789,9 +783,8 @@ void Html_tag_open_select(DilloHtml *html, const char *tag, int tagsize)
}
HT2TB(html)->addWidget (embed, html->backgroundStyle ());
Html_add_input(html, type, embed, name, NULL, false);
Html_add_input(html, type, embed, name.value().c_str(), NULL, false);
a_Html_stash_init(html);
dFree(name);
}
/*
@ -838,16 +831,16 @@ void Html_tag_open_optgroup(DilloHtml *html, const char *tag, int tagsize)
if (input &&
(input->type == DILLO_HTML_INPUT_SELECT ||
input->type == DILLO_HTML_INPUT_SEL_LIST)) {
char *label = a_Html_get_attr_wdef(html, tag, tagsize, "label", NULL);
auto label = a_Html_get_attr_wdef(html, tag, tagsize, "label", NULL);
bool enabled = (a_Html_get_attr(html, tag, tagsize, "disabled") == NULL);
if (!label) {
BUG_MSG("<optgroup> requires label attribute.");
label = dStrdup("");
label = "";
}
DilloHtmlOptgroup *opt =
new DilloHtmlOptgroup (label, enabled);
new DilloHtmlOptgroup (dStrdup(label.value().c_str()), enabled);
input->select->addOpt(opt);
}
@ -891,13 +884,13 @@ void Html_tag_open_option(DilloHtml *html, const char *tag, int tagsize)
if (input &&
(input->type == DILLO_HTML_INPUT_SELECT ||
input->type == DILLO_HTML_INPUT_SEL_LIST)) {
char *value = a_Html_get_attr_wdef(html, tag, tagsize, "value", NULL);
char *label = a_Html_get_attr_wdef(html, tag, tagsize, "label", NULL);
auto value = a_Html_get_attr_wdef(html, tag, tagsize, "value", NULL);
auto label = a_Html_get_attr_wdef(html, tag, tagsize, "label", NULL);
bool selected = (a_Html_get_attr(html, tag, tagsize,"selected") != NULL);
bool enabled = (a_Html_get_attr(html, tag, tagsize, "disabled") == NULL);
DilloHtmlOption *option =
new DilloHtmlOption (value, label, selected, enabled);
new DilloHtmlOption (dStrdup( value.value().c_str() ), dStrdup( label.value().c_str() ), selected, enabled);
input->select->addOpt(option);
}
@ -923,30 +916,28 @@ void Html_tag_open_button(DilloHtml *html, const char *tag, int tagsize)
* bit simpler. May be changed in the future.
*/
DilloHtmlInputType inp_type;
char *type;
assert((html->InFlags & (IN_BUTTON | IN_SELECT | IN_TEXTAREA)) == 0);
html->InFlags |= IN_BUTTON;
type = a_Html_get_attr_wdef(html, tag, tagsize, "type", "");
auto type = a_Html_get_attr_wdef(html, tag, tagsize, "type", "");
if (!dStrAsciiCasecmp(type, "button")) {
if (!dStrAsciiCasecmp(type.value().c_str(), "button")) {
inp_type = DILLO_HTML_INPUT_BUTTON;
} else if (!dStrAsciiCasecmp(type, "reset")) {
} else if (!dStrAsciiCasecmp(type.value().c_str(), "reset")) {
inp_type = DILLO_HTML_INPUT_BUTTON_RESET;
} else if (!dStrAsciiCasecmp(type, "submit") || !*type) {
} else if (!dStrAsciiCasecmp(type.value().c_str(), "submit") || type.value().empty()) {
/* submit button is the default */
inp_type = DILLO_HTML_INPUT_BUTTON_SUBMIT;
} else {
inp_type = DILLO_HTML_INPUT_UNKNOWN;
BUG_MSG("<button> type unknown: '%s'.", type);
BUG_MSG("<button> type unknown: '%s'.", type.value().c_str());
}
if (inp_type != DILLO_HTML_INPUT_UNKNOWN) {
/* Render the button */
Embed *embed;
const char *attrbuf;
char *name, *value;
if (prefs.show_tooltip &&
(attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
@ -970,14 +961,11 @@ void Html_tag_open_button(DilloHtml *html, const char *tag, int tagsize)
S_TOP(html)->textblock = html->dw = page_p;
value = a_Html_get_attr_wdef(html, tag, tagsize, "value", NULL);
name = a_Html_get_attr_wdef(html, tag, tagsize, "name", NULL);
auto value = a_Html_get_attr_wdef(html, tag, tagsize, "value", NULL);
auto name = a_Html_get_attr_wdef(html, tag, tagsize, "name", NULL);
Html_add_input(html, inp_type, embed, name, value, FALSE);
dFree(name);
dFree(value);
Html_add_input(html, inp_type, embed, name.value().c_str(), value.value().c_str(), FALSE);
}
dFree(type);
}
/**

View File

@ -1045,7 +1045,6 @@ static const char *Html_parse_entity(DilloHtml *html, const char *token,
int toksize, int *entsize, bool_t is_attr)
{
const char *ret = NULL;
char *tok;
if (toksize > 50) {
/* In pathological cases, attributes can be megabytes long and filled
@ -1056,18 +1055,18 @@ static const char *Html_parse_entity(DilloHtml *html, const char *token,
}
token++;
tok = dStrndup(token, (uint_t)toksize);
std::string tok= token;
while( tok.size() > toksize ) tok.pop_back();
if (*tok == '#') {
ret = Html_parse_numeric_charref(html, tok+1, is_attr, entsize);
} else if (isalpha(*tok)) {
ret = Html_parse_named_charref(html, tok, is_attr, entsize);
if (tok.front() == '#') {
ret = Html_parse_numeric_charref(html, tok.data()+1, is_attr, entsize);
} else if (isalpha(tok.front())) {
ret = Html_parse_named_charref(html, tok.data(), is_attr, entsize);
} else if (prefs.show_extra_warnings &&
(!(html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f))) {
// HTML5 doesn't mind literal '&'s.
BUG_MSG("Literal '&'.");
}
dFree(tok);
return ret;
}
@ -2068,7 +2067,6 @@ static void Html_tag_open_abbr(DilloHtml *html, const char *tag, int tagsize)
*/
void a_Html_common_image_attrs(DilloHtml *html, const char *tag, int tagsize)
{
char *width_ptr, *height_ptr;
const char *attrbuf;
CssLength l_w = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO);
CssLength l_h = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO);
@ -2079,17 +2077,17 @@ void a_Html_common_image_attrs(DilloHtml *html, const char *tag, int tagsize)
html->styleEngine->setNonCssHint(PROPERTY_X_TOOLTIP, CSS_TYPE_STRING,
attrbuf);
}
width_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "width", NULL);
height_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "height", NULL);
auto width_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "width", NULL);
auto height_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "height", NULL);
// Check for malicious values
// TODO: the same for percentage and relative lengths.
if (width_ptr) {
l_w = a_Html_parse_length (html, width_ptr);
if (width_ptr.has_value()) {
l_w = a_Html_parse_length (html, width_ptr.value().c_str());
w = (int) (CSS_LENGTH_TYPE(l_w) == CSS_LENGTH_TYPE_PX ?
CSS_LENGTH_VALUE(l_w) : 0);
}
if (height_ptr) {
l_h = a_Html_parse_length (html, height_ptr);
if (height_ptr.has_value()) {
l_h = a_Html_parse_length (html, height_ptr.value().c_str());
h = (int) (CSS_LENGTH_TYPE(l_h) == CSS_LENGTH_TYPE_PX ?
CSS_LENGTH_VALUE(l_h) : 0);
}
@ -2105,9 +2103,7 @@ void a_Html_common_image_attrs(DilloHtml *html, const char *tag, int tagsize)
if (w < 0 || h < 0 ||
w > IMAGE_MAX_AREA || h > IMAGE_MAX_AREA ||
(h > 0 && w > IMAGE_MAX_AREA / h)) {
dFree(width_ptr);
dFree(height_ptr);
width_ptr = height_ptr = NULL;
width_ptr = height_ptr = std::nullopt;
MSG("a_Html_common_image_attrs: suspicious image size request %d x %d\n",
w, h);
} else {
@ -2130,16 +2126,11 @@ void a_Html_common_image_attrs(DilloHtml *html, const char *tag, int tagsize)
* We know a_Html_image_new() will use size() as its next index */
html->styleEngine->setNonCssHint (PROPERTY_X_IMG, CSS_TYPE_INTEGER,
html->images->size());
dFree(width_ptr);
dFree(height_ptr);
}
DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize)
{
bool load_now;
char *alt_ptr;
const char *attrbuf;
DilloUrl *url;
DilloImage *image;
@ -2148,13 +2139,12 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize)
!(url = a_Html_url_new(html, attrbuf, NULL, 0).release()))
return NULL;
alt_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "alt", NULL);
if (!alt_ptr || !*alt_ptr) {
dFree(alt_ptr);
alt_ptr = dStrdup("[IMG]");
auto alt_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "alt", NULL);
if (!alt_ptr.has_value() || alt_ptr.value().empty()) {
alt_ptr = "[IMG]";
}
dw::Image *dw = new dw::Image(alt_ptr);
dw::Image *dw = new dw::Image(alt_ptr.value().c_str());
image =
a_Image_new(html->dw->getLayout(), (void*)(dw::core::ImgRenderer*)dw, 0, 0);
@ -2184,7 +2174,6 @@ DilloImage *a_Html_image_new(DilloHtml *html, const char *tag, int tagsize)
hi->image = image;
}
dFree(alt_ptr);
return image;
}
@ -2953,18 +2942,16 @@ static void Html_tag_close_li(DilloHtml *html)
*/
static void Html_tag_open_hr(DilloHtml *html, const char *tag, int tagsize)
{
char *width_ptr;
const char *attrbuf;
int32_t size = 0;
width_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "width", NULL);
if (width_ptr) {
auto width_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "width", NULL);
if (width_ptr.has_value()) {
if (html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f)
BUG_MSG("<hr> width attribute is obsolete.");
html->styleEngine->setNonCssHint (CSS_PROPERTY_WIDTH,
CSS_TYPE_LENGTH_PERCENTAGE,
a_Html_parse_length (html, width_ptr));
dFree(width_ptr);
a_Html_parse_length (html, width_ptr.value().c_str()));
}
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "size"))) {
@ -4277,15 +4264,16 @@ const char *a_Html_get_attr(DilloHtml *html,
* Call a_Html_get_attr() and dStrdup() the returned string.
* If the attribute isn't found a copy of 'def' is returned.
*/
char *a_Html_get_attr_wdef(DilloHtml *html,
std::optional< std::string > a_Html_get_attr_wdef(DilloHtml *html,
const char *tag,
int tagsize,
const char *attrname,
const char *def)
{
const char *attrbuf = a_Html_get_attr(html, tag, tagsize, attrname);
return attrbuf ? dStrdup(attrbuf) : dStrdup(def);
if( attrbuf ) return attrbuf;
if( def ) return def;
return std::nullopt;
}
/**

View File

@ -16,6 +16,7 @@
#include <vector>
#include <memory>
#include <optional>
#include "url.hh"
#include "bw.hh"
@ -271,7 +272,7 @@ const char *a_Html_get_attr(DilloHtml *html,
int tagsize,
const char *attrname);
char *a_Html_get_attr_wdef(DilloHtml *html,
std::optional< std::string > a_Html_get_attr_wdef(DilloHtml *html,
const char *tag,
int tagsize,
const char *attrname,