mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
[ecmascript] Rewritten document.write
spidermonkey segfaults on test/ecmascript/document_write.html quickjs and mujs do not.
This commit is contained in:
parent
7d8e92703b
commit
865f3fa0d0
@ -302,6 +302,7 @@ ecmascript_get_interpreter(struct view_state *vs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
(void)init_string(&interpreter->code);
|
(void)init_string(&interpreter->code);
|
||||||
|
(void)init_string(&interpreter->writecode);
|
||||||
return interpreter;
|
return interpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,6 +323,7 @@ ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter)
|
|||||||
#endif
|
#endif
|
||||||
free_ecmascript_string_list(&interpreter->onload_snippets);
|
free_ecmascript_string_list(&interpreter->onload_snippets);
|
||||||
done_string(&interpreter->code);
|
done_string(&interpreter->code);
|
||||||
|
done_string(&interpreter->writecode);
|
||||||
/* Is it superfluous? */
|
/* Is it superfluous? */
|
||||||
if (interpreter->vs->doc_view) {
|
if (interpreter->vs->doc_view) {
|
||||||
struct ecmascript_timeout *t;
|
struct ecmascript_timeout *t;
|
||||||
@ -369,6 +371,44 @@ check_for_rerender(struct ecmascript_interpreter *interpreter, const char* text)
|
|||||||
struct session *ses = doc_view->session;
|
struct session *ses = doc_view->session;
|
||||||
struct cache_entry *cached = document->cached;
|
struct cache_entry *cached = document->cached;
|
||||||
|
|
||||||
|
if (!strcmp(text, "eval")) {
|
||||||
|
if (interpreter->element_offset) {
|
||||||
|
if (interpreter->writecode.length) {
|
||||||
|
std::map<int, xmlpp::Element *> *mapa = (std::map<int, xmlpp::Element *> *)document->element_map;
|
||||||
|
|
||||||
|
if (mapa) {
|
||||||
|
auto element = (*mapa).find(interpreter->element_offset);
|
||||||
|
|
||||||
|
if (element != (*mapa).end()) {
|
||||||
|
xmlpp::Element *el = element->second;
|
||||||
|
xmlpp::ustring text = "<root>";
|
||||||
|
text += interpreter->writecode.source;
|
||||||
|
text += "</root>";
|
||||||
|
|
||||||
|
xmlDoc* doc = htmlReadDoc((xmlChar*)text.c_str(), NULL, NULL, HTML_PARSE_RECOVER | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING);
|
||||||
|
// Encapsulate raw libxml document in a libxml++ wrapper
|
||||||
|
xmlpp::Document doc1(doc);
|
||||||
|
|
||||||
|
auto root = doc1.get_root_node();
|
||||||
|
auto root1 = root->find("//root")[0];
|
||||||
|
auto children2 = root1->get_children();
|
||||||
|
auto it2 = children2.begin();
|
||||||
|
auto end2 = children2.end();
|
||||||
|
for (; it2 != end2; ++it2) {
|
||||||
|
xmlAddPrevSibling(el->cobj(), (*it2)->cobj());
|
||||||
|
}
|
||||||
|
xmlpp::Node::remove_node(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (interpreter->writecode.length) {
|
||||||
|
add_fragment(cached, 0, interpreter->writecode.source, interpreter->writecode.length);
|
||||||
|
document->ecmascript_counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//fprintf(stderr, "%s\n", text);
|
//fprintf(stderr, "%s\n", text);
|
||||||
|
|
||||||
if (document->dom) {
|
if (document->dom) {
|
||||||
|
@ -66,6 +66,9 @@ struct ecmascript_interpreter {
|
|||||||
/* The code evaluated by setTimeout() */
|
/* The code evaluated by setTimeout() */
|
||||||
struct string code;
|
struct string code;
|
||||||
|
|
||||||
|
/* document.write buffer */
|
||||||
|
struct string writecode;
|
||||||
|
|
||||||
struct heartbeat *heartbeat;
|
struct heartbeat *heartbeat;
|
||||||
|
|
||||||
/* This is a cross-rerenderings accumulator of
|
/* This is a cross-rerenderings accumulator of
|
||||||
|
@ -858,12 +858,6 @@ mjs_document_write_do(js_State *J, int newline)
|
|||||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||||
#endif
|
#endif
|
||||||
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
|
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)js_getcontext(J);
|
||||||
struct string code;
|
|
||||||
|
|
||||||
if (!init_string(&code)) {
|
|
||||||
js_pushnull(J);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int argc = 1;
|
int argc = 1;
|
||||||
|
|
||||||
if (argc >= 1)
|
if (argc >= 1)
|
||||||
@ -873,47 +867,20 @@ mjs_document_write_do(js_State *J, int newline)
|
|||||||
const char *str = js_tostring(J, i+1);
|
const char *str = js_tostring(J, i+1);
|
||||||
|
|
||||||
if (str) {
|
if (str) {
|
||||||
add_to_string(&code, str);
|
add_to_string(&interpreter->writecode, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newline)
|
if (newline)
|
||||||
{
|
{
|
||||||
add_to_string(&code, "\n");
|
add_to_string(&interpreter->writecode, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//DBG("%s",code.source);
|
interpreter->changed = true;
|
||||||
|
|
||||||
/* XXX: I don't know about you, but I have *ENOUGH* of those 'Undefined
|
|
||||||
* function' errors, I want to see just the useful ones. So just
|
|
||||||
* lighting a led and going away, no muss, no fuss. --pasky */
|
|
||||||
/* TODO: Perhaps we can introduce ecmascript.error_report_unsupported
|
|
||||||
* -> "Show information about the document using some valid,
|
|
||||||
* nevertheless unsupported methods/properties." --pasky too */
|
|
||||||
|
|
||||||
struct document_view *doc_view = interpreter->vs->doc_view;
|
|
||||||
struct document *document;
|
|
||||||
document = doc_view->document;
|
|
||||||
struct cache_entry *cached = doc_view->document->cached;
|
|
||||||
cached = doc_view->document->cached;
|
|
||||||
struct fragment *f = get_cache_fragment(cached);
|
|
||||||
|
|
||||||
if (f && f->length)
|
|
||||||
{
|
|
||||||
if (false && document->ecmascript_counter==0)
|
|
||||||
{
|
|
||||||
add_fragment(cached,0,code.source,code.length);
|
|
||||||
} else {
|
|
||||||
add_fragment(cached,f->length,code.source,code.length);
|
|
||||||
}
|
|
||||||
document->ecmascript_counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_LEDS
|
#ifdef CONFIG_LEDS
|
||||||
set_led_value(interpreter->vs->doc_view->session->status.ecmascript_led, 'J');
|
set_led_value(interpreter->vs->doc_view->session->status.ecmascript_led, 'J');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
done_string(&code);
|
|
||||||
js_pushundefined(J);
|
js_pushundefined(J);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,11 +903,6 @@ js_document_write_do(JSContext *ctx, JSValueConst this_val, int argc, JSValueCon
|
|||||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||||
#endif
|
#endif
|
||||||
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)JS_GetContextOpaque(ctx);
|
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)JS_GetContextOpaque(ctx);
|
||||||
struct string code;
|
|
||||||
|
|
||||||
if (!init_string(&code)) {
|
|
||||||
return JS_EXCEPTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc >= 1)
|
if (argc >= 1)
|
||||||
{
|
{
|
||||||
@ -921,48 +916,20 @@ js_document_write_do(JSContext *ctx, JSValueConst this_val, int argc, JSValueCon
|
|||||||
if (!str) {
|
if (!str) {
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
add_bytes_to_string(&code, str, len);
|
add_bytes_to_string(&interpreter->writecode, str, len);
|
||||||
JS_FreeCString(ctx, str);
|
JS_FreeCString(ctx, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newline)
|
if (newline)
|
||||||
{
|
{
|
||||||
add_to_string(&code, "\n");
|
add_to_string(&interpreter->writecode, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//DBG("%s",code.source);
|
interpreter->changed = true;
|
||||||
|
|
||||||
/* XXX: I don't know about you, but I have *ENOUGH* of those 'Undefined
|
|
||||||
* function' errors, I want to see just the useful ones. So just
|
|
||||||
* lighting a led and going away, no muss, no fuss. --pasky */
|
|
||||||
/* TODO: Perhaps we can introduce ecmascript.error_report_unsupported
|
|
||||||
* -> "Show information about the document using some valid,
|
|
||||||
* nevertheless unsupported methods/properties." --pasky too */
|
|
||||||
|
|
||||||
struct document_view *doc_view = interpreter->vs->doc_view;
|
|
||||||
struct document *document;
|
|
||||||
document = doc_view->document;
|
|
||||||
struct cache_entry *cached = doc_view->document->cached;
|
|
||||||
cached = doc_view->document->cached;
|
|
||||||
struct fragment *f = get_cache_fragment(cached);
|
|
||||||
|
|
||||||
if (f && f->length)
|
|
||||||
{
|
|
||||||
if (false && document->ecmascript_counter==0)
|
|
||||||
{
|
|
||||||
add_fragment(cached,0,code.source,code.length);
|
|
||||||
} else {
|
|
||||||
add_fragment(cached,f->length,code.source,code.length);
|
|
||||||
}
|
|
||||||
document->ecmascript_counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_LEDS
|
#ifdef CONFIG_LEDS
|
||||||
set_led_value(interpreter->vs->doc_view->session->status.ecmascript_led, 'J');
|
set_led_value(interpreter->vs->doc_view->session->status.ecmascript_led, 'J');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
done_string(&code);
|
|
||||||
|
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1305,56 +1305,24 @@ document_write_do(JSContext *ctx, unsigned int argc, JS::Value *rval, int newlin
|
|||||||
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)JS::GetRealmPrivate(comp);
|
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)JS::GetRealmPrivate(comp);
|
||||||
JS::CallArgs args = JS::CallArgsFromVp(argc, rval);
|
JS::CallArgs args = JS::CallArgsFromVp(argc, rval);
|
||||||
|
|
||||||
struct string code;
|
|
||||||
|
|
||||||
if (!init_string(&code)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc >= 1)
|
if (argc >= 1)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < argc; ++i)
|
for (unsigned int i = 0; i < argc; ++i)
|
||||||
{
|
{
|
||||||
jshandle_value_to_char_string(&code, ctx, args[i]);
|
jshandle_value_to_char_string(&interpreter->writecode, ctx, args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newline)
|
if (newline)
|
||||||
{
|
{
|
||||||
add_to_string(&code, "\n");
|
add_to_string(&interpreter->writecode, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//DBG("%s",code.source);
|
interpreter->changed = true;
|
||||||
|
|
||||||
/* XXX: I don't know about you, but I have *ENOUGH* of those 'Undefined
|
|
||||||
* function' errors, I want to see just the useful ones. So just
|
|
||||||
* lighting a led and going away, no muss, no fuss. --pasky */
|
|
||||||
/* TODO: Perhaps we can introduce ecmascript.error_report_unsupported
|
|
||||||
* -> "Show information about the document using some valid,
|
|
||||||
* nevertheless unsupported methods/properties." --pasky too */
|
|
||||||
|
|
||||||
struct document_view *doc_view = interpreter->vs->doc_view;
|
|
||||||
struct document *document;
|
|
||||||
document = doc_view->document;
|
|
||||||
struct cache_entry *cached = doc_view->document->cached;
|
|
||||||
cached = doc_view->document->cached;
|
|
||||||
struct fragment *f = get_cache_fragment(cached);
|
|
||||||
|
|
||||||
if (f && f->length)
|
|
||||||
{
|
|
||||||
if (false && document->ecmascript_counter==0)
|
|
||||||
{
|
|
||||||
add_fragment(cached,0,code.source,code.length);
|
|
||||||
} else {
|
|
||||||
add_fragment(cached,f->length,code.source,code.length);
|
|
||||||
}
|
|
||||||
document->ecmascript_counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_LEDS
|
#ifdef CONFIG_LEDS
|
||||||
set_led_value(interpreter->vs->doc_view->session->status.ecmascript_led, 'J');
|
set_led_value(interpreter->vs->doc_view->session->status.ecmascript_led, 'J');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
done_string(&code);
|
|
||||||
args.rval().setBoolean(false);
|
args.rval().setBoolean(false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
-| 16 colors |-
|
-| 16 colors |-
|
||||||
</title>
|
</title>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
function onl()
|
||||||
|
{
|
||||||
|
|
||||||
document.writeln('<html><head><title>-| 16 colors |-</title></head><pre>');
|
document.writeln('<html><head><title>-| 16 colors |-</title></head><pre>');
|
||||||
var colors=[
|
var colors=[
|
||||||
"white",
|
"white",
|
||||||
@ -53,8 +56,9 @@ document.writeln('<html><head><title>-| 16 colors |-</title></head><pre>');
|
|||||||
document.writeln('<font color="red">and this is false: '+false+'</font>');
|
document.writeln('<font color="red">and this is false: '+false+'</font>');
|
||||||
document.writeln('<font color="yellow">',"That's it as ... ","1+1=",2,'</font>');
|
document.writeln('<font color="yellow">',"That's it as ... ","1+1=",2,'</font>');
|
||||||
document.writeln('</pre></body></html>');
|
document.writeln('</pre></body></html>');
|
||||||
</script>
|
}
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body onload="onl()">
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user