mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to b2g-inbound
This commit is contained in:
commit
9e58e35146
@ -4723,7 +4723,7 @@
|
||||
|
||||
<method name="_mouseenter">
|
||||
<body><![CDATA[
|
||||
if (this.closing)
|
||||
if (this.hidden || this.closing)
|
||||
return;
|
||||
|
||||
let tabContainer = this.parentNode;
|
||||
|
@ -60,7 +60,7 @@ function expectNoObserverCalled() {
|
||||
if (gObservedTopics[topic])
|
||||
is(gObservedTopics[topic], 0, topic + " notification unexpected");
|
||||
}
|
||||
gObservedTopics = {}
|
||||
gObservedTopics = {};
|
||||
}
|
||||
|
||||
function promiseMessage(aMessage, aAction) {
|
||||
@ -816,7 +816,7 @@ function test() {
|
||||
finish();
|
||||
});
|
||||
}, true);
|
||||
let rootDir = getRootDirectory(gTestPath)
|
||||
let rootDir = getRootDirectory(gTestPath);
|
||||
rootDir = rootDir.replace("chrome://mochitests/content/",
|
||||
"https://example.com/");
|
||||
content.location = rootDir + "get_user_media.html";
|
||||
|
@ -4,6 +4,19 @@
|
||||
<body>
|
||||
<div id="message"></div>
|
||||
<script>
|
||||
// Specifies whether we are using fake streams to run this automation
|
||||
var useFakeStreams = true;
|
||||
try {
|
||||
var audioDevice = SpecialPowers.getCharPref("media.audio_loopback_dev");
|
||||
var videoDevice = SpecialPowers.getCharPref("media.video_loopback_dev");
|
||||
dump("TEST DEVICES: Using media devices:\n");
|
||||
dump("audio: " + audioDevice + "\nvideo: " + videoDevice + "\n");
|
||||
useFakeStreams = false;
|
||||
} catch (e) {
|
||||
dump("TEST DEVICES: No test devices found (in media.{audio,video}_loopback_dev, using fake streams.\n");
|
||||
useFakeStreams = true;
|
||||
}
|
||||
|
||||
function message(m) {
|
||||
document.getElementById("message").innerHTML = m;
|
||||
window.parent.postMessage(m, "*");
|
||||
@ -12,8 +25,11 @@ function message(m) {
|
||||
var gStream;
|
||||
|
||||
function requestDevice(aAudio, aVideo) {
|
||||
window.navigator.mozGetUserMedia({video: aVideo, audio: aAudio, fake: true},
|
||||
function(stream) {
|
||||
var opts = {video: aVideo, audio: aAudio};
|
||||
if (useFakeStreams) {
|
||||
opts.fake = true;
|
||||
}
|
||||
window.navigator.mozGetUserMedia(opts, function(stream) {
|
||||
gStream = stream;
|
||||
message("ok");
|
||||
}, function(err) { message("error: " + err); });
|
||||
|
7
js/src/jit-test/tests/ion/bug1018621.js
Normal file
7
js/src/jit-test/tests/ion/bug1018621.js
Normal file
@ -0,0 +1,7 @@
|
||||
function strictSome(k) {
|
||||
"use strict";
|
||||
for (var i = 0; i < args.length; i++)
|
||||
assertEq(arguments[i], args[i], "wrong argument " + i);
|
||||
}
|
||||
args = [8, 6, 7, NaN, undefined, 0.3];
|
||||
strictSome.call(NaN, 8, 6, 7, NaN, undefined, 0.3);
|
@ -425,8 +425,11 @@ class CompileInfo
|
||||
|
||||
// Function.arguments can be used to access all arguments in non-strict
|
||||
// scripts, so we can't optimize out any arguments.
|
||||
if (!script()->strict() && firstArgSlot() <= slot && slot - firstArgSlot() < nargs())
|
||||
if ((hasArguments() || !script()->strict()) &&
|
||||
firstArgSlot() <= slot && slot - firstArgSlot() < nargs())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1656,9 +1656,51 @@ JitFrameIterator::osiIndex() const
|
||||
return ionScript()->getOsiIndex(reader.osiReturnPointOffset());
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
InlineFrameIterator::InlineFrameIterator(ThreadSafeContext *cx, const JitFrameIterator *iter)
|
||||
: callee_(cx),
|
||||
script_(cx)
|
||||
{
|
||||
resetOn(iter);
|
||||
}
|
||||
|
||||
InlineFrameIterator::InlineFrameIterator(JSRuntime *rt, const JitFrameIterator *iter)
|
||||
: callee_(rt),
|
||||
script_(rt)
|
||||
{
|
||||
resetOn(iter);
|
||||
}
|
||||
|
||||
InlineFrameIterator::InlineFrameIterator(ThreadSafeContext *cx, const IonBailoutIterator *iter)
|
||||
: frame_(iter),
|
||||
framesRead_(0),
|
||||
frameCount_(UINT32_MAX),
|
||||
callee_(cx),
|
||||
script_(cx)
|
||||
{
|
||||
if (iter) {
|
||||
start_ = SnapshotIterator(*iter);
|
||||
findNextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
InlineFrameIterator::InlineFrameIterator(ThreadSafeContext *cx, const InlineFrameIterator *iter)
|
||||
: frame_(iter ? iter->frame_ : nullptr),
|
||||
framesRead_(0),
|
||||
frameCount_(iter ? iter->frameCount_ : UINT32_MAX),
|
||||
callee_(cx),
|
||||
script_(cx)
|
||||
{
|
||||
if (frame_) {
|
||||
start_ = SnapshotIterator(*frame_);
|
||||
// findNextFrame will iterate to the next frame and init. everything.
|
||||
// Therefore to settle on the same frame, we report one frame less readed.
|
||||
framesRead_ = iter->framesRead_ - 1;
|
||||
findNextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
InlineFrameIteratorMaybeGC<allowGC>::resetOn(const JitFrameIterator *iter)
|
||||
InlineFrameIterator::resetOn(const JitFrameIterator *iter)
|
||||
{
|
||||
frame_ = iter;
|
||||
framesRead_ = 0;
|
||||
@ -1669,12 +1711,9 @@ InlineFrameIteratorMaybeGC<allowGC>::resetOn(const JitFrameIterator *iter)
|
||||
findNextFrame();
|
||||
}
|
||||
}
|
||||
template void InlineFrameIteratorMaybeGC<NoGC>::resetOn(const JitFrameIterator *iter);
|
||||
template void InlineFrameIteratorMaybeGC<CanGC>::resetOn(const JitFrameIterator *iter);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
void
|
||||
InlineFrameIteratorMaybeGC<allowGC>::findNextFrame()
|
||||
InlineFrameIterator::findNextFrame()
|
||||
{
|
||||
JS_ASSERT(more());
|
||||
|
||||
@ -1756,17 +1795,30 @@ InlineFrameIteratorMaybeGC<allowGC>::findNextFrame()
|
||||
|
||||
framesRead_++;
|
||||
}
|
||||
template void InlineFrameIteratorMaybeGC<NoGC>::findNextFrame();
|
||||
template void InlineFrameIteratorMaybeGC<CanGC>::findNextFrame();
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSObject *
|
||||
InlineFrameIterator::computeScopeChain(Value scopeChainValue) const
|
||||
{
|
||||
if (scopeChainValue.isObject())
|
||||
return &scopeChainValue.toObject();
|
||||
|
||||
if (isFunctionFrame()) {
|
||||
// Heavyweight functions should always have a scope chain.
|
||||
MOZ_ASSERT(!callee()->isHeavyweight());
|
||||
return callee()->environment();
|
||||
}
|
||||
|
||||
// Ion does not handle scripts that are not compile-and-go.
|
||||
MOZ_ASSERT(!script()->isForEval());
|
||||
MOZ_ASSERT(script()->compileAndGo());
|
||||
return &script()->global();
|
||||
}
|
||||
|
||||
bool
|
||||
InlineFrameIteratorMaybeGC<allowGC>::isFunctionFrame() const
|
||||
InlineFrameIterator::isFunctionFrame() const
|
||||
{
|
||||
return !!callee_;
|
||||
}
|
||||
template bool InlineFrameIteratorMaybeGC<NoGC>::isFunctionFrame() const;
|
||||
template bool InlineFrameIteratorMaybeGC<CanGC>::isFunctionFrame() const;
|
||||
|
||||
MachineState
|
||||
MachineState::FromBailout(mozilla::Array<uintptr_t, Registers::Total> ®s,
|
||||
@ -1782,13 +1834,12 @@ MachineState::FromBailout(mozilla::Array<uintptr_t, Registers::Total> ®s,
|
||||
return machine;
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
bool
|
||||
InlineFrameIteratorMaybeGC<allowGC>::isConstructing() const
|
||||
InlineFrameIterator::isConstructing() const
|
||||
{
|
||||
// Skip the current frame and look at the caller's.
|
||||
if (more()) {
|
||||
InlineFrameIteratorMaybeGC<allowGC> parent(GetJSContextFromJitCode(), this);
|
||||
InlineFrameIterator parent(GetJSContextFromJitCode(), this);
|
||||
++parent;
|
||||
|
||||
// Inlined Getters and Setters are never constructing.
|
||||
@ -1803,8 +1854,6 @@ InlineFrameIteratorMaybeGC<allowGC>::isConstructing() const
|
||||
|
||||
return frame_->isConstructing();
|
||||
}
|
||||
template bool InlineFrameIteratorMaybeGC<NoGC>::isConstructing() const;
|
||||
template bool InlineFrameIteratorMaybeGC<CanGC>::isConstructing() const;
|
||||
|
||||
bool
|
||||
JitFrameIterator::isConstructing() const
|
||||
@ -1921,9 +1970,8 @@ JitFrameIterator::dumpBaseline() const
|
||||
}
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
void
|
||||
InlineFrameIteratorMaybeGC<allowGC>::dump() const
|
||||
InlineFrameIterator::dump() const
|
||||
{
|
||||
if (more())
|
||||
fprintf(stderr, " JS frame (inlined)\n");
|
||||
@ -1982,8 +2030,6 @@ InlineFrameIteratorMaybeGC<allowGC>::dump() const
|
||||
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
template void InlineFrameIteratorMaybeGC<NoGC>::dump() const;
|
||||
template void InlineFrameIteratorMaybeGC<CanGC>::dump() const;
|
||||
|
||||
void
|
||||
JitFrameIterator::dump() const
|
||||
|
@ -18,22 +18,6 @@
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
template <AllowGC allowGC>
|
||||
inline
|
||||
InlineFrameIteratorMaybeGC<allowGC>::InlineFrameIteratorMaybeGC(ThreadSafeContext *cx,
|
||||
const IonBailoutIterator *iter)
|
||||
: frame_(iter),
|
||||
framesRead_(0),
|
||||
frameCount_(UINT32_MAX),
|
||||
callee_(cx),
|
||||
script_(cx)
|
||||
{
|
||||
if (iter) {
|
||||
start_ = SnapshotIterator(*iter);
|
||||
findNextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
inline BaselineFrame *
|
||||
JitFrameIterator::baselineFrame() const
|
||||
{
|
||||
|
@ -453,8 +453,7 @@ class SnapshotIterator
|
||||
|
||||
// Reads frame information in callstack order (that is, innermost frame to
|
||||
// outermost frame).
|
||||
template <AllowGC allowGC=CanGC>
|
||||
class InlineFrameIteratorMaybeGC
|
||||
class InlineFrameIterator
|
||||
{
|
||||
const JitFrameIterator *frame_;
|
||||
SnapshotIterator start_;
|
||||
@ -467,8 +466,8 @@ class InlineFrameIteratorMaybeGC
|
||||
// frames contained in the recover buffer.
|
||||
uint32_t frameCount_;
|
||||
|
||||
typename MaybeRooted<JSFunction*, allowGC>::RootType callee_;
|
||||
typename MaybeRooted<JSScript*, allowGC>::RootType script_;
|
||||
RootedFunction callee_;
|
||||
RootedScript script_;
|
||||
jsbytecode *pc_;
|
||||
uint32_t numActualArgs_;
|
||||
|
||||
@ -478,55 +477,13 @@ class InlineFrameIteratorMaybeGC
|
||||
|
||||
private:
|
||||
void findNextFrame();
|
||||
|
||||
JSObject *computeScopeChain(Value scopeChainValue) const {
|
||||
if (scopeChainValue.isObject())
|
||||
return &scopeChainValue.toObject();
|
||||
|
||||
if (isFunctionFrame()) {
|
||||
// Heavyweight functions should always have a scope chain.
|
||||
MOZ_ASSERT(!callee()->isHeavyweight());
|
||||
return callee()->environment();
|
||||
}
|
||||
|
||||
// Ion does not handle scripts that are not compile-and-go.
|
||||
MOZ_ASSERT(!script()->isForEval());
|
||||
MOZ_ASSERT(script()->compileAndGo());
|
||||
return &script()->global();
|
||||
}
|
||||
JSObject *computeScopeChain(Value scopeChainValue) const;
|
||||
|
||||
public:
|
||||
InlineFrameIteratorMaybeGC(ThreadSafeContext *cx, const JitFrameIterator *iter)
|
||||
: callee_(cx),
|
||||
script_(cx)
|
||||
{
|
||||
resetOn(iter);
|
||||
}
|
||||
|
||||
InlineFrameIteratorMaybeGC(JSRuntime *rt, const JitFrameIterator *iter)
|
||||
: callee_(rt),
|
||||
script_(rt)
|
||||
{
|
||||
resetOn(iter);
|
||||
}
|
||||
|
||||
InlineFrameIteratorMaybeGC(ThreadSafeContext *cx, const IonBailoutIterator *iter);
|
||||
|
||||
InlineFrameIteratorMaybeGC(ThreadSafeContext *cx, const InlineFrameIteratorMaybeGC *iter)
|
||||
: frame_(iter ? iter->frame_ : nullptr),
|
||||
framesRead_(0),
|
||||
frameCount_(iter ? iter->frameCount_ : UINT32_MAX),
|
||||
callee_(cx),
|
||||
script_(cx)
|
||||
{
|
||||
if (frame_) {
|
||||
start_ = SnapshotIterator(*frame_);
|
||||
// findNextFrame will iterate to the next frame and init. everything.
|
||||
// Therefore to settle on the same frame, we report one frame less readed.
|
||||
framesRead_ = iter->framesRead_ - 1;
|
||||
findNextFrame();
|
||||
}
|
||||
}
|
||||
InlineFrameIterator(ThreadSafeContext *cx, const JitFrameIterator *iter);
|
||||
InlineFrameIterator(JSRuntime *rt, const JitFrameIterator *iter);
|
||||
InlineFrameIterator(ThreadSafeContext *cx, const IonBailoutIterator *iter);
|
||||
InlineFrameIterator(ThreadSafeContext *cx, const InlineFrameIterator *iter);
|
||||
|
||||
bool more() const {
|
||||
return frame_ && framesRead_ < frameCount_;
|
||||
@ -587,7 +544,7 @@ class InlineFrameIteratorMaybeGC
|
||||
// The overflown arguments are not available in current frame.
|
||||
// They are the last pushed arguments in the parent frame of
|
||||
// this inlined frame.
|
||||
InlineFrameIteratorMaybeGC it(cx, this);
|
||||
InlineFrameIterator it(cx, this);
|
||||
++it;
|
||||
unsigned argsObjAdj = it.script()->argumentsHasVarBinding() ? 1 : 0;
|
||||
SnapshotIterator parent_s(it.snapshotIterator());
|
||||
@ -673,7 +630,7 @@ class InlineFrameIteratorMaybeGC
|
||||
return s.read();
|
||||
}
|
||||
|
||||
InlineFrameIteratorMaybeGC &operator++() {
|
||||
InlineFrameIterator &operator++() {
|
||||
findNextFrame();
|
||||
return *this;
|
||||
}
|
||||
@ -696,11 +653,9 @@ class InlineFrameIteratorMaybeGC
|
||||
}
|
||||
|
||||
private:
|
||||
InlineFrameIteratorMaybeGC() MOZ_DELETE;
|
||||
InlineFrameIteratorMaybeGC(const InlineFrameIteratorMaybeGC &iter) MOZ_DELETE;
|
||||
InlineFrameIterator() MOZ_DELETE;
|
||||
InlineFrameIterator(const InlineFrameIterator &iter) MOZ_DELETE;
|
||||
};
|
||||
typedef InlineFrameIteratorMaybeGC<CanGC> InlineFrameIterator;
|
||||
typedef InlineFrameIteratorMaybeGC<NoGC> InlineFrameIteratorNoGC;
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
@ -6,6 +6,7 @@ package org.mozilla.gecko.db;
|
||||
|
||||
import java.lang.IllegalArgumentException;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
import org.mozilla.gecko.db.BrowserContract.FormHistory;
|
||||
@ -33,6 +34,7 @@ public class FormHistoryProvider extends SQLiteBridgeContentProvider {
|
||||
// This should be kept in sync with the db version in toolkit/components/satchel/nsFormHistory.js
|
||||
private static int DB_VERSION = 4;
|
||||
private static String DB_FILENAME = "formhistory.sqlite";
|
||||
private static final String TELEMETRY_TAG = "SQLITEBRIDGE_PROVIDER_FORMS";
|
||||
|
||||
private static final String WHERE_GUID_IS_NULL = BrowserContract.DeletedFormHistory.GUID + " IS NULL";
|
||||
private static final String WHERE_GUID_IS_VALUE = BrowserContract.DeletedFormHistory.GUID + " = ?";
|
||||
@ -153,6 +155,11 @@ public class FormHistoryProvider extends SQLiteBridgeContentProvider {
|
||||
return DB_FILENAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTelemetryPrefix() {
|
||||
return TELEMETRY_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDBVersion(){
|
||||
return DB_VERSION;
|
||||
|
@ -29,6 +29,7 @@ public class HomeProvider extends SQLiteBridgeContentProvider {
|
||||
// This should be kept in sync with the db version in mobile/android/modules/HomeProvider.jsm
|
||||
private static int DB_VERSION = 2;
|
||||
private static String DB_FILENAME = "home.sqlite";
|
||||
private static final String TELEMETRY_TAG = "SQLITEBRIDGE_PROVIDER_HOME";
|
||||
|
||||
private static final String TABLE_ITEMS = "items";
|
||||
|
||||
@ -144,6 +145,11 @@ public class HomeProvider extends SQLiteBridgeContentProvider {
|
||||
return DB_FILENAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTelemetryPrefix() {
|
||||
return TELEMETRY_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDBVersion(){
|
||||
return DB_VERSION;
|
||||
|
@ -29,6 +29,8 @@ public class PasswordsProvider extends SQLiteBridgeContentProvider {
|
||||
static final String TABLE_PASSWORDS = "moz_logins";
|
||||
static final String TABLE_DELETED_PASSWORDS = "moz_deleted_logins";
|
||||
|
||||
private static final String TELEMETRY_TAG = "SQLITEBRIDGE_PROVIDER_PASSWORDS";
|
||||
|
||||
private static final int PASSWORDS = 100;
|
||||
private static final int DELETED_PASSWORDS = 101;
|
||||
|
||||
@ -91,6 +93,11 @@ public class PasswordsProvider extends SQLiteBridgeContentProvider {
|
||||
return DB_FILENAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTelemetryPrefix() {
|
||||
return TELEMETRY_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDBVersion(){
|
||||
return DB_VERSION;
|
||||
|
@ -6,14 +6,14 @@ package org.mozilla.gecko.db;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
import org.mozilla.gecko.GeckoThread;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.Telemetry;
|
||||
import org.mozilla.gecko.mozglue.GeckoLoader;
|
||||
import org.mozilla.gecko.sqlite.SQLiteBridge;
|
||||
import org.mozilla.gecko.sqlite.SQLiteBridgeException;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
@ -35,6 +35,8 @@ import android.util.Log;
|
||||
*/
|
||||
|
||||
public abstract class SQLiteBridgeContentProvider extends ContentProvider {
|
||||
private static final String ERROR_MESSAGE_DATABASE_IS_LOCKED = "Can't step statement: (5) database is locked";
|
||||
|
||||
private HashMap<String, SQLiteBridge> mDatabasePerProfile;
|
||||
protected Context mContext = null;
|
||||
private final String mLogTag;
|
||||
@ -43,6 +45,42 @@ public abstract class SQLiteBridgeContentProvider extends ContentProvider {
|
||||
mLogTag = logTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must override this to allow error reporting code to compose
|
||||
* the correct histogram name.
|
||||
*
|
||||
* Ensure that you define the new histograms if you define a new class!
|
||||
*/
|
||||
protected abstract String getTelemetryPrefix();
|
||||
|
||||
/**
|
||||
* Errors are recorded in telemetry using an enumerated histogram.
|
||||
*
|
||||
* <https://developer.mozilla.org/en-US/docs/Mozilla/Performance/
|
||||
* Adding_a_new_Telemetry_probe#Choosing_a_Histogram_Type>
|
||||
*
|
||||
* These are the allowable enumeration values. Keep these in sync with the
|
||||
* histogram definition!
|
||||
*
|
||||
*/
|
||||
private static enum TelemetryErrorOp {
|
||||
BULKINSERT (0),
|
||||
DELETE (1),
|
||||
INSERT (2),
|
||||
QUERY (3),
|
||||
UPDATE (4);
|
||||
|
||||
private final int bucket;
|
||||
|
||||
TelemetryErrorOp(final int bucket) {
|
||||
this.bucket = bucket;
|
||||
}
|
||||
|
||||
public int getBucket() {
|
||||
return bucket;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
if (mDatabasePerProfile == null) {
|
||||
@ -255,7 +293,7 @@ public abstract class SQLiteBridgeContentProvider extends ContentProvider {
|
||||
try {
|
||||
deleted = db.delete(getTable(uri), selection, selectionArgs);
|
||||
} catch (SQLiteBridgeException ex) {
|
||||
Log.e(mLogTag, "Error deleting record", ex);
|
||||
reportError(ex, TelemetryErrorOp.DELETE);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
@ -291,7 +329,7 @@ public abstract class SQLiteBridgeContentProvider extends ContentProvider {
|
||||
db.setTransactionSuccessful();
|
||||
}
|
||||
} catch (SQLiteBridgeException ex) {
|
||||
Log.e(mLogTag, "Error inserting in db", ex);
|
||||
reportError(ex, TelemetryErrorOp.INSERT);
|
||||
throw ex;
|
||||
} finally {
|
||||
if (useTransaction) {
|
||||
@ -312,7 +350,6 @@ public abstract class SQLiteBridgeContentProvider extends ContentProvider {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long id = -1;
|
||||
int rowsAdded = 0;
|
||||
|
||||
String table = getTable(uri);
|
||||
@ -323,12 +360,12 @@ public abstract class SQLiteBridgeContentProvider extends ContentProvider {
|
||||
ContentValues values = new ContentValues(initialValues);
|
||||
setupDefaults(uri, values);
|
||||
onPreInsert(values, uri, db);
|
||||
id = db.insert(table, null, values);
|
||||
db.insert(table, null, values);
|
||||
rowsAdded++;
|
||||
}
|
||||
db.setTransactionSuccessful();
|
||||
} catch (SQLiteBridgeException ex) {
|
||||
Log.e(mLogTag, "Error inserting in db", ex);
|
||||
reportError(ex, TelemetryErrorOp.BULKINSERT);
|
||||
throw ex;
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
@ -360,7 +397,7 @@ public abstract class SQLiteBridgeContentProvider extends ContentProvider {
|
||||
try {
|
||||
updated = db.update(getTable(uri), values, selection, selectionArgs);
|
||||
} catch (SQLiteBridgeException ex) {
|
||||
Log.e(mLogTag, "Error updating table", ex);
|
||||
reportError(ex, TelemetryErrorOp.UPDATE);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
@ -386,13 +423,32 @@ public abstract class SQLiteBridgeContentProvider extends ContentProvider {
|
||||
cursor = db.query(getTable(uri), projection, selection, selectionArgs, null, null, sortOrder, null);
|
||||
onPostQuery(cursor, uri, db);
|
||||
} catch (SQLiteBridgeException ex) {
|
||||
Log.e(mLogTag, "Error querying database", ex);
|
||||
reportError(ex, TelemetryErrorOp.QUERY);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
private String getHistogram(SQLiteBridgeException e) {
|
||||
// If you add values here, make sure to update
|
||||
// toolkit/components/telemetry/Histograms.json.
|
||||
if (ERROR_MESSAGE_DATABASE_IS_LOCKED.equals(e.getMessage())) {
|
||||
return getTelemetryPrefix() + "_LOCKED";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void reportError(SQLiteBridgeException e, TelemetryErrorOp op) {
|
||||
Log.e(mLogTag, "Error in database " + op.name(), e);
|
||||
final String histogram = getHistogram(e);
|
||||
if (histogram == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Telemetry.HistogramAdd(histogram, op.getBucket());
|
||||
}
|
||||
|
||||
protected abstract String getDBName();
|
||||
|
||||
protected abstract int getDBVersion();
|
||||
|
@ -12,7 +12,8 @@ config = {
|
||||
"--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s",
|
||||
"--certificate-path=tests/certs", "--autorun", "--close-when-done",
|
||||
"--console-level=INFO", "--setpref=webgl.force-enabled=true",
|
||||
"--quiet"
|
||||
"--quiet",
|
||||
"--use-test-media-devices"
|
||||
],
|
||||
"webapprt_options": [
|
||||
"--app=%(app_path)s", "--utility-path=tests/bin",
|
||||
|
@ -104,6 +104,10 @@ private:
|
||||
SERVER_RESPONSE_INVALID = 2,
|
||||
};
|
||||
|
||||
// Number of blocklist and allowlist hits we have seen.
|
||||
uint32_t mBlocklistCount;
|
||||
uint32_t mAllowlistCount;
|
||||
|
||||
// The query containing metadata about the downloaded file.
|
||||
nsCOMPtr<nsIApplicationReputationQuery> mQuery;
|
||||
|
||||
@ -243,7 +247,7 @@ nsresult
|
||||
PendingDBLookup::LookupSpec(const nsACString& aSpec,
|
||||
bool aAllowlistOnly)
|
||||
{
|
||||
LOG(("Checking principal %s", aSpec.Data()));
|
||||
LOG(("Checking principal %s [this=%p]", aSpec.Data(), this));
|
||||
mSpec = aSpec;
|
||||
mAllowlistOnly = aAllowlistOnly;
|
||||
nsresult rv = LookupSpecInternal(aSpec);
|
||||
@ -298,12 +302,13 @@ NS_IMETHODIMP
|
||||
PendingDBLookup::HandleEvent(const nsACString& tables)
|
||||
{
|
||||
// HandleEvent is guaranteed to call either:
|
||||
// 1) PendingLookup::OnComplete if the URL can be classified locally, or
|
||||
// 2) PendingLookup::LookupNext if the URL can be cannot classified locally.
|
||||
// 1) PendingLookup::OnComplete if the URL matches the blocklist, or
|
||||
// 2) PendingLookup::LookupNext if the URL does not match the blocklist.
|
||||
// Blocklisting trumps allowlisting.
|
||||
nsAutoCString blockList;
|
||||
Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE, &blockList);
|
||||
if (!mAllowlistOnly && FindInReadable(blockList, tables)) {
|
||||
mPendingLookup->mBlocklistCount++;
|
||||
Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_LOCAL, BLOCK_LIST);
|
||||
LOG(("Found principal %s on blocklist [this = %p]", mSpec.get(), this));
|
||||
return mPendingLookup->OnComplete(true, NS_OK);
|
||||
@ -312,13 +317,15 @@ PendingDBLookup::HandleEvent(const nsACString& tables)
|
||||
nsAutoCString allowList;
|
||||
Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE, &allowList);
|
||||
if (FindInReadable(allowList, tables)) {
|
||||
mPendingLookup->mAllowlistCount++;
|
||||
Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_LOCAL, ALLOW_LIST);
|
||||
LOG(("Found principal %s on allowlist [this = %p]", mSpec.get(), this));
|
||||
return mPendingLookup->OnComplete(false, NS_OK);
|
||||
// Don't call onComplete, since blocklisting trumps allowlisting
|
||||
} else {
|
||||
LOG(("Didn't find principal %s on any list [this = %p]", mSpec.get(),
|
||||
this));
|
||||
Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_LOCAL, NO_LIST);
|
||||
}
|
||||
|
||||
LOG(("Didn't find principal %s on any list [this = %p]", mSpec.get(), this));
|
||||
Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_LOCAL, NO_LIST);
|
||||
return mPendingLookup->LookupNext();
|
||||
}
|
||||
|
||||
@ -328,6 +335,8 @@ NS_IMPL_ISUPPORTS(PendingLookup,
|
||||
|
||||
PendingLookup::PendingLookup(nsIApplicationReputationQuery* aQuery,
|
||||
nsIApplicationReputationCallback* aCallback) :
|
||||
mBlocklistCount(0),
|
||||
mAllowlistCount(0),
|
||||
mQuery(aQuery),
|
||||
mCallback(aCallback)
|
||||
{
|
||||
@ -371,27 +380,36 @@ nsresult
|
||||
PendingLookup::LookupNext()
|
||||
{
|
||||
// We must call LookupNext or SendRemoteQuery upon return.
|
||||
// Look up all of the URLs that could whitelist this download.
|
||||
// Blacklist first.
|
||||
// Look up all of the URLs that could allow or block this download.
|
||||
// Blocklist first.
|
||||
if (mBlocklistCount > 0) {
|
||||
return OnComplete(true, NS_OK);
|
||||
}
|
||||
int index = mAnylistSpecs.Length() - 1;
|
||||
nsCString spec;
|
||||
bool allowlistOnly = false;
|
||||
if (index >= 0) {
|
||||
// Check the source URI and referrer.
|
||||
// Check the source URI, referrer and redirect chain.
|
||||
spec = mAnylistSpecs[index];
|
||||
mAnylistSpecs.RemoveElementAt(index);
|
||||
} else {
|
||||
// Check the allowlists next.
|
||||
index = mAllowlistSpecs.Length() - 1;
|
||||
if (index >= 0) {
|
||||
allowlistOnly = true;
|
||||
spec = mAllowlistSpecs[index];
|
||||
mAllowlistSpecs.RemoveElementAt(index);
|
||||
}
|
||||
}
|
||||
if (index >= 0) {
|
||||
nsRefPtr<PendingDBLookup> lookup(new PendingDBLookup(this));
|
||||
return lookup->LookupSpec(spec, allowlistOnly);
|
||||
return lookup->LookupSpec(spec, false);
|
||||
}
|
||||
// If any of mAnylistSpecs matched the blocklist, go ahead and block.
|
||||
if (mBlocklistCount > 0) {
|
||||
return OnComplete(true, NS_OK);
|
||||
}
|
||||
// If any of mAnylistSpecs matched the allowlist, go ahead and pass.
|
||||
if (mAllowlistCount > 0) {
|
||||
return OnComplete(false, NS_OK);
|
||||
}
|
||||
// Only binary signatures remain.
|
||||
index = mAllowlistSpecs.Length() - 1;
|
||||
if (index >= 0) {
|
||||
spec = mAllowlistSpecs[index];
|
||||
LOG(("PendingLookup::LookupNext: checking %s on allowlist", spec.get()));
|
||||
mAllowlistSpecs.RemoveElementAt(index);
|
||||
nsRefPtr<PendingDBLookup> lookup(new PendingDBLookup(this));
|
||||
return lookup->LookupSpec(spec, true);
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
// There are no more URIs to check against local list. If the file is not
|
||||
@ -407,6 +425,7 @@ PendingLookup::LookupNext()
|
||||
}
|
||||
return NS_OK;
|
||||
#else
|
||||
LOG(("PendingLookup: Nothing left to check [this=%p]", this));
|
||||
return OnComplete(false, NS_OK);
|
||||
#endif
|
||||
}
|
||||
@ -630,7 +649,7 @@ PendingLookup::DoLookupInternal()
|
||||
if (redirects) {
|
||||
AddRedirects(redirects);
|
||||
} else {
|
||||
LOG(("ApplicationReputation: Got no redirects"));
|
||||
LOG(("ApplicationReputation: Got no redirects [this=%p]", this));
|
||||
}
|
||||
|
||||
// Extract the signature and parse certificates so we can use it to check
|
||||
@ -976,7 +995,7 @@ NS_IMETHODIMP
|
||||
ApplicationReputationService::QueryReputation(
|
||||
nsIApplicationReputationQuery* aQuery,
|
||||
nsIApplicationReputationCallback* aCallback) {
|
||||
LOG(("Starting application reputation check"));
|
||||
LOG(("Starting application reputation check [query=%p]", aQuery));
|
||||
NS_ENSURE_ARG_POINTER(aQuery);
|
||||
NS_ENSURE_ARG_POINTER(aCallback);
|
||||
|
||||
|
@ -68,11 +68,15 @@ function run_test() {
|
||||
Services.prefs.clearUserPref("browser.safebrowsing.malware.enabled");
|
||||
});
|
||||
|
||||
// Set download_block_table explicitly.
|
||||
// Set block and allow tables explicitly, since the allowlist is normally
|
||||
// disabled on non-Windows platforms.
|
||||
Services.prefs.setCharPref("urlclassifier.downloadBlockTable",
|
||||
"goog-badbinurl-shavar");
|
||||
Services.prefs.setCharPref("urlclassifier.downloadAllowTable",
|
||||
"goog-downloadwhite-digest256");
|
||||
do_register_cleanup(function() {
|
||||
Services.prefs.clearUserPref("urlclassifier.downloadBlockTable");
|
||||
Services.prefs.clearUserPref("urlclassifier.downloadAllowTable");
|
||||
});
|
||||
|
||||
gHttpServ = new HttpServer();
|
||||
@ -97,9 +101,13 @@ function check_telemetry(aCount,
|
||||
.getService(Ci.nsITelemetry)
|
||||
.getHistogramById("APPLICATION_REPUTATION_LOCAL")
|
||||
.snapshot();
|
||||
do_check_eq(local.counts[ALLOW_LIST], aListCounts[ALLOW_LIST]);
|
||||
do_check_eq(local.counts[BLOCK_LIST], aListCounts[BLOCK_LIST]);
|
||||
do_check_eq(local.counts[NO_LIST], aListCounts[NO_LIST]);
|
||||
do_check_eq(local.counts[ALLOW_LIST], aListCounts[ALLOW_LIST],
|
||||
"Allow list counts don't match");
|
||||
do_check_eq(local.counts[BLOCK_LIST], aListCounts[BLOCK_LIST],
|
||||
"Block list counts don't match");
|
||||
do_check_eq(local.counts[NO_LIST], aListCounts[NO_LIST],
|
||||
"No list counts don't match");
|
||||
|
||||
let shouldBlock = Cc["@mozilla.org/base/telemetry;1"]
|
||||
.getService(Ci.nsITelemetry)
|
||||
.getHistogramById("APPLICATION_REPUTATION_SHOULD_BLOCK")
|
||||
@ -200,9 +208,9 @@ add_test(function test_local_list() {
|
||||
streamUpdater.updateUrl = "http://localhost:4444/downloads";
|
||||
|
||||
// Load up some update chunks for the safebrowsing server to serve.
|
||||
// This chunk contains the hash of whitelisted.com/.
|
||||
registerTableUpdate("goog-badbinurl-shavar", "data/block_digest.chunk");
|
||||
// This chunk contains the hash of blocklisted.com/.
|
||||
registerTableUpdate("goog-badbinurl-shavar", "data/block_digest.chunk");
|
||||
// This chunk contains the hash of whitelisted.com/.
|
||||
registerTableUpdate("goog-downloadwhite-digest256", "data/digest.chunk");
|
||||
|
||||
// Download some updates, and don't continue until the downloads are done.
|
||||
@ -299,15 +307,16 @@ add_test(function test_redirect_on_blocklist() {
|
||||
let counts = get_telemetry_counts();
|
||||
let listCounts = counts.listCounts;
|
||||
listCounts[BLOCK_LIST]++;
|
||||
listCounts[ALLOW_LIST]++;
|
||||
let secman = Services.scriptSecurityManager;
|
||||
let badRedirects = Cc["@mozilla.org/array;1"]
|
||||
.createInstance(Ci.nsIMutableArray);
|
||||
badRedirects.appendElement(secman.getNoAppCodebasePrincipal(whitelistedURI),
|
||||
false);
|
||||
badRedirects.appendElement(secman.getNoAppCodebasePrincipal(exampleURI),
|
||||
false);
|
||||
badRedirects.appendElement(secman.getNoAppCodebasePrincipal(blocklistedURI),
|
||||
false);
|
||||
badRedirects.appendElement(secman.getNoAppCodebasePrincipal(whitelistedURI),
|
||||
false);
|
||||
gAppRep.queryReputation({
|
||||
sourceURI: whitelistedURI,
|
||||
referrerURI: exampleURI,
|
||||
|
@ -5908,6 +5908,24 @@
|
||||
"extended_statistics_ok": true,
|
||||
"description": "Time spent to open an existing cache entry"
|
||||
},
|
||||
"SQLITEBRIDGE_PROVIDER_PASSWORDS_LOCKED": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": "10",
|
||||
"description": "The number of errors using the PasswordsProvider due to a locked DB."
|
||||
},
|
||||
"SQLITEBRIDGE_PROVIDER_FORMS_LOCKED": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": "10",
|
||||
"description": "The number of errors using the FormHistoryProvider due to a locked DB."
|
||||
},
|
||||
"SQLITEBRIDGE_PROVIDER_HOME_LOCKED": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": "10",
|
||||
"description": "The number of errors using the HomeProvider due to a locked DB."
|
||||
},
|
||||
"SSL_TLS12_INTOLERANCE_REASON_PRE": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
|
@ -181,7 +181,7 @@ LookupCache::Dump()
|
||||
|
||||
for (uint32_t i = 0; i < mCompletions.Length(); i++) {
|
||||
nsAutoCString str;
|
||||
mCompletions[i].ToString(str);
|
||||
mCompletions[i].ToHexString(str);
|
||||
LOG(("Completion: %s", str.get()));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user