diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 08b6e16702c7a..249cd5494f82e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,6 +18,13 @@ jobs: # This workflow contains a single job called "build" build: + strategy: + matrix: + taintspew: [ 'false', 'true' ] + jitspew: [ 'false', 'true' ] + + name: 'SpiderMonkey (taintspew: ${{ matrix.taintspew }}, jitspew: ${{ matrix.jitspew }})' + # The type of runner that the job will run on runs-on: ubuntu-latest @@ -52,6 +59,14 @@ jobs: cd build cp taintfox_mozconfig_spidermonkey .mozconfig + - name: Enable JitSpew + if: ${{ matrix.jitspew == 'true' }} + run: echo "ac_add_options --enable-jitspew" >> .mozconfig + + - name: Enable TaintSpew + if: ${{ matrix.taintspew == 'true' }} + run: echo "ac_add_options --enable-taintspew" >> .mozconfig + # Build - name: Build run: | @@ -71,7 +86,7 @@ jobs: - name: Upload Report uses: actions/upload-artifact@v4 # upload test results - if: success() || failure() # run this step even if previous step failed + if: ${{ matrix.taintspew == 'false' && matrix.jitspew == 'false' && (success() || failure()) }} # run this step even if previous step failed with: name: test-results path: build/jstest_output.xml diff --git a/js/moz.configure b/js/moz.configure index b52afe7c75230..771bec5525c2e 100644 --- a/js/moz.configure +++ b/js/moz.configure @@ -480,6 +480,13 @@ def ion_perf(value, target): set_define("JS_ION_PERF", ion_perf) +option( + "--enable-taintspew", + help="Enable writing taint flow information to file" +) + +set_define("JS_TAINTSPEW", depends_if("--enable-taintspew")(lambda _: True)) +set_config("JS_TAINTSPEW", depends_if("--enable-taintspew")(lambda _: True)) option( "--enable-jitspew", @@ -494,16 +501,6 @@ set_config("JS_JITSPEW", depends_if("--enable-jitspew")(lambda _: True)) set_define("JS_STRUCTURED_SPEW", depends_if("--enable-jitspew")(lambda _: True)) set_config("JS_STRUCTURED_SPEW", depends_if("--enable-jitspew")(lambda _: True)) -option( - "--enable-taintspew", - default=False, - help="{Enable|Disable} the taint flow spew variable", -) - -# Also enable the structured spewer for tainting -set_define("JS_STRUCTURED_SPEW", depends_if("--enable-taintspew")(lambda _: True)) -set_config("JS_STRUCTURED_SPEW", depends_if("--enable-taintspew")(lambda _: True)) - @depends("--enable-jit", "--enable-jitspew", simulator, target, moz_debug) def jit_disasm_arm(jit_enabled, spew, simulator, target, debug): if not jit_enabled: diff --git a/js/public/Id.h b/js/public/Id.h index 087f9e61c9a79..b82d9f6bf3f1a 100644 --- a/js/public/Id.h +++ b/js/public/Id.h @@ -209,7 +209,7 @@ class PropertyKey { return reinterpret_cast(toString()); } -#if defined(DEBUG) || defined(JS_JITSPEW) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_TAINTSPEW) void dump() const; void dump(js::GenericPrinter& out) const; void dump(js::JSONPrinter& json) const; diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 8e02208c3ecf6..63a16a08a58a8 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -5025,19 +5025,30 @@ JS_ReportTaintSink(JSContext* cx, JS::HandleString str, const char* sink, JS::Ha " pl = parent.location.href;\n" " } catch (e) {\n" " pl = 'different origin';\n" - " }\n" + " }\n" + " var timestamp = -1;\n" + " try {\n" + " timestamp = Date.now();\n" + " } catch (e) {\n" + " timestamp = -2;\n" + " }\n" " var e = document.createEvent('CustomEvent');\n" - " e.initCustomEvent('__taintreport', true, false, {\n" + " var info = {\n" " subframe: t !== window,\n" " loc: location.href,\n" " parentloc: pl,\n" " referrer: document.referrer,\n" " str: str,\n" " sink: sink,\n" - " stack: stack\n" - " });\n" + " stack: stack,\n" + " timestamp: timestamp\n" + " }\n" + " e.initCustomEvent('__taintreport', true, false, info);\n" " t.dispatchEvent(e);\n" - "}"; + " return info;\n" + "} else {\n" + " return undefined;\n" + "}\n"; CompileOptions options(cx); options.setFile("taint_reporting.js"); @@ -5069,11 +5080,19 @@ JS_ReportTaintSink(JSContext* cx, JS::HandleString str, const char* sink, JS::Ha arguments[2].setUndefined(); } - RootedValue rval(cx); - JS_CallFunction(cx, nullptr, report, arguments, &rval); + RootedValue retVal(cx); + JS_CallFunction(cx, nullptr, report, arguments, &retVal); MOZ_ASSERT(!cx->isExceptionPending()); - MaybeSpewStringTaint(cx, str); +// Enable this with ac_add_options --enable-taintspew +#if defined(JS_TAINTSPEW) + WriteTaintToFile(cx, str, retVal); +#endif + +// Enable with ac_add_options --enable-jitspew +#if defined (JS_JITSPEW) + MaybeSpewStringTaint(cx, str, retval); +#endif } JS_PUBLIC_API bool JS::FinishIncrementalEncoding(JSContext* cx, diff --git a/js/src/jstaint.cpp b/js/src/jstaint.cpp index d28f707cfbf5f..05348f15a2757 100644 --- a/js/src/jstaint.cpp +++ b/js/src/jstaint.cpp @@ -3,6 +3,8 @@ */ #include "jstaint.h" +#include "mozilla/Sprintf.h" + #include #include #include @@ -16,10 +18,12 @@ #include "js/CharacterEncoding.h" #include "js/ErrorReport.h" #include "js/UniquePtr.h" +#include "util/GetPidProvider.h" // getpid() #include "vm/FrameIter.h" #include "vm/JSAtomUtils.h" #include "vm/JSContext.h" #include "vm/JSFunction.h" +#include "vm/JSONPrinter.h" #include "vm/StringType.h" using namespace JS; @@ -372,60 +376,183 @@ void JS::MarkTaintedFunctionArguments(JSContext* cx, JSFunction* function, const } } -void JS::MaybeSpewStringTaint(JSContext* cx, JSString* str) { -#ifdef JS_STRUCTURED_SPEW - if (!str || !str->taint()) { +#if defined(JS_JITSPEW) +void JS::MaybeSpewStringTaint(JSContext* cx, JSString* str, HandleValue location) { + // Use the standard spew framework to create a single spew file + AutoStructuredSpewer spew(cx, SpewChannel::TaintFlowSpewer, cx->currentScript()); + if (spew) { + // Dump the string and taint flow itself + PrintJsonTaint(cx, str, location, *spew); + spew->flush(); + } +} +#endif + +#if defined(JS_TAINTSPEW) + +// Choose a sensible default directory. +// +// The preference here is to use the current working directory, +// except on Android. +# ifndef DEFAULT_TAINT_DIRECTORY +# if defined(_WIN32) +# define DEFAULT_TAINT_DIRECTORY "." +# elif defined(__ANDROID__) +# define DEFAULT_TAINT_DIRECTORY "/sdcard/Download" +# else +# define DEFAULT_TAINT_DIRECTORY "." +# endif +# endif + +void JS::WriteTaintToFile(JSContext* cx, JSString* str, HandleValue location) { + // Don't use the standard spewer here, as we can't easily set the filename + static int counter = 0; + + char filename[2048] = {0}; + if (getenv("TAINT_FILE")) { + SprintfLiteral(filename, "%s", getenv("TAINT_FILE")); + } else { + SprintfLiteral(filename, "%s/taint_output", DEFAULT_TAINT_DIRECTORY); + } + + char suffix_path[2048] = {0}; + SprintfLiteral(suffix_path, "%s.%d.%u.json", filename, getpid(), counter++); + + Fprinter output; + if (!output.init(suffix_path)) { + SEprinter p; + p.put("Error opening taint output file: "); + p.put(suffix_path); + p.put("\n"); + p.flush(); return; } - AutoStructuredSpewer spew(cx, SpewChannel::TaintFlowSpewer, cx->currentScript()); - if (spew) { - JSLinearString* linear = str->ensureLinear(cx); - if (linear) { - spew->property("str", linear); - } else { - spew->property("str", "Non-linear String!"); - } + JSONPrinter json(output); + json.beginObject(); + PrintJsonTaint(cx, str, location, json); + json.endObject(); - spew->beginListProperty("taint"); - for (const TaintRange& range : str->taint()) { - spew->beginObject(); - spew->property("begin", range.begin()); - spew->property("end", range.end()); - - spew->beginListProperty("flow"); - for (TaintNode& node : range.flow()) { - const TaintOperation& op = node.operation(); - spew->beginObject(); - spew->property("operation", op.name()); - spew->boolProperty("builtin", op.is_native()); - spew->boolProperty("source", op.isSource()); - - const TaintLocation& loc = op.location(); - spew->beginObjectProperty("location"); - spew->property("filename", loc.filename().c_str(), loc.filename().size()); - spew->property("line", loc.line()); - spew->property("pos", loc.pos()); - spew->property("scriptline", loc.scriptStartLine()); - spew->property("scripthash", JS::convertDigestToHexString(loc.scriptHash()).c_str()); - spew->endObject(); // Location - - spew->beginListProperty("arguments"); - for (auto& arg : op.arguments()) { - spew->string(arg.c_str(), arg.size()); + output.flush(); + output.finish(); +} +#endif + +#if defined(JS_JITSPEW) || defined(JS_TAINTSPEW) +void JS::PrintJsonObject(JSContext* cx, JSObject* obj, js::JSONPrinter& json) { + // This code is adapted from JSObject::dumpFields, which was too verbose for our needs + if (obj && obj->is()) { + const auto* nobj = &obj->as(); + + if (PropMap* map = nobj->shape()->propMap()) { + Vector maps; + while (true) { + if (!maps.append(map)) { + json.property("error", "*oom in JSObject::dumpFields*"); + break; + } + if (!map->hasPrevious()) { + break; } - spew->endList(); + map = map->asLinked()->previous(); + } - spew->endObject(); // Operation + for (size_t i = maps.length(); i > 0; i--) { + size_t index = i - 1; + PropMap* map = maps[index]; + uint32_t len = (index == 0) ? obj->shape()->asNative().propMapLength() + : PropMap::Capacity; + for (uint32_t j = 0; j < len; j++) { + if (!map->hasKey(j)) { + MOZ_ASSERT(map->isDictionary()); + continue; + } + + JS::UniqueChars propChars = map->getPropertyNameAt(j); + if (!propChars) { + json.property("error", "*oom in PropMap::getPropertyNameAt*"); + continue; + } + + PropertyInfoWithKey prop = map->getPropertyInfoWithKey(j); + if (prop.isDataProperty()) { + const Value& val = nobj->getSlot(prop.slot()); + if (val.isDouble()) { + double d = val.toDouble(); + // JSONPrinter::floatProperty appears to ignore the precision argument + json.floatProperty(propChars.get(), d, 10); + } else if (val.isString()) { + JSString *str = val.toString(); + JSLinearString* linear = str->ensureLinear(cx); + if (linear) { + json.property(propChars.get(), linear); + } else { + json.property(propChars.get(), "Non-linear String!"); + } + } + } + } } - spew->endList(); // flow - spew->endObject(); // range } - spew->endList(); + } +} +void JS::PrintJsonTaint(JSContext* cx, JSString* str, HandleValue location, js::JSONPrinter& json) { + if (!str || !str->taint()) { + return; } -#endif + + // Dump additional information from the taintreport + if (location.isObject()) { + JSObject* obj = ToObject(cx, location); + PrintJsonObject(cx, obj, json); + } + + JSLinearString* linear = str->ensureLinear(cx); + if (linear) { + json.property("string", linear); + } else { + json.property("string", "Non-linear String!"); + } + + json.beginListProperty("taint"); + for (const TaintRange& range : str->taint()) { + json.beginObject(); + json.property("begin", range.begin()); + json.property("end", range.end()); + + json.beginListProperty("flow"); + for (TaintNode& node : range.flow()) { + const TaintOperation& op = node.operation(); + json.beginObject(); + json.property("operation", op.name()); + json.boolProperty("builtin", op.is_native()); + json.boolProperty("source", op.isSource()); + + const TaintLocation& loc = op.location(); + json.beginObjectProperty("location"); + json.property("filename", loc.filename().c_str(), loc.filename().size()); + json.property("line", loc.line()); + json.property("pos", loc.pos()); + json.property("scriptline", loc.scriptStartLine()); + json.property("scripthash", JS::convertDigestToHexString(loc.scriptHash()).c_str()); + json.endObject(); // Location + + json.beginListProperty("arguments"); + for (auto& arg : op.arguments()) { + json.string(arg.c_str(), arg.size()); + } + json.endList(); + + json.endObject(); // Operation + } + json.endList(); // flow + json.endObject(); // range + } + json.endList(); + } +#endif void JS::MaybeSpewMessage(JSContext* cx, JSString* str) { // First print message to stderr @@ -449,7 +576,7 @@ void JS::MaybeSpewMessage(JSContext* cx, JSString* str) { #endif } -// Print a message to stdout. +// Print a warning message to stdout and the JS console void JS::TaintFoxReport(JSContext* cx, const char* msg) { JS_ReportWarningUTF8(cx, "%s", msg); diff --git a/js/src/jstaint.h b/js/src/jstaint.h index b604c7530d486..0bc5bc7455467 100644 --- a/js/src/jstaint.h +++ b/js/src/jstaint.h @@ -85,9 +85,34 @@ TaintOperation TaintOperationFromContext(JSContext* cx, const char* name, bool i // This is mainly useful for tracing tainted arguments through the code. void MarkTaintedFunctionArguments(JSContext* cx, JSFunction* function, const JS::CallArgs& args); -// Write the taint report to file -void MaybeSpewStringTaint(JSContext* cx, JSString* str); -// Write a message to the file +// Write the taint information to a StructuredSpewer +// To enable this, set the +// ac_add_options --enable-jitspew +// flag in the .mozconfig build file +// and the environment variable +// SPEW=TaintFlowSpewer,AtStartup +#ifdef JS_JITSPEW +void MaybeSpewStringTaint(JSContext* cx, JSString* str, HandleValue location); +#endif + +// Write taint information from a string to file +// This can be set by the TAINT_FILE environment variable or defaults to taint_output in the current directory +// One file is produced per taint report call +// Writing to file is enable by the compilation flag +// ac_add_options --enable-taintspew +#ifdef JS_TAINTSPEW +void WriteTaintToFile(JSContext* cx, JSString* str, HandleValue location); +#endif + +#if defined(JS_JITSPEW) || defined(JS_TAINTSPEW) +// Write a string and its taint information to JSON +void PrintJsonTaint(JSContext* cx, JSString* str, HandleValue location, js::JSONPrinter& json); + +// Write a simple version of an object to JSON +void PrintJsonObject(JSContext* cx, JSObject* obj, js::JSONPrinter& json); +#endif + +// Write a message to stderr and the spewer if enabled void MaybeSpewMessage(JSContext* cx, JSString* str); // Print a message to stdout. diff --git a/js/src/vm/Id.cpp b/js/src/vm/Id.cpp index a3d46f178697d..29d9a7948c656 100644 --- a/js/src/vm/Id.cpp +++ b/js/src/vm/Id.cpp @@ -51,7 +51,7 @@ bool JS::PropertyKey::isWellKnownSymbol(JS::SymbolCode code) const { return JS::PropertyKey::isNonIntAtom(&str->asAtom()); } -#if defined(DEBUG) || defined(JS_JITSPEW) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_TAINTSPEW) void JS::PropertyKey::dump() const { js::Fprinter out(stderr); @@ -115,4 +115,4 @@ void JS::PropertyKey::dumpStringContent(js::GenericPrinter& out) const { } } -#endif /* defined(DEBUG) || defined(JS_JITSPEW) */ +#endif /* defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_TAINTSPEW) */ diff --git a/js/src/vm/JSONPrinter.h b/js/src/vm/JSONPrinter.h index 06a16e4c2b662..16346bd797832 100644 --- a/js/src/vm/JSONPrinter.h +++ b/js/src/vm/JSONPrinter.h @@ -94,6 +94,9 @@ class JSONPrinter { // to its saw-OOM state. void outOfMemory() { out_.reportOutOfMemory(); } + // Flush the output + void flush() { out_.flush(); } + protected: void beginInline(); void endInline(); diff --git a/js/src/vm/PropMap.cpp b/js/src/vm/PropMap.cpp index 8c1acaeea8815..c051da1ec6d8d 100644 --- a/js/src/vm/PropMap.cpp +++ b/js/src/vm/PropMap.cpp @@ -6,6 +6,8 @@ #include "vm/PropMap-inl.h" +#include "mozilla/Sprintf.h" + #include "gc/HashUtil.h" #include "js/GCVector.h" #include "js/Printer.h" // js::GenericPrinter, js::Fprinter @@ -1030,7 +1032,7 @@ bool LinkedPropMap::createTable(JSContext* cx) { return true; } -#if defined(DEBUG) || defined(JS_JITSPEW) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_TAINTSPEW) void PropMap::dump() const { Fprinter out(stderr); dump(out); @@ -1243,7 +1245,7 @@ JS::UniqueChars PropMap::getPropertyNameAt(uint32_t index) const { return sp.release(); } -#endif // defined(DEBUG) || defined(JS_JITSPEW) +#endif // defined(DEBUG) || defined(JS_JITSPEW)|| defined(JS_TAINTSPEW) #ifdef DEBUG void PropMap::checkConsistency(NativeObject* obj) const { diff --git a/js/src/vm/PropMap.h b/js/src/vm/PropMap.h index 17792cdfe7c61..86b4b1c7abe99 100644 --- a/js/src/vm/PropMap.h +++ b/js/src/vm/PropMap.h @@ -513,7 +513,7 @@ class PropMap : public gc::TenuredCellWithFlags { uint32_t approximateEntryCount() const; -#if defined(DEBUG) || defined(JS_JITSPEW) +#if defined(DEBUG) || defined(JS_JITSPEW)|| defined(JS_TAINTSPEW) void dump() const; void dump(js::GenericPrinter& out) const; void dump(js::JSONPrinter& json) const; @@ -737,7 +737,7 @@ class SharedPropMap : public PropMap { Handle map, uint32_t length); -#if defined(DEBUG) || defined(JS_JITSPEW) +#if defined(DEBUG) || defined(JS_JITSPEW)|| defined(JS_TAINTSPEW) void dumpOwnFields(js::JSONPrinter& json) const; #endif }; @@ -850,7 +850,7 @@ class LinkedPropMap final : public PropMap { return data_.propInfos[index]; } -#if defined(DEBUG) || defined(JS_JITSPEW) +#if defined(DEBUG) || defined(JS_JITSPEW)|| defined(JS_TAINTSPEW) void dumpOwnFields(js::JSONPrinter& json) const; #endif }; @@ -1058,7 +1058,7 @@ class DictionaryPropMap final : public PropMap { offsetof(LinkedPropMap, data_)); } -#if defined(DEBUG) || defined(JS_JITSPEW) +#if defined(DEBUG) || defined(JS_JITSPEW)|| defined(JS_TAINTSPEW) void dumpOwnFields(js::JSONPrinter& json) const; #endif }; diff --git a/js/src/vm/StringType.cpp b/js/src/vm/StringType.cpp index 3e77db3654969..eb0cd1433ed89 100644 --- a/js/src/vm/StringType.cpp +++ b/js/src/vm/StringType.cpp @@ -271,7 +271,7 @@ mozilla::Maybe> JSString::encodeUTF8Partial( return mozilla::Some(std::make_tuple(totalRead, totalWritten)); } -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) template /*static */ void JSString::dumpCharsNoQuote(const CharT* s, size_t n, @@ -742,7 +742,7 @@ bool JSRope::hash(uint32_t* outHash) const { return true; } -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void JSRope::dumpOwnRepresentationFields(js::JSONPrinter& json) const { json.beginObjectProperty("leftChild"); leftChild()->dumpRepresentationFields(json); @@ -1214,7 +1214,7 @@ template JSString* js::ConcatStrings(JSContext* cx, JSString* const& left, JSString* const& right, gc::Heap heap); -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void JSDependentString::dumpOwnRepresentationFields( js::JSONPrinter& json) const { json.property("baseOffset", baseOffset()); @@ -1662,7 +1662,7 @@ bool JS::SourceText::initMaybeBorrowed( return initImpl(fc, chars, length, taint, ownership); } -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void JSAtom::dump(js::GenericPrinter& out) { out.printf("JSAtom* (%p) = ", (void*)this); this->JSString::dump(out); @@ -2262,7 +2262,7 @@ template JSString* NewMaybeExternalString( } /* namespace js */ -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void JSExtensibleString::dumpOwnRepresentationFields( js::JSONPrinter& json) const { json.property("capacity", capacity()); @@ -2660,22 +2660,22 @@ void JSString::sweepAfterMinorGC(JS::GCContext* gcx, JSString* str) { } if (IsInsideNursery(str) && !IsForwarded(str) && str->isTainted()) { -#ifdef TAINT_DEBUG_NURSERY +#ifdef JS_TAINTSPEW_NURSERY printf("-----------------------------------------------------\n"); printf("Str: %p\n", str); str->dumpRepresentationHeader(); #endif auto* ptr = reinterpret_cast(str) + offsetOfTaint(); -#ifdef TAINT_DEBUG_NURSERY +#ifdef JS_TAINTSPEW_NURSERY printf("Ptr: %p\n", ptr); printf("Before: %p\n", *reinterpret_cast(ptr)); #endif str->clearTaint(); -#ifdef TAINT_DEBUG_NURSERY +#ifdef JS_TAINTSPEW_NURSERY printf("After Clear: %p\n", *reinterpret_cast(ptr)); #endif AlwaysPoison(ptr, 0x7A, sizeof(StringTaint), MemCheckKind::MakeNoAccess); -#ifdef TAINT_DEBUG_NURSERY +#ifdef JS_TAINTSPEW_NURSERY printf("After Poison: %p\n", *reinterpret_cast(ptr)); printf("-----------------------------------------------------\n"); #endif diff --git a/js/src/vm/StringType.h b/js/src/vm/StringType.h index 3840061d4926e..422657c3212c8 100644 --- a/js/src/vm/StringType.h +++ b/js/src/vm/StringType.h @@ -33,7 +33,6 @@ #include "js/UniquePtr.h" #include "util/Text.h" -#define TAINT_DEBUG class JSDependentString; class JSExtensibleString; @@ -815,7 +814,7 @@ class JSString : public js::gc::CellWithLengthAndFlags { return kind; } -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void dump() const; void dump(js::GenericPrinter& out) const; void dump(js::JSONPrinter& json) const; @@ -964,7 +963,7 @@ class JSRope : public JSString { void traceChildren(JSTracer* trc); -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void dumpOwnRepresentationFields(js::JSONPrinter& json) const; #endif @@ -1152,7 +1151,7 @@ class JSLinearString : public JSString { inline void finalize(JS::GCContext* gcx); inline size_t allocSize() const; -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void dumpOwnRepresentationFields(js::JSONPrinter& json) const; #endif @@ -1203,7 +1202,7 @@ class JSDependentString : public JSLinearString { setNonInlineChars(chars + offset); } -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void dumpOwnRepresentationFields(js::JSONPrinter& json) const; #endif @@ -1232,7 +1231,7 @@ class JSExtensibleString : public JSLinearString { return d.s.u3.capacity; } -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void dumpOwnRepresentationFields(js::JSONPrinter& json) const; #endif }; @@ -1259,7 +1258,7 @@ class JSInlineString : public JSLinearString { template static bool lengthFits(size_t length); -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void dumpOwnRepresentationFields(js::JSONPrinter& json) const; #endif @@ -1405,7 +1404,7 @@ class JSExternalString : public JSLinearString { // kind. inline void finalize(JS::GCContext* gcx); -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void dumpOwnRepresentationFields(js::JSONPrinter& json) const; #endif }; @@ -1472,7 +1471,7 @@ class JSAtom : public JSLinearString { template static bool lengthFitsInline(size_t length); -#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(TAINT_DEBUG) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) || defined(JS_TAINTSPEW) void dump(js::GenericPrinter& out); void dump(); #endif diff --git a/js/src/vm/SymbolType.cpp b/js/src/vm/SymbolType.cpp index 6e08ccb52de3c..92ac85421227c 100644 --- a/js/src/vm/SymbolType.cpp +++ b/js/src/vm/SymbolType.cpp @@ -76,7 +76,7 @@ Symbol* Symbol::for_(JSContext* cx, HandleString description) { return sym; } -#if defined(DEBUG) || defined(JS_JITSPEW) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_TAINTSPEW) void Symbol::dump() const { js::Fprinter out(stderr); dump(out); @@ -177,7 +177,7 @@ void Symbol::dumpPropertyName(js::GenericPrinter& out) const { out.printf("", unsigned(code_)); } } -#endif // defined(DEBUG) || defined(JS_JITSPEW) +#endif // defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_TAINTSPEW) bool js::SymbolDescriptiveString(JSContext* cx, Symbol* sym, MutableHandleValue result) { diff --git a/js/src/vm/SymbolType.h b/js/src/vm/SymbolType.h index ccc87b7f6df05..c1a52ffc69bb1 100644 --- a/js/src/vm/SymbolType.h +++ b/js/src/vm/SymbolType.h @@ -100,7 +100,7 @@ class Symbol return mallocSizeOf(this); } -#if defined(DEBUG) || defined(JS_JITSPEW) +#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_TAINTSPEW) void dump() const; // Debugger-friendly stderr dump. void dump(js::GenericPrinter& out) const; void dump(js::JSONPrinter& json) const;