Added important check using JS_IsConstructing() in constructors, since
authorMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 10 Feb 2005 11:57:05 +0000 (11:57 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 10 Feb 2005 11:57:05 +0000 (11:57 +0000)
otherwise an assertion can cause a crash whenever the user script attempts
to call a constructor as a function (I.E. fd = FD(); vs fd = new FD();)

tests/js-test/src/classes/js_fd.c

index 3869a43..84845cb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: js_fd.c,v 1.5 2005/02/10 10:34:25 mmondor Exp $ */
+/* $Id: js_fd.c,v 1.6 2005/02/10 11:57:05 mmondor Exp $ */
 
 /*
  * Copyright (c) 2005, Matthew Mondor
@@ -101,6 +101,8 @@ static JSBool       fd_static_getProperty(JSContext *, JSObject *, jsval, jsval *);
 static JSBool  fd_m_open(JSContext *, JSObject *, uintN, jsval *, jsval *);
 static JSBool  fd_m_set(JSContext *, JSObject *, uintN, jsval *, jsval *);
 static JSBool  fd_m_close(JSContext *, JSObject *, uintN, jsval *, jsval *);
+static JSBool  fd_m_truncate(JSContext *, JSObject *, uintN, jsval *,
+                   jsval *);
 static JSBool  fd_m_put(JSContext *, JSObject *, uintN, jsval *, jsval *);
 static JSBool  fd_m_get(JSContext *, JSObject *, uintN, jsval *, jsval *);
 /*
@@ -114,8 +116,6 @@ static JSBool       fd_m_accept(JSContext *, JSObject *, uintN, jsval *, jsval *);
 static JSBool  fd_m_setsockopt(JSContext *, JSObject *, uintN, jsval *,
                    jsval *);
 static JSBool  fd_m_poll(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_truncate(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
 static JSBool  fd_m_shutdown(JSContext *, JSObject *, uintN, jsval *,
                    jsval *);
  */
@@ -138,6 +138,7 @@ static JSFunctionSpec fd_methods[] = {
        { "open", fd_m_open, 0, 0, 0 }, /* Variable 2-3 parameters */
        { "set", fd_m_set, 1, 0, 0 },
        { "close", fd_m_close, 0, 0, 0 },
+       { "truncate", fd_m_truncate, 1, 0, 0 },
        { "put", fd_m_put, 1, 0, 0 },
        { "get", fd_m_get, 0, 0, 0 },
 /*
@@ -150,7 +151,6 @@ static JSFunctionSpec fd_methods[] = {
        { "accept", fd_m_accept, 0, 0, 0 },
        { "setsockopt", fd_m_setsockopt, 2, 0, 0 },
        { "poll", fd_m_poll, 1, 0, 0 },
-       { "truncate", fd_m_truncate, 1, 0, 0 },
        { "shutdown", fd_m_shutdown, 1, 0, 0 },
        { "fcntl", fd_m_fcntl, 0, 0, 0 },
  */
@@ -268,7 +268,18 @@ fd_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
 
        if (argc != 0) {
                QUEUE_EXCEPTION("Wrong number of arguments");
-               return JS_FALSE;
+               goto err;
+       }
+
+       /*
+        * IMPORTANT: We must verify if the caller attempts to execute us as a
+        * normal function rather than as a constructor.  Otherwise, the
+        * caller can cause the interpreter to abort(3) in an assertion in
+        * JS_SetPrivate()!
+        */
+       if (!JS_IsConstructing(cx)) {
+               QUEUE_EXCEPTION("Constructor called as a function");
+               goto err;
        }
 
        if ((jsfd = JS_malloc(cx, sizeof(jsfd_t))) == NULL) {
@@ -622,6 +633,46 @@ fd_m_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 }
 
 static JSBool
+fd_m_truncate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+    jsval *rval)
+{
+       jsfd_t  *jsfd;
+       off_t   size;
+       int32_t i32;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc == 1) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+
+       if ((jsfd = JS_GetInstancePrivate(cx, obj, &fd_class, NULL)) == NULL) {
+               QUEUE_EXCEPTION("Null private data!");
+               return JS_FALSE;
+       }
+
+       if (jsfd->fd == -1) {
+               QUEUE_EXCEPTION("Descriptor closed");
+               return JS_FALSE;
+       }
+
+       if (!JS_ValueToInt32(cx, argv[0], &i32)) {
+               QUEUE_EXCEPTION("Invalid size argument");
+               return JS_FALSE;
+       }
+       size = (off_t)i32;
+
+       if (ftruncate(jsfd->fd, size) == -1) {
+               jsfd->error = errno;
+               QUEUE_EXCEPTION(strerror(errno));
+               return JS_FALSE;
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool
 fd_m_put(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
        jsfd_t          *jsfd;