JS_GetStringBytes/Length tip

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

JS_GetStringBytes/Length tip

Rob Swindell
I've found myself doing the following operation in many (dozens) of my
native SpiderMonkey methods:

char* buf;

if((buf=JS_GetStringBytes(JS_ValueToString(cx, argv[n])))==NULL)
    return(JS_FALSE);

The problem with this is that JS_ValueToString() may return NULL, in which
case, JS_GetStringBytes() will crash (e.g. segfault/access violation).

So then I found myself doing the following operation instead:

JSString* str;
char* buf;

if((str=JS_ValueToString(cx, argv[n]))==NULL)
    return(JS_FALSE);

if((buf=JS_GetStringBytes(str))==NULL)
    return(JS_FALSE);

And then, if I want to support embedded nulls ('\0') in the string, I need
to do:

size_t len;

len=JS_GetStringLength(str);

Getting tired of typing (or copying and pasting) the above into many many
native functions, I instead created the following function to perform all 3
steps (safely) in one function call:

char*
js_ValueToStringBytes(JSContext* cx, jsval val, size_t* len)
{
 JSString* str;

 if((str=JS_ValueToString(cx, val))==NULL)
  return(NULL);

 if(len!=NULL)
  *len = JS_GetStringLength(str);

 return(JS_GetStringBytes(str));
}

Which allows me to replace the 3 separate function calls with one:

if((inbuf=js_ValueToStringBytes(cx, argv[n], &len))==NULL)
    return(JS_FALSE);

or:

if((inbuf=js_ValueToStringBytes(cx, argv[n], NULL))==NULL)    /* length not
needed, assumes ASCIIZ */
    return(JS_FALSE);

-Rob


_______________________________________________
mozilla-jseng mailing list
[hidden email]
http://mail.mozilla.org/listinfo/mozilla-jseng
Reply | Threaded
Open this post in threaded view
|

Re: JS_GetStringBytes/Length tip

Brendan Eich
Rob Swindell wrote:

> I've found myself doing the following operation in many (dozens) of my
> native SpiderMonkey methods:
>
> char* buf;
>
> if((buf=JS_GetStringBytes(JS_ValueToString(cx, argv[n])))==NULL)
>     return(JS_FALSE);
>
> The problem with this is that JS_ValueToString() may return NULL, in which
> case, JS_GetStringBytes() will crash (e.g. segfault/access violation).

Another tip:

JS_GetStringBytes never returns null (ancient API compatibility with the
days when it was a one-line accessor of str->bytes -- before Unicode,
SpiderMonkey stored ISO-Latin-1 in 8-bit chars).

/be
_______________________________________________
mozilla-jseng mailing list
[hidden email]
http://mail.mozilla.org/listinfo/mozilla-jseng
Reply | Threaded
Open this post in threaded view
|

Re: JS_GetStringBytes/Length tip

Rob Swindell-2
  To: Brendan Eich
  Re: Re: JS_GetStringBytes/Length tip
  By: Brendan Eich to Rob Swindell on Sun Oct 16 2005 05:22 pm

 > Rob Swindell wrote:
 > > I've found myself doing the following operation in many (dozens) of my
 > > native SpiderMonkey methods:
 > >
 > > char* buf;
 > >
 > > if((buf=JS_GetStringBytes(JS_ValueToString(cx, argv[n])))==NULL)
 > >     return(JS_FALSE);
 > >
 > > The problem with this is that JS_ValueToString() may return NULL, in which
 > > case, JS_GetStringBytes() will crash (e.g. segfault/access violation).
 >
 > Another tip:
 >
 > JS_GetStringBytes never returns null (ancient API compatibility with the
 > days when it was a one-line accessor of str->bytes -- before Unicode,
 > SpiderMonkey stored ISO-Latin-1 in 8-bit chars).

Yeah, I noticed that (return bytes ? bytes : "";) but figured safe coding is
better coding. :-)

                                                  digital man

Snapple "Real Fact" #105:
You will burn 7% more calories walking on hard dirt than pavement.
--- Synchronet 3.13b-Win32 NewsLink 1.83
 *  Vertrauen - Anaheim Hills, California - telnet://vert.synchro.net
_______________________________________________
mozilla-jseng mailing list
[hidden email]
http://mail.mozilla.org/listinfo/mozilla-jseng
Reply | Threaded
Open this post in threaded view
|

Re: JS_GetStringBytes/Length tip

Brendan Eich
Rob Swindell wrote:

>  > JS_GetStringBytes never returns null (ancient API compatibility with the
>  > days when it was a one-line accessor of str->bytes -- before Unicode,
>  > SpiderMonkey stored ISO-Latin-1 in 8-bit chars).
>
> Yeah, I noticed that (return bytes ? bytes : "";) but figured safe coding is
> better coding. :-)

There is no way JS_GetStringBytes can change, so there's no need to
test.  In general, if you see an API that does not take a JSContext *cx
first parameter, that API is infallible -- it can't throw an error as an
exception, or report out-of-memory, without cx.

/be
_______________________________________________
mozilla-jseng mailing list
[hidden email]
http://mail.mozilla.org/listinfo/mozilla-jseng
Reply | Threaded
Open this post in threaded view
|

Re: JS_GetStringBytes/Length tip

Rob Swindell-3
  To: Brendan Eich
  Re: Re: JS_GetStringBytes/Length tip
  By: Brendan Eich to netscape.public.mozilla.jseng on Mon Oct 17 2005 10:02 pm

 > Rob Swindell wrote:
 >
 > >  > JS_GetStringBytes never returns null (ancient API compatibility with th
 > >  > days when it was a one-line accessor of str->bytes -- before Unicode,
 > >  > SpiderMonkey stored ISO-Latin-1 in 8-bit chars).
 > >
 > > Yeah, I noticed that (return bytes ? bytes : "";) but figured safe coding
 > > better coding. :-)
 >
 > There is no way JS_GetStringBytes can change, so there's no need to
 > test.  In general, if you see an API that does not take a JSContext *cx
 > first parameter, that API is infallible -- it can't throw an error as an
 > exception, or report out-of-memory, without cx.

Okay, thanks. Good to know JS_GetStringBytes won't be changing (or returning
NULL at least).

                                                  digital man

Snapple "Real Fact" #142:
Hawaii is the only U.S. state never to report a temperature of zero degrees F or below.
--- Synchronet 3.13b-Win32 NewsLink 1.83
 *  Vertrauen - Anaheim Hills, California - telnet://vert.synchro.net
_______________________________________________
mozilla-jseng mailing list
[hidden email]
http://mail.mozilla.org/listinfo/mozilla-jseng