From e5856f0a405ea984168b334b4284f8fff99caa02 Mon Sep 17 00:00:00 2001 From: Rob Swindell <rob@synchro.net> Date: Fri, 1 Jan 2021 15:44:30 -0800 Subject: [PATCH] Fix: can_* and is_* properties were not dynamic. Added "posts" property. The following properties would only reflect the status at the time the msg_area object was initialized: - can_access - can_read - can_post - is_operator - is_moderated ... so if changes were made the user while online, for example, these property values would *not* also change to reflect the current state. The grp[] and grp_list[] 'can_access' properties still have this flaw. Also: Add a new "posts" property to the sub[] and sub_list[] objects to report the current number of posted messages (quicker than opening a MsgBase instance). --- src/sbbs3/js_msg_area.c | 169 ++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 101 deletions(-) diff --git a/src/sbbs3/js_msg_area.c b/src/sbbs3/js_msg_area.c index 5a5252e5b6..0213230594 100644 --- a/src/sbbs3/js_msg_area.c +++ b/src/sbbs3/js_msg_area.c @@ -1,9 +1,5 @@ -/* js_msg_area.c */ - /* Synchronet JavaScript "Message Area" Object */ -/* $Id: js_msg_area.c,v 1.75 2020/08/16 01:01:09 rswindell Exp $ */ - /**************************************************************************** * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * @@ -17,21 +13,9 @@ * See the GNU General Public License for more details: gpl.txt or * * http://www.fsf.org/copyleft/gpl.html * * * - * Anonymous FTP access to the most recent released source is available at * - * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * - * * - * Anonymous CVS access to the development source and modification history * - * is available at cvs.synchro.net:/cvsroot/sbbs, example: * - * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * - * (just hit return, no password is necessary) * - * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * - * * * For Synchronet coding style and modification guidelines, see * * http://www.synchro.net/source.html * * * - * You are encouraged to submit any modifications (preferably in Unix diff * - * format) via e-mail to mods@synchro.net * - * * * Note: If this box doesn't appear square, then you need to fix your tabs. * ****************************************************************************/ @@ -95,6 +79,7 @@ static char* msg_sub_prop_desc[] = { ,"user's current new message scan pointer (highest-read message number)" ,"user's message scan configuration (bitfield) - see <tt>SCAN_CFG_*</tt> in <tt>sbbsdefs.js</tt> for details" ,"user's last-read message number" + ,"number of messages currently posted to this sub-board <i>(introduced in v3.18c)</i>" ,NULL }; #endif @@ -104,6 +89,7 @@ struct js_msg_area_priv { user_t *user; client_t *client; subscan_t *subscan; + uint subnum; }; BOOL DLLCALL js_CreateMsgAreaProperties(JSContext* cx, scfg_t* cfg, JSObject* subobj, uint subnum) @@ -250,29 +236,56 @@ BOOL DLLCALL js_CreateMsgAreaProperties(JSContext* cx, scfg_t* cfg, JSObject* su return(TRUE); } -/*******************************************/ -/* Re-writable Sub-board Object Properites */ -/*******************************************/ +/***************************************/ +/* Dynamic Sub-board Object Properites */ +/***************************************/ enum { - SUB_PROP_SCAN_PTR + SUB_PROP_CAN_ACCESS + ,SUB_PROP_CAN_READ + ,SUB_PROP_CAN_POST + ,SUB_PROP_IS_OPERATOR + ,SUB_PROP_IS_MODERATED + ,SUB_PROP_SCAN_PTR ,SUB_PROP_SCAN_CFG ,SUB_PROP_LAST_READ + ,SUB_PROP_POSTS }; - static JSBool js_sub_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) { jsval idval; jsint tiny; - subscan_t* scan; + struct js_msg_area_priv *p; - if((scan=(subscan_t*)JS_GetPrivate(cx,obj))==NULL) - return(JS_TRUE); + if((p=(struct js_msg_area_priv*)JS_GetPrivate(cx, obj))==NULL) + return JS_FALSE; + subscan_t* scan = p->subscan; JS_IdToValue(cx, id, &idval); tiny = JSVAL_TO_INT(idval); switch(tiny) { + case SUB_PROP_CAN_ACCESS: + *vp = BOOLEAN_TO_JSVAL(p->user==NULL || can_user_access_sub(p->cfg, p->subnum, p->user, p->client)); + break; + case SUB_PROP_CAN_READ: + *vp = BOOLEAN_TO_JSVAL(p->user==NULL || can_user_read_sub(p->cfg, p->subnum, p->user, p->client)); + break; + case SUB_PROP_CAN_POST: + *vp = BOOLEAN_TO_JSVAL(p->user==NULL || can_user_post(p->cfg, p->subnum, p->user, p->client,/* reason: */NULL)); + break; + case SUB_PROP_IS_OPERATOR: + *vp = BOOLEAN_TO_JSVAL(p->user == NULL || is_user_subop(p->cfg, p->subnum, p->user, p->client)); + break; + case SUB_PROP_IS_MODERATED: + if(p->cfg->sub[p->subnum]->mod_ar != NULL + && p->cfg->sub[p->subnum]->mod_ar[0] != 0 + && p->user != NULL + && chk_ar(p->cfg,p->cfg->sub[p->subnum]->mod_ar, p->user, p->client)) + *vp = JSVAL_TRUE; + else + *vp = JSVAL_FALSE; + break; case SUB_PROP_SCAN_PTR: *vp=UINT_TO_JSVAL(scan->ptr); break; @@ -282,6 +295,9 @@ static JSBool js_sub_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) case SUB_PROP_LAST_READ: *vp=UINT_TO_JSVAL(scan->last); break; + case SUB_PROP_POSTS: + *vp=UINT_TO_JSVAL(getposts(p->cfg, p->subnum)); + break; } return(JS_TRUE); @@ -322,12 +338,29 @@ static JSBool js_sub_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, j static struct JSPropertySpec js_sub_properties[] = { /* name ,tinyid ,flags */ - { "scan_ptr" ,SUB_PROP_SCAN_PTR ,JSPROP_ENUMERATE|JSPROP_SHARED }, - { "scan_cfg" ,SUB_PROP_SCAN_CFG ,JSPROP_ENUMERATE|JSPROP_SHARED }, - { "last_read" ,SUB_PROP_LAST_READ ,JSPROP_ENUMERATE|JSPROP_SHARED }, + { "can_access" ,SUB_PROP_CAN_ACCESS ,JSPROP_ENUMERATE|JSPROP_SHARED|JSPROP_READONLY }, + { "can_read" ,SUB_PROP_CAN_READ ,JSPROP_ENUMERATE|JSPROP_SHARED|JSPROP_READONLY }, + { "can_post" ,SUB_PROP_CAN_POST ,JSPROP_ENUMERATE|JSPROP_SHARED|JSPROP_READONLY }, + { "is_operator" ,SUB_PROP_IS_OPERATOR ,JSPROP_ENUMERATE|JSPROP_SHARED|JSPROP_READONLY }, + { "is_moderated" ,SUB_PROP_IS_MODERATED ,JSPROP_ENUMERATE|JSPROP_SHARED|JSPROP_READONLY }, + { "scan_ptr" ,SUB_PROP_SCAN_PTR ,JSPROP_ENUMERATE|JSPROP_SHARED }, + { "scan_cfg" ,SUB_PROP_SCAN_CFG ,JSPROP_ENUMERATE|JSPROP_SHARED }, + { "last_read" ,SUB_PROP_LAST_READ ,JSPROP_ENUMERATE|JSPROP_SHARED }, + { "posts" ,SUB_PROP_POSTS ,JSPROP_ENUMERATE|JSPROP_SHARED|JSPROP_READONLY }, {0} }; +static void +js_msg_area_finalize(JSContext *cx, JSObject *obj) +{ + struct js_msg_area_priv *p; + + if((p=(struct js_msg_area_priv*)JS_GetPrivate(cx,obj))==NULL) + return; + + free(p); + JS_SetPrivate(cx,obj,NULL); +} static JSClass js_sub_class = { "MsgSub" /* name */ @@ -339,7 +372,7 @@ static JSClass js_sub_class = { ,JS_EnumerateStub /* enumerate */ ,JS_ResolveStub /* resolve */ ,JS_ConvertStub /* convert */ - ,JS_FinalizeStub /* finalize */ + ,js_msg_area_finalize /* finalize */ }; JSBool DLLCALL js_msg_area_resolve(JSContext* cx, JSObject* areaobj, jsid id) @@ -504,35 +537,15 @@ JSBool DLLCALL js_msg_area_resolve(JSContext* cx, JSObject* areaobj, jsid id) for(d=0;d<p->cfg->total_subs;d++) { if(p->cfg->sub[d]->grp!=l) continue; - if((subobj=JS_NewObject(cx, &js_sub_class, subobj_proto, NULL))==NULL) return JS_FALSE; -/** Crash ^^^ Here in JSexec/ircd upon recycle/reload of script: - - mozjs185-1.0.dll!62e4a968() - [Frames below may be incorrect and/or missing, no symbols loaded for mozjs185-1.0.dll] - mozjs185-1.0.dll!62eda4b2() - mozjs185-1.0.dll!62e9cd4e() - mozjs185-1.0.dll!62ea3cf0() - mozjs185-1.0.dll!62e4e39e() - mozjs185-1.0.dll!62edd884() - mozjs185-1.0.dll!62e8010f() - mozjs185-1.0.dll!62e5b0c9() - mozjs185-1.0.dll!62e4b1ee() -> sbbs.dll!js_CreateMsgAreaObject(JSContext * cx=0x07b33ce8, JSObject * parent=0x0a37f028, scfg_t * cfg=0x004a2b20, user_t * user=0x00000000, client_t * client=0x00000000, subscan_t * subscan=0x00000000) Line 459 + 0x17 bytes C - sbbs.dll!js_CreateUserObjects(JSContext * cx=0x07b33ce8, JSObject * parent=0x0a37f028, scfg_t * cfg=0x004a2b20, user_t * user=0x00000000, client_t * client=0x00000000, char * html_index_file=0x00000000, subscan_t * subscan=0x00000000) Line 1431 + 0x1d bytes C - sbbs.dll!js_CreateCommonObjects(JSContext * js_cx=0x07b33ce8, scfg_t * cfg=0x004a2b20, scfg_t * node_cfg=0x004a2b20, jsSyncMethodSpec * methods=0x00000000, __int64 uptime=0, char * host_name=0x101bdaa6, char * socklib_desc=0x101bdaa6, js_branch_t * branch=0x019c8f30, js_startup_t * js_startup=0x0012f7cc, client_t * client=0x00000000, unsigned int client_socket=4294967295, js_server_props_t * props=0x00000000) Line 3858 + 0x1b bytes C - sbbs.dll!js_load(JSContext * cx=0x02e36300, unsigned int argc=3, unsigned __int64 * arglist=0x01d700d0) Line 282 + 0x44 bytes C - mozjs185-1.0.dll!62e91dfd() - jsexec.exe!__lock_fhandle(int fh=1240564) Line 467 C - 7ffdf000() - ffff0007() - mozjs185-1.0.dll!62fe9c60() - -*/ - - if(p->subscan!=NULL) - JS_SetPrivate(cx,subobj,&p->subscan[d]); + struct js_msg_area_priv *np = malloc(sizeof(struct js_msg_area_priv)); + if(np == NULL) + continue; + *np = *p; + np->subscan = &p->subscan[d]; + np->subnum = d; + JS_SetPrivate(cx, subobj, np); val=OBJECT_TO_JSVAL(subobj); sub_index=-1; @@ -561,39 +574,6 @@ JSBool DLLCALL js_msg_area_resolve(JSContext* cx, JSObject* areaobj, jsid id) if(!js_CreateMsgAreaProperties(cx, p->cfg, subobj, d)) return JS_FALSE; - val = BOOLEAN_TO_JSVAL(grp_index >= 0 && sub_index >= 0); - if(!JS_SetProperty(cx, subobj, "can_access", &val)) - return JS_FALSE; - - if(p->user==NULL) - val=BOOLEAN_TO_JSVAL(JS_TRUE); - else - val=BOOLEAN_TO_JSVAL(can_user_read_sub(p->cfg,d,p->user,p->client)); - if(!JS_SetProperty(cx, subobj, "can_read", &val)) - return JS_FALSE; - - if(p->user==NULL) - val=BOOLEAN_TO_JSVAL(JS_TRUE); - else - val=BOOLEAN_TO_JSVAL(can_user_post(p->cfg,d,p->user,p->client,/* reason: */NULL)); - if(!JS_SetProperty(cx, subobj, "can_post", &val)) - return JS_FALSE; - - if(p->user==NULL) - val=BOOLEAN_TO_JSVAL(JS_TRUE); - else - val=BOOLEAN_TO_JSVAL(is_user_subop(p->cfg,d,p->user,p->client)); - if(!JS_SetProperty(cx, subobj, "is_operator", &val)) - return JS_FALSE; - - if(p->cfg->sub[d]->mod_ar!=NULL && p->cfg->sub[d]->mod_ar[0]!=0 && p->user!=NULL - && chk_ar(p->cfg,p->cfg->sub[d]->mod_ar,p->user,p->client)) - val=BOOLEAN_TO_JSVAL(JS_TRUE); - else - val=BOOLEAN_TO_JSVAL(JS_FALSE); - if(!JS_SetProperty(cx, subobj, "is_moderated", &val)) - return JS_FALSE; - if(!JS_DefineProperties(cx, subobj, js_sub_properties)) return JS_FALSE; @@ -634,19 +614,6 @@ static JSBool js_msg_area_enumerate(JSContext *cx, JSObject *obj) return(js_msg_area_resolve(cx, obj, JSID_VOID)); } -static void -js_msg_area_finalize(JSContext *cx, JSObject *obj) -{ - struct js_msg_area_priv *p; - - if((p=(struct js_msg_area_priv*)JS_GetPrivate(cx,obj))==NULL) - return; - - free(p); - JS_SetPrivate(cx,obj,NULL); -} - - static JSClass js_msg_area_class = { "MsgArea" /* name */ ,JSCLASS_HAS_PRIVATE /* flags */ -- GitLab