Bug 505838 JS_GetStringBytes(JS_ValueToString(...)..) is a bad pattern

r=jorendorff
This commit is contained in:
timeless@mozdev.org 2009-08-12 11:49:53 +02:00
Родитель 2f8517133e
Коммит 20bb7612d5
2 изменённых файлов: 117 добавлений и 52 удалений

Просмотреть файл

@ -1484,7 +1484,11 @@ file_copyTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
fileInitiallyOpen = file->isOpen;
JSFILE_CHECK_READ;
dest = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
JSString *str = JS_ValueToString(cx, argv[0]);
if (!str)
goto out;
dest = JS_GetStringBytes(str);
/* make sure we are not reading a file open for writing */
if (file->isOpen && !js_canRead(cx, file)) {
@ -1573,7 +1577,11 @@ file_renameTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
JSFILE_CHECK_NATIVE("renameTo");
JSFILE_CHECK_CLOSED("renameTo");
dest = RESOLVE_PATH(cx, JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
JSString *str = JS_ValueToString(cx, argv[0]);
if (!str)
goto out;
dest = RESOLVE_PATH(cx, JS_GetStringBytes(str));
if (PR_Rename(file->path, dest)==PR_SUCCESS){
/* copy the new filename */
@ -2024,7 +2032,11 @@ file_mkdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
else
goto out;
}else{
char *dirName = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
JSString *str = JS_ValueToString(cx, argv[0]);
if (!str)
goto out;
char *dirName = JS_GetStringBytes(str);
char *fullName;
fullName = js_combinePath(cx, file->path, dirName);
@ -2670,7 +2682,11 @@ file_currentDirSetter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
JSObject *rhsObject;
char *path;
path = JS_GetStringBytes(JS_ValueToString(cx, *vp));
JSString *str = JS_ValueToString(cx, *vp);
if (!str)
return JS_FALSE;
path = JS_GetStringBytes(str);
rhsObject = js_NewFileObject(cx, path);
if (!rhsObject)
return JS_FALSE;

Просмотреть файл

@ -207,6 +207,33 @@ JS_EXTERN_API(void) add_history(char *line);
JS_END_EXTERN_C
#endif
class ToString {
public:
ToString(JSContext *aCx, jsval v, JSBool aThrow = JS_FALSE)
: cx(aCx)
, mThrow(aThrow)
{
mStr = JS_ValueToString(cx, v);
if (!aThrow && !mStr && JS_IsExceptionPending(cx)) {
if (!JS_ReportPendingException(cx))
JS_ClearPendingException(cx);
}
JS_AddNamedRoot(cx, &mStr, "Value ToString helper");
}
~ToString() {
JS_RemoveRoot(cx, &mStr);
}
JSBool threw() { return !mStr; }
jsval getJSVal() { return STRING_TO_JSVAL(mStr); }
const char *getBytes() {
return mStr ? JS_GetStringBytes(mStr) : "(error converting value)";
}
private:
JSContext *cx;
JSString *mStr;
JSBool mThrow;
};
static char *
GetLine(FILE *file, const char * prompt)
{
@ -1608,7 +1635,15 @@ SrcNotes(JSContext *cx, JSScript *script)
JS_GET_SCRIPT_OBJECT(script, index, obj);
fun = (JSFunction *) JS_GetPrivate(cx, obj);
str = JS_DecompileFunction(cx, fun, JS_DONT_PRETTY_PRINT);
bytes = str ? JS_GetStringBytes(str) : "N/A";
if (str) {
bytes = JS_GetStringBytes(str);
} else {
if (JS_IsExceptionPending(cx)) {
if (!JS_ReportPendingException(cx))
JS_ClearPendingException(cx);
}
bytes = "N/A";
}
fprintf(gOutFile, " function %u (%s)", index, bytes);
break;
}
@ -2205,7 +2240,7 @@ ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JSBool ok;
if (!JS_AddArgumentFormatter(cx, "ZZ", ZZ_formatter))
return JS_FALSE;;
return JS_FALSE;
ok = JS_ConvertArguments(cx, argc, argv, "b/ciujdIsSWofvZZ*",
&b, &c, &i, &u, &j, &d, &I, &s, &str, &w, &obj2,
&fun, &v, &re, &im);
@ -2215,13 +2250,26 @@ ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
fprintf(gOutFile,
"b %u, c %x (%c), i %ld, u %lu, j %ld\n",
b, c, (char)c, i, u, j);
ToString obj2string(cx, obj2);
ToString valueString(cx, v);
JSString *tmpstr = JS_DecompileFunction(cx, fun, 4);
const char *func;
if (tmpstr) {
func = JS_GetStringBytes(tmpstr);
} else {
if (JS_IsExceptionPending(cx)) {
if (!JS_ReportPendingException(cx))
JS_ClearPendingException(cx);
}
func = "error decompiling fun";
}
fprintf(gOutFile,
"d %g, I %g, s %s, S %s, W %s, obj %s, fun %s\n"
"v %s, re %g, im %g\n",
d, I, s, str ? JS_GetStringBytes(str) : "", EscapeWideString(w),
JS_GetStringBytes(JS_ValueToString(cx, OBJECT_TO_JSVAL(obj2))),
fun ? JS_GetStringBytes(JS_DecompileFunction(cx, fun, 4)) : "",
JS_GetStringBytes(JS_ValueToString(cx, v)), re, im);
obj2string.getBytes(),
fun ? func : "",
valueString.getBytes(), re, im);
return JS_TRUE;
}
#endif
@ -4019,57 +4067,58 @@ static JSBool its_enum_fail;/* whether to fail when enumerating it */
static JSBool
its_addProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
if (its_noisy) {
fprintf(gOutFile, "adding its property %s,",
JS_GetStringBytes(JS_ValueToString(cx, id)));
fprintf(gOutFile, " initial value %s\n",
JS_GetStringBytes(JS_ValueToString(cx, *vp)));
}
if (!its_noisy)
return JS_TRUE;
ToString idString(cx, id);
fprintf(gOutFile, "adding its property %s,", idString.getBytes());
ToString valueString(cx, *vp);
fprintf(gOutFile, " initial value %s\n", valueString.getBytes());
return JS_TRUE;
}
static JSBool
its_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
if (its_noisy) {
fprintf(gOutFile, "deleting its property %s,",
JS_GetStringBytes(JS_ValueToString(cx, id)));
fprintf(gOutFile, " current value %s\n",
JS_GetStringBytes(JS_ValueToString(cx, *vp)));
}
if (!its_noisy)
return JS_TRUE;
ToString idString(cx, id);
fprintf(gOutFile, "deleting its property %s,", idString.getBytes());
ToString valueString(cx, *vp);
fprintf(gOutFile, " initial value %s\n", valueString.getBytes());
return JS_TRUE;
}
static JSBool
its_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
if (its_noisy) {
fprintf(gOutFile, "getting its property %s,",
JS_GetStringBytes(JS_ValueToString(cx, id)));
fprintf(gOutFile, " current value %s\n",
JS_GetStringBytes(JS_ValueToString(cx, *vp)));
}
if (!its_noisy)
return JS_TRUE;
ToString idString(cx, id);
fprintf(gOutFile, "getting its property %s,", idString.getBytes());
ToString valueString(cx, *vp);
fprintf(gOutFile, " initial value %s\n", valueString.getBytes());
return JS_TRUE;
}
static JSBool
its_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
char *str;
ToString idString(cx, id);
if (its_noisy) {
fprintf(gOutFile, "setting its property %s,",
JS_GetStringBytes(JS_ValueToString(cx, id)));
fprintf(gOutFile, " new value %s\n",
JS_GetStringBytes(JS_ValueToString(cx, *vp)));
fprintf(gOutFile, "setting its property %s,", idString.getBytes());
ToString valueString(cx, *vp);
fprintf(gOutFile, " new value %s\n", valueString.getBytes());
}
if (!JSVAL_IS_STRING(id))
return JS_TRUE;
str = JS_GetStringBytes(JSVAL_TO_STRING(id));
if (!strcmp(str, "noisy"))
if (!strcmp(idString.getBytes(), "noisy"))
JS_ValueToBoolean(cx, *vp, &its_noisy);
else if (!strcmp(str, "enum_fail"))
else if (!strcmp(idString.getBytes(), "enum_fail"))
JS_ValueToBoolean(cx, *vp, &its_enum_fail);
return JS_TRUE;
@ -4127,8 +4176,9 @@ its_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
JSObject **objp)
{
if (its_noisy) {
ToString idString(cx, id);
fprintf(gOutFile, "resolving its property %s, flags {%s,%s,%s}\n",
JS_GetStringBytes(JS_ValueToString(cx, id)),
idString.getBytes(),
(flags & JSRESOLVE_QUALIFIED) ? "qualified" : "",
(flags & JSRESOLVE_ASSIGNING) ? "assigning" : "",
(flags & JSRESOLVE_DETECTING) ? "detecting" : "");
@ -4405,19 +4455,17 @@ env_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
/* XXX porting may be easy, but these don't seem to supply setenv by default */
#if !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS
JSString *idstr, *valstr;
const char *name, *value;
int rv;
idstr = JS_ValueToString(cx, id);
valstr = JS_ValueToString(cx, *vp);
if (!idstr || !valstr)
ToString idstr(cx, id, JS_TRUE);
if (idstr.threw())
return JS_FALSE;
ToString valstr(cx, *vp, JS_TRUE);
if (valstr.threw())
return JS_FALSE;
name = JS_GetStringBytes(idstr);
value = JS_GetStringBytes(valstr);
#if defined XP_WIN || defined HPUX || defined OSF1 || defined IRIX
{
char *waste = JS_smprintf("%s=%s", name, value);
char *waste = JS_smprintf("%s=%s", idstr.getBytes(), valstr.getBytes());
if (!waste) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
@ -4431,17 +4479,17 @@ env_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
* that will crash if you pass it an auto char array (so it must place
* its argument directly in the char *environ[] array).
*/
free(waste);
JS_smprintf_free(waste);
#endif
}
#else
rv = setenv(name, value, 1);
rv = setenv(idstr.getBytes(), valstr.getBytes(), 1);
#endif
if (rv < 0) {
JS_ReportError(cx, "can't set envariable %s to %s", name, value);
JS_ReportError(cx, "can't set env variable %s to %s", idstr.getBytes(), valstr.getBytes());
return JS_FALSE;
}
*vp = STRING_TO_JSVAL(valstr);
*vp = valstr.getJSVal();
#endif /* !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS */
return JS_TRUE;
}
@ -4482,16 +4530,17 @@ static JSBool
env_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
JSObject **objp)
{
JSString *idstr, *valstr;
JSString *valstr;
const char *name, *value;
if (flags & JSRESOLVE_ASSIGNING)
return JS_TRUE;
idstr = JS_ValueToString(cx, id);
if (!idstr)
ToString idstr(cx, id, JS_TRUE);
if (idstr.threw())
return JS_FALSE;
name = JS_GetStringBytes(idstr);
name = idstr.getBytes();
value = getenv(name);
if (value) {
valstr = JS_NewStringCopyZ(cx, value);