...
 
Commits (13)
  • Philip Chimento's avatar
    system: Fix missing error check in dumpHeap() · 2fb9c043
    Philip Chimento authored
    The fopen() call was missing an error check, causing a crash if the path
    did not exist, for example.
    
    Closes: #134
    2fb9c043
  • Philip Chimento's avatar
    build: Post-release version bump · bc30b51b
    Philip Chimento authored
    bc30b51b
  • Cosimo Cecchi's avatar
    Merge branch '134-dump-heap-error-check' into 'master' · 8ba5f851
    Cosimo Cecchi authored
    Fix missing error check in dumpHeap()
    
    Closes #134
    
    See merge request GNOME/gjs!277
    8ba5f851
  • Philip Chimento's avatar
    function: Handle case of a bare GDestroyNotify in a function's args · 7d241743
    Philip Chimento authored
    For example, g_memory_input_stream_new_from_data() has a GDestroyNotify
    parameter which isn't associated with a callback, but with static data.
    I don't know of an annotation which will express the relation of a
    destroy parameter to anything other than a callback.
    
    Previously, since we assumed that all GDestroyNotify parameters were
    associated with callbacks, we'd mark their type as PARAM_SKIPPED. Their
    GIArgument would later be filled in when processing the calllback
    parameter. In the case of g_memory_input_stream_new_from_data(), this
    would crash because there was no callback parameter, so the GIArgument
    of the destroy parameter would never be filled in, and uninitialized
    data would be passed to the C function.
    
    Instead, mark such parameters as PARAM_UNKNOWN, a new parameter type
    indicating that we don't know what to pass for that parameter. If JS
    code tries to call a function with a PARAM_UNKNOWN parameter, then an
    exception will be thrown.
    
    Closes: #221
    7d241743
  • Philip Chimento's avatar
    function: Free transfer-full in arguments when function fails · a2f9ea08
    Philip Chimento authored
    If we fail to marshal the arguments and throw an exception before
    calling a gobject-introspected function, or the function itself throws
    a GError exception, then we can assume that any transfer of ownership
    of a (transfer full) or (transfer container) in-argument was not
    completed.
    
    This means that we have to free any storage that would otherwise have
    had its ownership transferred to the function.
    a2f9ea08
  • Cosimo Cecchi's avatar
    Merge branch '221-param-unknown' into 'master' · 600c5b3e
    Cosimo Cecchi authored
    function: Handle case of a bare GDestroyNotify in a function's args
    
    Closes #221
    
    See merge request GNOME/gjs!278
    600c5b3e
  • Philip Chimento's avatar
    context: Remove lazy flag from evaluated sources · d588f22f
    Philip Chimento authored
    This escaped notice when we removed the lazy flag from all other sources
    in commit b032fda4.
    d588f22f
  • Philip Chimento's avatar
    context: Fix gjs_context_eval() for non-zero-terminated strings · 870b1942
    Philip Chimento authored
    Calling gjs_context_eval() with a non-zero-terminated string has
    apparently been broken for quite a long time. I guess nobody ever does
    that.
    
    This is a surprisingly complicated fix for a simple-sounding problem.
    The complication is due to the passed-in strlen being ignored in more
    than one place: both in gjs_strip_unix_shebang() and in the code that
    converts UTF-8 to UTF-16.
    
    In addition, gjs_strip_unix_shebang() would access invalid memory if
    given a 1-length string or a non-zero-terminated string.
    
    We fix the UTF-16 conversion code, and replace gjs_strip_unix_shebang()
    with a safer version using C++ strings (which we have anyway after
    converting to UTF-16.) This new function, gjs_unix_shebang_len(),
    returns the offset that must be added to the string's starting position,
    in order to skip the shebang line.
    
    It would be better in the future to return a std::u16string_view from
    gjs_unix_shebang_len(), but that is not yet available in C++14.
    
    This bug was found by compiling with -Wunused-parameter!
    870b1942
  • Philip Chimento's avatar
    release: Prepare for 1.56.1 · 2b17ce95
    Philip Chimento authored
    2b17ce95
  • Iain Lane's avatar
    New upstream version 1.56.1 · 2655a05d
    Iain Lane authored
    2655a05d
  • Iain Lane's avatar
    Update upstream source from tag 'upstream/1.56.1' · 6521ea10
    Iain Lane authored
    Update to upstream version '1.56.1'
    with Debian dir cf0a52d7e310a3eae47d847c4b430ca2cbcef3a8
    6521ea10
  • Iain Lane's avatar
    New upstream release · f2683e24
    Iain Lane authored
    f2683e24
  • Iain Lane's avatar
    Update changelog · 09e81592
    Iain Lane authored
    09e81592
Version 1.56.1
--------------
- Closed bugs and merge requests:
* Calling dumpHeap() on non-existent directory causes crash [#134, !277,
Philip Chimento]
* Using Gio.MemoryInputStream.new_from_data ("string") causes segfault [#221,
!278, Philip Chimento]
* Fix gjs_context_eval() for non-zero-terminated strings [!281, Philip
Chimento]
Version 1.56.0
--------------
......
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for gjs 1.56.0.
# Generated by GNU Autoconf 2.69 for gjs 1.56.1.
#
# Report bugs to <https://gitlab.gnome.org/GNOME/gjs/issues>.
#
......@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='gjs'
PACKAGE_TARNAME='gjs'
PACKAGE_VERSION='1.56.0'
PACKAGE_STRING='gjs 1.56.0'
PACKAGE_VERSION='1.56.1'
PACKAGE_STRING='gjs 1.56.1'
PACKAGE_BUGREPORT='https://gitlab.gnome.org/GNOME/gjs/issues'
PACKAGE_URL='https://wiki.gnome.org/Projects/Gjs'
......@@ -1449,7 +1449,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures gjs 1.56.0 to adapt to many kinds of systems.
\`configure' configures gjs 1.56.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
......@@ -1519,7 +1519,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of gjs 1.56.0:";;
short | recursive ) echo "Configuration of gjs 1.56.1:";;
esac
cat <<\_ACEOF
......@@ -1697,7 +1697,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
gjs configure 1.56.0
gjs configure 1.56.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
......@@ -2248,7 +2248,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by gjs $as_me 1.56.0, which was
It was created by gjs $as_me 1.56.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
......@@ -3111,7 +3111,7 @@ fi
# Define the identity of the package.
PACKAGE='gjs'
VERSION='1.56.0'
VERSION='1.56.1'
cat >>confdefs.h <<_ACEOF
......@@ -3338,10 +3338,10 @@ ac_config_headers="$ac_config_headers config.h"
GJS_VERSION=15600
GJS_VERSION=15601
$as_echo "#define GJS_VERSION (1 * 100 + 56) * 100 + 0" >>confdefs.h
$as_echo "#define GJS_VERSION (1 * 100 + 56) * 100 + 1" >>confdefs.h
GETTEXT_PACKAGE=gjs
......@@ -24031,7 +24031,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by gjs $as_me 1.56.0, which was
This file was extended by gjs $as_me 1.56.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
......@@ -24102,7 +24102,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
gjs config.status 1.56.0
gjs config.status 1.56.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
......
......@@ -3,7 +3,7 @@
m4_define(pkg_major_version, 1)
m4_define(pkg_minor_version, 56)
m4_define(pkg_micro_version, 0)
m4_define(pkg_micro_version, 1)
m4_define(pkg_version, pkg_major_version.pkg_minor_version.pkg_micro_version)
m4_define(pkg_int_version, (pkg_major_version * 100 + pkg_minor_version) * 100 + pkg_micro_version)
......
gjs (1.56.1-1) UNRELEASED; urgency=medium
* New upstream stable release, fixing:
+ Calling dumpHeap() on non-existent directory causes crash
+ Using Gio.MemoryInputStream.new_from_data ("string") causes segfault
+ Fix gjs_context_eval() for non-zero-terminated strings
-- Iain Lane <laney@debian.org> Tue, 09 Apr 2019 09:25:13 +0100
gjs (1.56.0-1) experimental; urgency=medium
* New upstream release
......
......@@ -77,8 +77,7 @@ gjs_foreign_load_foreign_module(JSContext *context,
script = g_strdup_printf("imports.%s;", gi_namespace);
JS::RootedValue retval(context);
GjsContextPrivate* gjs = GjsContextPrivate::from_cx(context);
if (!gjs->eval_with_scope(nullptr, script, strlen(script), "<internal>",
&retval)) {
if (!gjs->eval_with_scope(nullptr, script, -1, "<internal>", &retval)) {
g_critical("ERROR importing foreign module %s\n", gi_namespace);
g_free(script);
return false;
......
......@@ -313,6 +313,8 @@ gjs_callback_closure(ffi_cif *cif,
case PARAM_CALLBACK:
/* Callbacks that accept another callback as a parameter are not
* supported, see gjs_callback_trampoline_new() */
case PARAM_UNKNOWN:
// PARAM_UNKNOWN is currently not ever set on a callback's args.
default:
g_assert_not_reached();
}
......@@ -1040,6 +1042,18 @@ gjs_invoke_c_function(JSContext *context,
break;
}
case PARAM_UNKNOWN:
gjs_throw(context,
"Error invoking %s.%s: impossible to determine what "
"to pass to the '%s' argument. It may be that the "
"function is unsupported, or there may be a bug in "
"its annotations.",
g_base_info_get_namespace(function->info),
g_base_info_get_name(function->info),
g_base_info_get_name(&arg_info));
failed = true;
break;
default:
;
}
......@@ -1196,7 +1210,15 @@ release:
if (direction == GI_DIRECTION_IN) {
arg = &in_arg_cvalues[c_arg_pos];
transfer = g_arg_info_get_ownership_transfer(&arg_info);
// If we failed before calling the function, or if the function
// threw an exception, then any GI_TRANSFER_EVERYTHING or
// GI_TRANSFER_CONTAINER parameters were not transferred. Treat
// them as GI_TRANSFER_NOTHING so that they are freed.
if (!failed && !did_throw_gerror)
transfer = g_arg_info_get_ownership_transfer(&arg_info);
else
transfer = GI_TRANSFER_NOTHING;
} else {
arg = &inout_original_arg_cvalues[c_arg_pos];
/* For inout, transfer refers to what we get back from the function; for
......@@ -1661,8 +1683,13 @@ init_cached_function_data (JSContext *context,
if (interface_type == GI_INFO_TYPE_CALLBACK) {
if (strcmp(g_base_info_get_name(interface_info), "DestroyNotify") == 0 &&
strcmp(g_base_info_get_namespace(interface_info), "GLib") == 0) {
/* Skip GDestroyNotify if they appear before the respective callback */
function->param_types[i] = PARAM_SKIPPED;
// We don't know (yet) what to do with GDestroyNotify
// appearing before a callback. If the callback comes later
// in the argument list, then PARAM_UNKNOWN will be
// overwritten with PARAM_SKIPPED. If no callback follows,
// then this is probably an unsupported function, so the
// value will remain PARAM_UNKNOWN.
function->param_types[i] = PARAM_UNKNOWN;
} else {
function->param_types[i] = PARAM_CALLBACK;
function->expected_js_argc += 1;
......
......@@ -39,7 +39,8 @@ typedef enum {
PARAM_NORMAL,
PARAM_SKIPPED,
PARAM_ARRAY,
PARAM_CALLBACK
PARAM_CALLBACK,
PARAM_UNKNOWN,
} GjsParamType;
struct GjsCallbackTrampoline {
......
......@@ -931,7 +931,7 @@ gjs_context_eval_file(GjsContext *js_context,
* GjsContextPrivate::eval_with_scope:
* @scope_object: an object to use as the global scope, or nullptr
* @script: JavaScript program encoded in UTF-8
* @script_len: length of @script
* @script_len: length of @script, or -1 if @script is 0-terminated
* @filename: filename to use as the origin of @script
* @retval: location for the return value of @script
*
......@@ -945,14 +945,7 @@ bool GjsContextPrivate::eval_with_scope(JS::HandleObject scope_object,
const char* script, ssize_t script_len,
const char* filename,
JS::MutableHandleValue retval) {
int start_line_number = 1;
JSAutoRequest ar(m_cx);
size_t real_len = script_len;
if (script_len < 0)
real_len = strlen(script);
script = gjs_strip_unix_shebang(script, &real_len, &start_line_number);
/* log and clear exception if it's set (should not be, normally...) */
if (JS_IsExceptionPending(m_cx)) {
......@@ -964,18 +957,13 @@ bool GjsContextPrivate::eval_with_scope(JS::HandleObject scope_object,
if (!eval_obj)
eval_obj = JS_NewPlainObject(m_cx);
JS::CompileOptions options(m_cx);
options.setFileAndLine(filename, start_line_number).setSourceIsLazy(true);
std::u16string utf16_string = gjs_utf8_script_to_utf16(script, script_len);
#if defined(G_OS_WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1900))
std::wstring wscript = gjs_win32_vc140_utf8_to_utf16(script);
std::u16string utf16_string(reinterpret_cast<const char16_t*>(wscript.c_str()));
#else
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
std::u16string utf16_string = convert.from_bytes(script);
#endif
unsigned start_line_number = 1;
size_t offset = gjs_unix_shebang_len(utf16_string, &start_line_number);
JS::SourceBufferHolder buf(utf16_string.c_str(), utf16_string.size(),
JS::SourceBufferHolder buf(utf16_string.c_str() + offset,
utf16_string.size() - offset,
JS::SourceBufferHolder::NoOwnership);
JS::AutoObjectVector scope_chain(m_cx);
......@@ -984,6 +972,9 @@ bool GjsContextPrivate::eval_with_scope(JS::HandleObject scope_object,
return false;
}
JS::CompileOptions options(m_cx);
options.setFileAndLine(filename, start_line_number);
if (!JS::Evaluate(m_cx, scope_chain, options, buf, retval))
return false;
......
......@@ -613,57 +613,35 @@ gjs_maybe_gc (JSContext *context)
}
/**
* gjs_strip_unix_shebang:
* gjs_unix_shebang_len:
*
* @script: (in): A pointer to a JS script
* @script_len: (inout): A pointer to the script length. The
* pointer will be modified if a shebang is stripped.
* @new_start_line_number: (out) (allow-none): A pointer to
* write the start-line number to account for the offset
* as a result of stripping the shebang.
* @script: A JS script
* @start_line_number: (out): the new start-line number to account for the
* offset as a result of stripping the shebang; can be either 1 or 2.
*
* Returns a pointer to the beginning of a script with unix
* shebangs removed. The outparams are useful to know the
* new length of the script and on what line of the
* Returns the offset in @script where the actual script begins with Unix
* shebangs removed. The outparam is useful to know what line of the
* original script we're executing from, so that any relevant
* offsets can be applied to the results of an execution pass.
*/
const char *
gjs_strip_unix_shebang(const char *script,
size_t *script_len,
int *start_line_number_out)
{
g_assert(script_len);
/* handle scripts with UNIX shebangs */
if (strncmp(script, "#!", 2) == 0) {
/* If we found a newline, advance the script by one line */
const char *s = (const char *) strstr (script, "\n");
if (s != NULL) {
if (*script_len > 0)
*script_len -= (s + 1 - script);
script = s + 1;
if (start_line_number_out)
*start_line_number_out = 2;
return script;
} else {
/* Just a shebang */
if (start_line_number_out)
*start_line_number_out = -1;
*script_len = 0;
return NULL;
}
size_t gjs_unix_shebang_len(const std::u16string& script,
unsigned* start_line_number) {
g_assert(start_line_number);
if (script.compare(0, 2, u"#!") != 0) {
// No shebang, leave the script unchanged
*start_line_number = 1;
return 0;
}
/* No shebang, return the original script */
if (start_line_number_out)
*start_line_number_out = 1;
*start_line_number = 2;
size_t newline_pos = script.find('\n', 2);
if (newline_pos == std::u16string::npos)
return script.size(); // Script consists only of a shebang line
return script;
// Point the offset after the newline
return newline_pos + 1;
}
#if defined(G_OS_WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1900))
......@@ -674,17 +652,30 @@ gjs_strip_unix_shebang(const char *script,
* obtain from MultiByteToWideChar(). See:
* https://social.msdn.microsoft.com/Forums/en-US/8f40dcd8-c67f-4eba-9134-a19b9178e481/vs-2015-rc-linker-stdcodecvt-error?forum=vcgeneral
*/
std::wstring gjs_win32_vc140_utf8_to_utf16(const char* str) {
int len = MultiByteToWideChar(CP_UTF8, 0, str, -1, nullptr, 0);
if (len == 0)
static std::wstring gjs_win32_vc140_utf8_to_utf16(const char* str,
ssize_t len) {
int bufsize = MultiByteToWideChar(CP_UTF8, 0, str, len, nullptr, 0);
if (bufsize == 0)
return nullptr;
std::wstring wstr(len, 0);
int result = MultiByteToWideChar(CP_UTF8, 0, str, -1, &wstr[0], len);
std::wstring wstr(bufsize, 0);
int result = MultiByteToWideChar(CP_UTF8, 0, str, len, &wstr[0], bufsize);
if (result == 0)
return nullptr;
wstr.resize(strlen(str));
wstr.resize(len < 0 ? strlen(str) : len);
return wstr;
}
#endif
std::u16string gjs_utf8_script_to_utf16(const char* script, ssize_t len) {
#if defined(G_OS_WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1900))
std::wstring wscript = gjs_win32_vc140_utf8_to_utf16(script, len);
return std::u16string(reinterpret_cast<const char16_t*>(wscript.c_str()));
#else
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
if (len < 0)
return convert.from_bytes(script);
return convert.from_bytes(script, script + len);
#endif
}
......@@ -299,13 +299,14 @@ bool gjs_unichar_from_string (JSContext *context,
void gjs_maybe_gc (JSContext *context);
void gjs_gc_if_needed(JSContext *cx);
GJS_USE
const char * gjs_strip_unix_shebang(const char *script,
size_t *script_len,
int *new_start_line_number);
G_END_DECLS
GJS_USE
size_t gjs_unix_shebang_len(const std::u16string& script,
unsigned* start_line_number);
GJS_USE
std::u16string gjs_utf8_script_to_utf16(const char* script, ssize_t len);
GJS_JSAPI_RETURN_CONVENTION
GjsAutoChar gjs_format_stack_trace(JSContext *cx,
JS::HandleObject saved_frame);
......
......@@ -88,27 +88,17 @@ class GjsModule {
/* Carries out the actual execution of the module code */
GJS_JSAPI_RETURN_CONVENTION
bool
evaluate_import(JSContext *cx,
JS::HandleObject module,
const char *script,
size_t script_len,
const char *filename,
int line_number)
{
JS::CompileOptions options(cx);
options.setFileAndLine(filename, line_number);
#if defined(G_OS_WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1900))
std::wstring wscript = gjs_win32_vc140_utf8_to_utf16(script);
std::u16string utf16_string(
reinterpret_cast<const char16_t*>(wscript.c_str()));
#else
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
std::u16string utf16_string = convert.from_bytes(script);
#endif
JS::SourceBufferHolder buf(utf16_string.c_str(), utf16_string.size(),
bool evaluate_import(JSContext* cx, JS::HandleObject module,
const char* script, ssize_t script_len,
const char* filename) {
std::u16string utf16_string =
gjs_utf8_script_to_utf16(script, script_len);
unsigned start_line_number = 1;
size_t offset = gjs_unix_shebang_len(utf16_string, &start_line_number);
JS::SourceBufferHolder buf(utf16_string.c_str() + offset,
utf16_string.size() - offset,
JS::SourceBufferHolder::NoOwnership);
JS::AutoObjectVector scope_chain(cx);
......@@ -117,6 +107,9 @@ class GjsModule {
return false;
}
JS::CompileOptions options(cx);
options.setFileAndLine(filename, start_line_number);
JS::RootedValue ignored_retval(cx);
if (!JS::Evaluate(cx, scope_chain, options, buf, &ignored_retval))
return false;
......@@ -139,7 +132,6 @@ class GjsModule {
GError *error = nullptr;
char *unowned_script;
size_t script_len = 0;
int start_line_number = 1;
if (!(g_file_load_contents(file, nullptr, &unowned_script, &script_len,
nullptr, &error)))
......@@ -148,12 +140,8 @@ class GjsModule {
GjsAutoChar script = unowned_script; /* steals ownership */
g_assert(script != nullptr);
const char *stripped_script =
gjs_strip_unix_shebang(script, &script_len, &start_line_number);
GjsAutoChar full_path = g_file_get_parse_name(file);
return evaluate_import(cx, module, stripped_script, script_len,
full_path, start_line_number);
return evaluate_import(cx, module, script, script_len, full_path);
}
/* JSClass operations */
......
......@@ -762,3 +762,12 @@ describe('GObject properties', function () {
expect(() => obj.some_readonly = 35).toThrow();
}).pend('https://gitlab.gnome.org/GNOME/gobject-introspection/merge_requests/32');
});
describe('GDestroyNotify parameters', function () {
it('throws when encountering a GDestroyNotify not associated with a callback', function () {
// the 'destroy' argument applies to the data, which is not supported in
// gobject-introspection
expect(() => Gio.MemoryInputStream.new_from_data('foobar'))
.toThrowError(/destroy/);
});
});
......@@ -28,3 +28,9 @@ describe('System.gc()', function () {
expect(System.gc).not.toThrow();
});
});
describe('System.dumpHeap()', function () {
it('throws but does not crash when given a nonexistent path', function () {
expect(() => System.dumpHeap('/does/not/exist')).toThrow();
});
});
\ No newline at end of file
This diff is collapsed.
......@@ -6,66 +6,70 @@
# define SECTION
#endif
static const SECTION union { const guint8 data[444]; const double alignment; void * const ptr;} mock_js_resources_resource_data = { {
0x47, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x28, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0xb0, 0xb7, 0x24, 0x30, 0x04, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x06, 0x00, 0x4c, 0x00,
0x08, 0x01, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00,
0xf1, 0x6a, 0x43, 0xdc, 0x07, 0x00, 0x00, 0x00,
0x0c, 0x01, 0x00, 0x00, 0x17, 0x00, 0x76, 0x00,
0x28, 0x01, 0x00, 0x00, 0x71, 0x01, 0x00, 0x00,
0xa3, 0x5c, 0x53, 0x9e, 0x00, 0x00, 0x00, 0x00,
0x71, 0x01, 0x00, 0x00, 0x04, 0x00, 0x4c, 0x00,
0x78, 0x01, 0x00, 0x00, 0x7c, 0x01, 0x00, 0x00,
0x2b, 0x31, 0xce, 0x57, 0x05, 0x00, 0x00, 0x00,
0x7c, 0x01, 0x00, 0x00, 0x05, 0x00, 0x4c, 0x00,
0x84, 0x01, 0x00, 0x00, 0x88, 0x01, 0x00, 0x00,
0x4b, 0x50, 0x90, 0x0b, 0x06, 0x00, 0x00, 0x00,
0x88, 0x01, 0x00, 0x00, 0x04, 0x00, 0x4c, 0x00,
0x8c, 0x01, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
0x9c, 0xba, 0xf8, 0xa8, 0x02, 0x00, 0x00, 0x00,
0x90, 0x01, 0x00, 0x00, 0x05, 0x00, 0x4c, 0x00,
0x98, 0x01, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x00,
0xd4, 0xb5, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff,
0x9c, 0x01, 0x00, 0x00, 0x01, 0x00, 0x4c, 0x00,
0xa0, 0x01, 0x00, 0x00, 0xa4, 0x01, 0x00, 0x00,
0x44, 0x97, 0xc8, 0xe0, 0x03, 0x00, 0x00, 0x00,
0xa4, 0x01, 0x00, 0x00, 0x12, 0x00, 0x4c, 0x00,
0xb8, 0x01, 0x00, 0x00, 0xbc, 0x01, 0x00, 0x00,
0x67, 0x6e, 0x6f, 0x6d, 0x65, 0x2f, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x6c, 0x6f, 0x61, 0x64,
0x65, 0x64, 0x4a, 0x53, 0x46, 0x72, 0x6f, 0x6d,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x2e, 0x6a, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2f, 0x2a, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x72,
0x74, 0x65, 0x64, 0x20, 0x6d, 0x6f, 0x63, 0x6b,
0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x20, 0x2a, 0x2f, 0x0a, 0x66, 0x75, 0x6e,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x6f,
0x63, 0x6b, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x7d,
0x0a, 0x00, 0x00, 0x28, 0x75, 0x75, 0x61, 0x79,
0x29, 0x67, 0x6a, 0x73, 0x2f, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74,
0x2f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x6f, 0x72, 0x67, 0x2f, 0x00, 0x00, 0x00, 0x00,
0x6d, 0x6f, 0x63, 0x6b, 0x2f, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x67, 0x6a, 0x73, 0x2d,
0x74, 0x65, 0x73, 0x74, 0x2d, 0x63, 0x6f, 0x76,
0x65, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00
#ifdef _MSC_VER
static const SECTION union { const guint8 data[445]; const double alignment; void * const ptr;} mock_js_resources_resource_data = { {
0107, 0126, 0141, 0162, 0151, 0141, 0156, 0164, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0030, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0000, 0000, 0050, 0010, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0002, 0000, 0000, 0000, 0002, 0000, 0000, 0000,
0005, 0000, 0000, 0000, 0010, 0000, 0000, 0000, 0010, 0000, 0000, 0000, 0010, 0000, 0000, 0000,
0260, 0267, 0044, 0060, 0003, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0006, 0000, 0114, 0000,
0010, 0001, 0000, 0000, 0014, 0001, 0000, 0000, 0361, 0152, 0103, 0334, 0006, 0000, 0000, 0000,
0014, 0001, 0000, 0000, 0027, 0000, 0166, 0000, 0050, 0001, 0000, 0000, 0161, 0001, 0000, 0000,
0243, 0134, 0123, 0236, 0000, 0000, 0000, 0000, 0161, 0001, 0000, 0000, 0004, 0000, 0114, 0000,
0170, 0001, 0000, 0000, 0174, 0001, 0000, 0000, 0113, 0120, 0220, 0013, 0005, 0000, 0000, 0000,
0174, 0001, 0000, 0000, 0004, 0000, 0114, 0000, 0200, 0001, 0000, 0000, 0204, 0001, 0000, 0000,
0053, 0061, 0316, 0127, 0007, 0000, 0000, 0000, 0204, 0001, 0000, 0000, 0005, 0000, 0114, 0000,
0214, 0001, 0000, 0000, 0220, 0001, 0000, 0000, 0324, 0265, 0002, 0000, 0377, 0377, 0377, 0377,
0220, 0001, 0000, 0000, 0001, 0000, 0114, 0000, 0224, 0001, 0000, 0000, 0230, 0001, 0000, 0000,
0104, 0227, 0310, 0340, 0004, 0000, 0000, 0000, 0230, 0001, 0000, 0000, 0022, 0000, 0114, 0000,
0254, 0001, 0000, 0000, 0260, 0001, 0000, 0000, 0234, 0272, 0370, 0250, 0002, 0000, 0000, 0000,
0260, 0001, 0000, 0000, 0005, 0000, 0114, 0000, 0270, 0001, 0000, 0000, 0274, 0001, 0000, 0000,
0147, 0156, 0157, 0155, 0145, 0057, 0000, 0000, 0002, 0000, 0000, 0000, 0154, 0157, 0141, 0144,
0145, 0144, 0112, 0123, 0106, 0162, 0157, 0155, 0122, 0145, 0163, 0157, 0165, 0162, 0143, 0145,
0056, 0152, 0163, 0000, 0000, 0000, 0000, 0000, 0071, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0057, 0052, 0040, 0145, 0170, 0160, 0157, 0162, 0164, 0145, 0144, 0040, 0155, 0157, 0143, 0153,
0137, 0146, 0165, 0156, 0143, 0164, 0151, 0157, 0156, 0040, 0052, 0057, 0012, 0146, 0165, 0156,
0143, 0164, 0151, 0157, 0156, 0040, 0155, 0157, 0143, 0153, 0137, 0146, 0165, 0156, 0143, 0164,
0151, 0157, 0156, 0050, 0051, 0040, 0173, 0175, 0012, 0000, 0000, 0050, 0165, 0165, 0141, 0171,
0051, 0147, 0152, 0163, 0057, 0000, 0000, 0000, 0007, 0000, 0000, 0000, 0157, 0162, 0147, 0057,
0000, 0000, 0000, 0000, 0164, 0145, 0163, 0164, 0057, 0000, 0000, 0000, 0006, 0000, 0000, 0000,
0057, 0000, 0000, 0000, 0003, 0000, 0000, 0000, 0147, 0152, 0163, 0055, 0164, 0145, 0163, 0164,
0055, 0143, 0157, 0166, 0145, 0162, 0141, 0147, 0145, 0057, 0000, 0000, 0001, 0000, 0000, 0000,
0155, 0157, 0143, 0153, 0057, 0000, 0000, 0000, 0004, 0000, 0000, 0000
} };
static GStaticResource static_resource = { mock_js_resources_resource_data.data, sizeof (mock_js_resources_resource_data.data), NULL, NULL, NULL };
#else /* _MSC_VER */
static const SECTION union { const guint8 data[445]; const double alignment; void * const ptr;} mock_js_resources_resource_data = {
"\107\126\141\162\151\141\156\164\000\000\000\000\000\000\000\000"
"\030\000\000\000\000\001\000\000\000\000\000\050\010\000\000\000"
"\000\000\000\000\001\000\000\000\002\000\000\000\002\000\000\000"
"\005\000\000\000\010\000\000\000\010\000\000\000\010\000\000\000"
"\260\267\044\060\003\000\000\000\000\001\000\000\006\000\114\000"
"\010\001\000\000\014\001\000\000\361\152\103\334\006\000\000\000"
"\014\001\000\000\027\000\166\000\050\001\000\000\161\001\000\000"
"\243\134\123\236\000\000\000\000\161\001\000\000\004\000\114\000"
"\170\001\000\000\174\001\000\000\113\120\220\013\005\000\000\000"
"\174\001\000\000\004\000\114\000\200\001\000\000\204\001\000\000"
"\053\061\316\127\007\000\000\000\204\001\000\000\005\000\114\000"
"\214\001\000\000\220\001\000\000\324\265\002\000\377\377\377\377"
"\220\001\000\000\001\000\114\000\224\001\000\000\230\001\000\000"
"\104\227\310\340\004\000\000\000\230\001\000\000\022\000\114\000"
"\254\001\000\000\260\001\000\000\234\272\370\250\002\000\000\000"
"\260\001\000\000\005\000\114\000\270\001\000\000\274\001\000\000"
"\147\156\157\155\145\057\000\000\002\000\000\000\154\157\141\144"
"\145\144\112\123\106\162\157\155\122\145\163\157\165\162\143\145"
"\056\152\163\000\000\000\000\000\071\000\000\000\000\000\000\000"
"\057\052\040\145\170\160\157\162\164\145\144\040\155\157\143\153"
"\137\146\165\156\143\164\151\157\156\040\052\057\012\146\165\156"
"\143\164\151\157\156\040\155\157\143\153\137\146\165\156\143\164"
"\151\157\156\050\051\040\173\175\012\000\000\050\165\165\141\171"
"\051\147\152\163\057\000\000\000\007\000\000\000\157\162\147\057"
"\000\000\000\000\164\145\163\164\057\000\000\000\006\000\000\000"
"\057\000\000\000\003\000\000\000\147\152\163\055\164\145\163\164"
"\055\143\157\166\145\162\141\147\145\057\000\000\001\000\000\000"
"\155\157\143\153\057\000\000\000\004\000\000\000" };
#endif /* !_MSC_VER */
static GStaticResource static_resource = { mock_js_resources_resource_data.data, sizeof (mock_js_resources_resource_data.data) - 1 /* nul terminator */, NULL, NULL, NULL };
extern GResource *mock_js_resources_get_resource (void);
GResource *mock_js_resources_get_resource (void)
{
......
......@@ -24,6 +24,8 @@
#include <config.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
......@@ -106,6 +108,11 @@ gjs_dump_heap(JSContext *cx,
if (filename) {
FILE *fp = fopen(filename, "a");
if (!fp) {
gjs_throw(cx, "Cannot dump heap to %s: %s", filename.get(),
strerror(errno));
return false;
}
js::DumpHeap(cx, fp, js::IgnoreNurseryObjects);
fclose(fp);
} else {
......
......@@ -65,6 +65,19 @@ gjstest_test_func_gjs_context_construct_eval(void)
g_object_unref (context);
}
static void gjstest_test_func_gjs_context_eval_non_zero_terminated(void) {
GjsAutoUnref<GjsContext> gjs = gjs_context_new();
GError* error = NULL;
int status;
// This string is invalid JS if it is treated as zero-terminated
bool ok = gjs_context_eval(gjs, "77!", 2, "<input>", &status, &error);
g_assert_true(ok);
g_assert_no_error(error);
g_assert_cmpint(status, ==, 77);
}
static void
gjstest_test_func_gjs_context_exit(void)
{
......@@ -329,52 +342,37 @@ gjstest_test_func_util_glib_strv_concat_pointers(void)
static void
gjstest_test_strip_shebang_no_advance_for_no_shebang(void)
{
const char *script = "foo\nbar";
size_t script_len_original = strlen(script);
size_t script_len = script_len_original;
int line_number = 1;
const char *stripped = gjs_strip_unix_shebang(script,
&script_len,
&line_number);
g_assert_cmpstr(script, ==, stripped);
g_assert(script_len == script_len_original);
g_assert(line_number == 1);
unsigned line_number = 1;
size_t offset = gjs_unix_shebang_len(u"foo\nbar", &line_number);
g_assert_cmpuint(offset, ==, 0);
g_assert_cmpuint(line_number, ==, 1);
}
static void gjstest_test_strip_shebang_no_advance_for_too_short_string(void) {
unsigned line_number = 1;
size_t offset = gjs_unix_shebang_len(u"Z", &line_number);
g_assert_cmpuint(offset, ==, 0);
g_assert_cmpuint(line_number, ==, 1);
}
static void
gjstest_test_strip_shebang_advance_for_shebang(void)
{
const char *script = "#!foo\nbar";
size_t script_len_original = strlen(script);
size_t script_len = script_len_original;
int line_number = 1;
const char *stripped = gjs_strip_unix_shebang(script,
&script_len,
&line_number);
g_assert_cmpstr(stripped, ==, "bar");
g_assert(script_len == 3);
g_assert(line_number == 2);
unsigned line_number = 1;
size_t offset = gjs_unix_shebang_len(u"#!foo\nbar", &line_number);
g_assert_cmpuint(offset, ==, 6);
g_assert_cmpuint(line_number, ==, 2);
}
static void
gjstest_test_strip_shebang_return_null_for_just_shebang(void)
{
const char *script = "#!foo";
size_t script_len_original = strlen(script);
size_t script_len = script_len_original;
int line_number = 1;
const char *stripped = gjs_strip_unix_shebang(script,
&script_len,
&line_number);
g_assert(stripped == NULL);
g_assert(script_len == 0);
g_assert(line_number == -1);
static void gjstest_test_strip_shebang_advance_to_end_for_just_shebang(void) {
unsigned line_number = 1;
size_t offset = gjs_unix_shebang_len(u"#!foo", &line_number);
g_assert_cmpuint(offset, ==, 5);
g_assert_cmpuint(line_number, ==, 2);
}
static void
......@@ -414,11 +412,16 @@ main(int argc,
g_test_add_func("/gjs/context/construct/destroy", gjstest_test_func_gjs_context_construct_destroy);
g_test_add_func("/gjs/context/construct/eval", gjstest_test_func_gjs_context_construct_eval);
g_test_add_func("/gjs/context/eval/non-zero-terminated",
gjstest_test_func_gjs_context_eval_non_zero_terminated);
g_test_add_func("/gjs/context/exit", gjstest_test_func_gjs_context_exit);
g_test_add_func("/gjs/gobject/js_defined_type", gjstest_test_func_gjs_gobject_js_defined_type);
g_test_add_func("/gjs/jsutil/strip_shebang/no_shebang", gjstest_test_strip_shebang_no_advance_for_no_shebang);
g_test_add_func("/gjs/jsutil/strip_shebang/short_string",
gjstest_test_strip_shebang_no_advance_for_too_short_string);
g_test_add_func("/gjs/jsutil/strip_shebang/have_shebang", gjstest_test_strip_shebang_advance_for_shebang);
g_test_add_func("/gjs/jsutil/strip_shebang/only_shebang", gjstest_test_strip_shebang_return_null_for_just_shebang);
g_test_add_func("/gjs/jsutil/strip_shebang/only_shebang",
gjstest_test_strip_shebang_advance_to_end_for_just_shebang);
g_test_add_func("/gjs/profiler/start_stop", gjstest_test_profiler_start_stop);
g_test_add_func("/util/glib/strv/concat/null", gjstest_test_func_util_glib_strv_concat_null);
g_test_add_func("/util/glib/strv/concat/pointers", gjstest_test_func_util_glib_strv_concat_pointers);
......
......@@ -13,7 +13,7 @@
#define GETTEXT_PACKAGE "gjs"
/* The gjs version as an integer */
#define GJS_VERSION 15600
#define GJS_VERSION 15601
/* define if the compiler supports basic C++11 syntax */
#define HAVE_CXX11 1
......@@ -74,7 +74,7 @@
#define PACKAGE_NAME "gjs"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "gjs 1.56.0"
#define PACKAGE_STRING "gjs 1.56.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "gjs"
......@@ -83,10 +83,10 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.56.0"
#define PACKAGE_VERSION "1.56.1"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "1.56.0"
#define VERSION "1.56.1"