Skip to content

Commit 631e714

Browse files
authored
Merge pull request #280 from leeN/rooting_issues
Added Rooting to avoid GC Hazards
2 parents 8295fe8 + 0c77f38 commit 631e714

File tree

6 files changed

+22
-16
lines changed

6 files changed

+22
-16
lines changed

js/src/builtin/Array.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,8 @@ bool js::array_join(JSContext* cx, unsigned argc, Value* vp) {
13761376
}
13771377

13781378
// Step 8.
1379-
JSString* str = sb.finishString();
1379+
// Foxhound: We have to root the string here, as we introduce the TaintOperationFromContext call, which can trigger the GC.
1380+
JS::Rooted<JSString*> str(cx, sb.finishString());
13801381
if (!str) {
13811382
return false;
13821383
}

js/src/builtin/JSON.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2358,14 +2358,16 @@ bool json_stringify(JSContext* cx, unsigned argc, Value* vp) {
23582358
// needs to support returning undefined. So this is a little awkward
23592359
// for the API, because we want to support streaming writers.
23602360
if (!sb.empty()) {
2361-
JSString* str = sb.finishString();
2361+
// Foxhound: We have to root the string here, as we introduce the TaintOperationFromContext call, which can trigger the GC.
2362+
JS::Rooted<JSString*> str(cx, sb.finishString());
23622363
if (!str) {
23632364
return false;
23642365
}
23652366

23662367
// TaintFox: Add stringify operation to taint flows.
2367-
str->taint().extend(TaintOperationFromContext(cx, "JSON.stringify", true));
2368-
2368+
if(str->isTainted()) {
2369+
str->taint().extend(TaintOperationFromContext(cx, "JSON.stringify", true));
2370+
}
23692371
args.rval().setString(str);
23702372
} else {
23712373
args.rval().setUndefined();

js/src/builtin/String.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,8 @@ static bool str_escape(JSContext* cx, unsigned argc, Value* vp) {
526526
return true;
527527
}
528528

529-
JSString* res = newChars.toString(cx, newLength);
529+
// Foxhound: We have to root the string here, as we introduce the TaintOperationFromContext call, which can trigger the GC.
530+
JS::Rooted<JSString*> res(cx, newChars.toString(cx, newLength));
530531
if (!res) {
531532
return false;
532533
}
@@ -970,7 +971,7 @@ JSString* js::SubstringKernel(JSContext* cx, HandleString str, int32_t beginInt,
970971
uint32_t len = lengthInt;
971972
// TaintFox
972973
SafeStringTaint newTaint = str->taint().safeSubTaint(begin, begin + len);
973-
974+
974975
/*
975976
* Optimization for one level deep ropes.
976977
* This is common for the following pattern:
@@ -1969,7 +1970,8 @@ static bool str_normalize(JSContext* cx, unsigned argc, Value* vp) {
19691970
form = NormalizationForm::NFC;
19701971
} else {
19711972
// Step 4.
1972-
JSLinearString* formStr = ArgToLinearString(cx, args, 0);
1973+
// Foxhound: We have to root the string here, as we introduce the TaintOperationFromContext call, which can trigger the GC.
1974+
JS::Rooted<JSLinearString*> formStr(cx, ArgToLinearString(cx, args, 0));
19731975
if (!formStr) {
19741976
return false;
19751977
}
@@ -3311,8 +3313,8 @@ static JSLinearString* TrimString(JSContext* cx, JSString* str, bool trimStart,
33113313
TrimString(linear->twoByteChars(nogc), trimStart, trimEnd, length, &begin,
33123314
&end);
33133315
}
3314-
3315-
JSLinearString* result = NewDependentString(cx, linear, begin, end - begin);
3316+
// Foxhound: We have to root the string here, as we introduce the TaintOperationFromContext call, which can trigger the GC.
3317+
JS::Rooted<JSLinearString*> result(cx, NewDependentString(cx, linear, begin, end - begin));
33163318

33173319
// TaintFox: Add trim operation to current taint flow.
33183320
// the acutal trimming of taint ranges has been done in
@@ -4292,8 +4294,8 @@ static ArrayObject* CharSplitHelper(JSContext* cx, Handle<JSLinearString*> str,
42924294
splits->ensureDenseInitializedLength(0, resultlen);
42934295

42944296
for (size_t i = 0; i < resultlen; ++i) {
4295-
// TaintFox: code modified to avoid atoms.
4296-
JSString* sub = NewDependentString(cx, str, i, 1);
4297+
// TaintFox: code modified to avoid atoms, and added rooting because TaintLocationFromContext can trigger a GC.
4298+
JS::Rooted<JSString*> sub(cx, NewDependentString(cx, str, i, 1));
42974299
// was:
42984300
// JSString* sub = staticStrings.getUnitStringForElement(cx, str, i);
42994301
if (!sub) {

js/src/jit/VMFunctions.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,8 +1356,9 @@ JSString* StringReplace(JSContext* cx, HandleString string,
13561356
MOZ_ASSERT(string);
13571357
MOZ_ASSERT(pattern);
13581358
MOZ_ASSERT(repl);
1359-
// Foxhound: this will propagate the taint but not add the operation
1360-
JSString* str = str_replace_string_raw(cx, string, pattern, repl);
1359+
// Foxhound: this will propagate the taint but not add the operation.
1360+
// Foxhound: We have to root the string here, as we introduce the TaintOperationFromContext call, which can trigger the GC.
1361+
Rooted<JSString*> str(cx, str_replace_string_raw(cx, string, pattern, repl));
13611362
if (str && str->taint().hasTaint()) {
13621363
str->taint().extend(TaintOperationFromContext(cx, "replace", true, pattern, repl));
13631364
}

js/src/jsapi.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5014,7 +5014,7 @@ JS_ReportTaintSink(JSContext* cx, JS::HandleString str, const char* sink, JS::Ha
50145014
// slot of the current global object.
50155015
RootedFunction report(cx);
50165016

5017-
JSObject* global = cx->global();
5017+
JS::Rooted<JSObject*> global(cx, cx->global());
50185018

50195019
RootedValue slot(cx, JS::GetReservedSlot(global, TAINT_REPORT_FUNCTION_SLOT));
50205020
if (slot.isUndefined()) {

js/src/jstaint.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ void JS::WriteTaintToFile(JSContext* cx, JSString* str, HandleValue location) {
417417

418418
char suffix_path[2048] = {0};
419419
SprintfLiteral(suffix_path, "%s.%d.%u.json", filename, getpid(), counter++);
420-
420+
421421
Fprinter output;
422422
if (!output.init(suffix_path)) {
423423
SEprinter p;
@@ -504,7 +504,7 @@ void JS::PrintJsonTaint(JSContext* cx, JSString* str, HandleValue location, js::
504504

505505
// Dump additional information from the taintreport
506506
if (location.isObject()) {
507-
JSObject* obj = ToObject(cx, location);
507+
JS::Rooted<JSObject*> obj(cx, ToObject(cx, location));
508508
PrintJsonObject(cx, obj, json);
509509
}
510510

0 commit comments

Comments
 (0)