Merge mozilla-central to autoland

--HG--
extra : rebase_source : da41c9831b781517597aebd0878c5ada415fd00b
This commit is contained in:
arthur.iakab 2018-05-08 15:49:18 +03:00
Родитель 160ba9f717 f2042a4c1f
Коммит b613e3c213
95 изменённых файлов: 18056 добавлений и 14617 удалений

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

@ -1,19 +1,19 @@
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const AndroidEvents = {
ANDROID_VIEW_CLICKED: 0x01,
ANDROID_VIEW_LONG_CLICKED: 0x02,
ANDROID_VIEW_SELECTED: 0x04,
ANDROID_VIEW_FOCUSED: 0x08,
ANDROID_VIEW_TEXT_CHANGED: 0x10,
ANDROID_WINDOW_STATE_CHANGED: 0x20,
ANDROID_VIEW_HOVER_ENTER: 0x80,
ANDROID_VIEW_HOVER_EXIT: 0x100,
ANDROID_VIEW_SCROLLED: 0x1000,
ANDROID_VIEW_TEXT_SELECTION_CHANGED: 0x2000,
ANDROID_ANNOUNCEMENT: 0x4000,
ANDROID_VIEW_ACCESSIBILITY_FOCUSED: 0x8000,
ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: 0x20000,
VIEW_CLICKED: 0x01,
VIEW_LONG_CLICKED: 0x02,
VIEW_SELECTED: 0x04,
VIEW_FOCUSED: 0x08,
VIEW_TEXT_CHANGED: 0x10,
WINDOW_STATE_CHANGED: 0x20,
VIEW_HOVER_ENTER: 0x80,
VIEW_HOVER_EXIT: 0x100,
VIEW_SCROLLED: 0x1000,
VIEW_TEXT_SELECTION_CHANGED: 0x2000,
ANNOUNCEMENT: 0x4000,
VIEW_ACCESSIBILITY_FOCUSED: 0x8000,
VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: 0x20000,
};
function ConstantsMap(aObject, aPrefix, aMap = {}, aModifier = null) {

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

@ -44,13 +44,13 @@ class AndroidPresentor {
let isExploreByTouch = (aReason == Ci.nsIAccessiblePivot.REASON_POINT &&
Utils.AndroidSdkVersion >= 14);
let focusEventType = (Utils.AndroidSdkVersion >= 16) ?
AndroidEvents.ANDROID_VIEW_ACCESSIBILITY_FOCUSED :
AndroidEvents.ANDROID_VIEW_FOCUSED;
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED :
AndroidEvents.VIEW_FOCUSED;
if (isExploreByTouch) {
// This isn't really used by TalkBack so this is a half-hearted attempt
// for now.
androidEvents.push({eventType: AndroidEvents.ANDROID_VIEW_HOVER_EXIT, text: []});
androidEvents.push({eventType: AndroidEvents.VIEW_HOVER_EXIT, text: []});
}
if (aReason === Ci.nsIAccessiblePivot.REASON_TEXT) {
@ -58,7 +58,7 @@ class AndroidPresentor {
let adjustedText = context.textAndAdjustedOffsets;
androidEvents.push({
eventType: AndroidEvents.ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
eventType: AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
text: [adjustedText.text],
fromIndex: adjustedText.startOffset,
toIndex: adjustedText.endOffset
@ -67,7 +67,7 @@ class AndroidPresentor {
} else {
let state = Utils.getState(context.accessible);
androidEvents.push({eventType: (isExploreByTouch) ?
AndroidEvents.ANDROID_VIEW_HOVER_ENTER : focusEventType,
AndroidEvents.VIEW_HOVER_ENTER : focusEventType,
text: Utils.localize(UtteranceGenerator.genForContext(
context)),
bounds: context.bounds,
@ -105,7 +105,7 @@ class AndroidPresentor {
}
return [{
eventType: AndroidEvents.ANDROID_VIEW_CLICKED,
eventType: AndroidEvents.VIEW_CLICKED,
text,
checked: state.contains(States.CHECKED)
}];
@ -116,7 +116,7 @@ class AndroidPresentor {
*/
textChanged(aAccessible, aIsInserted, aStart, aLength, aText, aModifiedText) {
let androidEvent = {
eventType: AndroidEvents.ANDROID_VIEW_TEXT_CHANGED,
eventType: AndroidEvents.VIEW_TEXT_CHANGED,
text: [aText],
fromIndex: aStart,
removedCount: 0,
@ -144,7 +144,7 @@ class AndroidPresentor {
if (Utils.AndroidSdkVersion >= 14 && !aIsFromUserInput) {
androidEvents.push({
eventType: AndroidEvents.ANDROID_VIEW_TEXT_SELECTION_CHANGED,
eventType: AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
text: [aText],
fromIndex: aStart,
toIndex: aEnd,
@ -156,7 +156,7 @@ class AndroidPresentor {
let [from, to] = aOldStart < aStart ?
[aOldStart, aStart] : [aStart, aOldStart];
androidEvents.push({
eventType: AndroidEvents.ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
eventType: AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
text: [aText],
fromIndex: from,
toIndex: to
@ -229,7 +229,7 @@ class AndroidPresentor {
}
let events = [{
eventType: AndroidEvents.ANDROID_VIEW_SCROLLED,
eventType: AndroidEvents.VIEW_SCROLLED,
text: [],
scrollX: aWindow.scrollX,
scrollY: aWindow.scrollY,
@ -241,7 +241,7 @@ class AndroidPresentor {
let currentAcc = currentContext.accessibleForBounds;
if (Utils.isAliveAndVisible(currentAcc)) {
events.push({
eventType: AndroidEvents.ANDROID_VIEW_ACCESSIBILITY_FOCUSED,
eventType: AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED,
bounds: Utils.getBounds(currentAcc)
});
}
@ -264,8 +264,8 @@ class AndroidPresentor {
let localizedAnnouncement = Utils.localize(aAnnouncement).join(" ");
return [{
eventType: (Utils.AndroidSdkVersion >= 16) ?
AndroidEvents.ANDROID_ANNOUNCEMENT :
AndroidEvents.ANDROID_VIEW_TEXT_CHANGED,
AndroidEvents.ANNOUNCEMENT :
AndroidEvents.VIEW_TEXT_CHANGED,
text: [localizedAnnouncement],
addedCount: localizedAnnouncement.length,
removedCount: 0,
@ -280,7 +280,7 @@ class AndroidPresentor {
*/
noMove(aMoveMethod) {
return [{
eventType: AndroidEvents.ANDROID_VIEW_ACCESSIBILITY_FOCUSED,
eventType: AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED,
exitView: aMoveMethod,
text: [""]
}];

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

@ -551,7 +551,7 @@ ExpectedPresent.prototype.ignore = function(aMessage) {
let firstEvent = (aMessage.json || [])[0];
return firstEvent && firstEvent.eventType === AndroidEvents.ANDROID_VIEW_SCROLLED;
return firstEvent && firstEvent.eventType === AndroidEvents.VIEW_SCROLLED;
};
function ExpectedCursorChange(aSpeech, aOptions) {
@ -564,7 +564,7 @@ ExpectedCursorChange.prototype = Object.create(ExpectedPresent.prototype);
function ExpectedCursorTextChange(aSpeech, aStartOffset, aEndOffset, aOptions) {
ExpectedPresent.call(this, [{
eventType: AndroidEvents.ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
eventType: AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
fromIndex: aStartOffset,
toIndex: aEndOffset
}], aOptions);
@ -578,7 +578,7 @@ ExpectedCursorTextChange.prototype =
function ExpectedClickAction(aOptions) {
ExpectedPresent.call(this, [{
eventType: AndroidEvents.ANDROID_VIEW_CLICKED
eventType: AndroidEvents.VIEW_CLICKED
}], aOptions);
}
@ -586,7 +586,7 @@ ExpectedClickAction.prototype = Object.create(ExpectedPresent.prototype);
function ExpectedCheckAction(aChecked, aOptions) {
ExpectedPresent.call(this, [{
eventType: AndroidEvents.ANDROID_VIEW_CLICKED,
eventType: AndroidEvents.VIEW_CLICKED,
checked: aChecked
}], aOptions);
}
@ -595,7 +595,7 @@ ExpectedCheckAction.prototype = Object.create(ExpectedPresent.prototype);
function ExpectedSwitchAction(aSwitched, aOptions) {
ExpectedPresent.call(this, [{
eventType: AndroidEvents.ANDROID_VIEW_CLICKED,
eventType: AndroidEvents.VIEW_CLICKED,
checked: aSwitched
}], aOptions);
}
@ -619,7 +619,7 @@ ExpectedValueChange.prototype = Object.create(ExpectedPresent.prototype);
// XXX: Implement Android event?
function ExpectedTextChanged(aValue, aOptions) {
ExpectedPresent.call(this, [{
eventType: AndroidEvents.ANDROID_VIEW_TEXT_CHANGED
eventType: AndroidEvents.VIEW_TEXT_CHANGED
}], aOptions);
}
@ -634,7 +634,7 @@ ExpectedEditState.prototype = Object.create(ExpectedMessage.prototype);
function ExpectedTextSelectionChanged(aStart, aEnd, aOptions) {
ExpectedPresent.call(this, [{
eventType: AndroidEvents.ANDROID_VIEW_TEXT_SELECTION_CHANGED,
eventType: AndroidEvents.VIEW_TEXT_SELECTION_CHANGED,
}], aOptions);
}
@ -643,7 +643,7 @@ ExpectedTextSelectionChanged.prototype =
function ExpectedTextCaretChanged(aFrom, aTo, aOptions) {
ExpectedPresent.call(this, [{
eventType: AndroidEvents.ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
eventType: AndroidEvents.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
fromIndex: aFrom,
toIndex: aTo
}], aOptions);
@ -653,7 +653,7 @@ ExpectedTextCaretChanged.prototype = Object.create(ExpectedPresent.prototype);
function ExpectedAnnouncement(aAnnouncement, aOptions) {
ExpectedPresent.call(this, [{
eventType: AndroidEvents.ANDROID_ANNOUNCEMENT,
eventType: AndroidEvents.ANNOUNCEMENT,
text: [ aAnnouncement],
addedCount: aAnnouncement.length
}], aOptions);

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

@ -57,7 +57,7 @@
var tests = [{
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["hidden I will be hidden"],
"addedCount": "hidden I will be hidden".length,
"removedCount": 0,
@ -71,7 +71,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["hidden I will be hidden"],
"addedCount": "hidden I will be hidden".length,
"removedCount": 0,
@ -86,7 +86,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["I will be shown"],
"addedCount": "I will be shown".length,
"removedCount": 0,
@ -100,7 +100,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["I will be shown"],
"addedCount": "I will be shown".length,
"removedCount": 0,
@ -115,7 +115,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["hidden I will be hidden"],
"addedCount": "hidden I will be hidden".length,
"removedCount": 0,
@ -129,7 +129,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["hidden I will be hidden"],
"addedCount": "hidden I will be hidden".length,
"removedCount": 0,
@ -144,7 +144,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["I will be shown"],
"addedCount": "I will be shown".length,
"removedCount": 0,
@ -158,7 +158,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["I will be shown"],
"addedCount": "I will be shown".length,
"removedCount": 0,
@ -173,7 +173,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["hidden I will be hidden"],
"addedCount": "hidden I will be hidden".length,
"removedCount": 0,
@ -187,7 +187,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["hidden I will be hidden"],
"addedCount": "hidden I will be hidden".length,
"removedCount": 0,
@ -201,7 +201,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["I will be shown"],
"addedCount": "I will be shown".length,
"removedCount": 0,
@ -215,7 +215,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["I will be shown"],
"addedCount": "I will be shown".length,
"removedCount": 0,
@ -229,7 +229,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["Text Added"],
"addedCount": "Text Added".length,
"removedCount": 0,
@ -243,7 +243,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["Text Added"],
"addedCount": "Text Added".length,
"removedCount": 0,
@ -257,7 +257,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["hidden Text Removed"],
"addedCount": "hidden Text Removed".length,
"removedCount": 0,
@ -271,7 +271,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["Descendant Text Added"],
"addedCount": "Descendant Text Added".length,
"removedCount": 0,
@ -285,7 +285,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["Descendant Text Added"],
"addedCount": "Descendant Text Added".length,
"removedCount": 0,
@ -299,7 +299,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["hidden Descendant Text Removed"],
"addedCount": "hidden Descendant Text Removed".length,
"removedCount": 0,
@ -313,7 +313,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["Descendant Text Added"],
"addedCount": "Descendant Text Added".length,
"removedCount": 0,
@ -327,7 +327,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["Descendant Text Added"],
"addedCount": "Descendant Text Added".length,
"removedCount": 0,
@ -341,7 +341,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["hidden Descendant Text Removed"],
"addedCount": "hidden Descendant Text Removed".length,
"removedCount": 0,
@ -355,7 +355,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["I am replaced main"],
"addedCount": "I am replaced main".length,
"removedCount": 0,
@ -370,7 +370,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["I am a replaced text"],
"addedCount": "I am a replaced text".length,
"removedCount": 0,
@ -384,7 +384,7 @@
}
}, {
expected: [{
"eventType": AndroidEvents.ANDROID_ANNOUNCEMENT,
"eventType": AndroidEvents.ANNOUNCEMENT,
"text": ["I am a replaced text"],
"addedCount": "I am a replaced text".length,
"removedCount": 0,

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

@ -0,0 +1,147 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#include "LauncherProcessWin.h"
#include <string.h>
#include "mozilla/Attributes.h"
#include "mozilla/CmdLineAndEnvUtils.h"
#include "mozilla/Maybe.h"
#include "mozilla/SafeMode.h"
#include "mozilla/UniquePtr.h"
#include "nsWindowsHelpers.h"
#include <windows.h>
#include "ProcThreadAttributes.h"
/**
* At this point the child process has been created in a suspended state. Any
* additional startup work (eg, blocklist setup) should go here.
*
* @return true if browser startup should proceed, otherwise false.
*/
static bool
PostCreationSetup(HANDLE aChildProcess, HANDLE aChildMainThread,
const bool aIsSafeMode)
{
return true;
}
/**
* Any mitigation policies that should be set on the browser process should go
* here.
*/
static void
SetMitigationPolicies(mozilla::ProcThreadAttributes& aAttrs, const bool aIsSafeMode)
{
}
static void
ShowError(DWORD aError = ::GetLastError())
{
if (aError == ERROR_SUCCESS) {
return;
}
LPWSTR rawMsgBuf = nullptr;
DWORD result = ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
aError, 0, reinterpret_cast<LPWSTR>(&rawMsgBuf),
0, nullptr);
if (!result) {
return;
}
::MessageBoxW(nullptr, rawMsgBuf, L"Firefox", MB_OK | MB_ICONERROR);
::LocalFree(rawMsgBuf);
}
namespace mozilla {
// Eventually we want to be able to set a build config flag such that, when set,
// this function will always return true.
bool
RunAsLauncherProcess(int& argc, wchar_t** argv)
{
return CheckArg(argc, argv, L"launcher",
static_cast<const wchar_t**>(nullptr),
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
}
int
LauncherMain(int argc, wchar_t* argv[])
{
UniquePtr<wchar_t[]> cmdLine(MakeCommandLine(argc, argv));
if (!cmdLine) {
return 1;
}
const Maybe<bool> isSafeMode = IsSafeModeRequested(argc, argv,
SafeModeFlag::None);
if (!isSafeMode) {
ShowError(ERROR_INVALID_PARAMETER);
return 1;
}
ProcThreadAttributes attrs;
SetMitigationPolicies(attrs, isSafeMode.value());
HANDLE stdHandles[] = {
::GetStdHandle(STD_INPUT_HANDLE),
::GetStdHandle(STD_OUTPUT_HANDLE),
::GetStdHandle(STD_ERROR_HANDLE)
};
attrs.AddInheritableHandles(stdHandles);
DWORD creationFlags = CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT;
STARTUPINFOEXW siex;
Maybe<bool> attrsOk = attrs.AssignTo(siex);
if (!attrsOk) {
ShowError();
return 1;
}
BOOL inheritHandles = FALSE;
if (attrsOk.value()) {
creationFlags |= EXTENDED_STARTUPINFO_PRESENT;
siex.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
siex.StartupInfo.hStdInput = stdHandles[0];
siex.StartupInfo.hStdOutput = stdHandles[1];
siex.StartupInfo.hStdError = stdHandles[2];
// Since attrsOk == true, we have successfully set the handle inheritance
// whitelist policy, so only the handles added to attrs will be inherited.
inheritHandles = TRUE;
}
PROCESS_INFORMATION pi = {};
if (!::CreateProcessW(argv[0], cmdLine.get(), nullptr, nullptr, inheritHandles,
creationFlags, nullptr, nullptr, &siex.StartupInfo, &pi)) {
ShowError();
return 1;
}
nsAutoHandle process(pi.hProcess);
nsAutoHandle mainThread(pi.hThread);
if (!PostCreationSetup(process.get(), mainThread.get(), isSafeMode.value()) ||
::ResumeThread(mainThread.get()) == static_cast<DWORD>(-1)) {
ShowError();
::TerminateProcess(process.get(), 1);
return 1;
}
return 0;
}
} // namespace mozilla

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

@ -0,0 +1,18 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#ifndef mozilla_LauncherProcessWin_h
#define mozilla_LauncherProcessWin_h
namespace mozilla {
bool RunAsLauncherProcess(int& argc, wchar_t* argv[]);
int LauncherMain(int argc, wchar_t* argv[]);
} // namespace mozilla
#endif // mozilla_LauncherProcessWin_h

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

@ -0,0 +1,153 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ProcThreadAttributes_h
#define mozilla_ProcThreadAttributes_h
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "mozilla/Move.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Vector.h"
#include <windows.h>
namespace mozilla {
class MOZ_RAII ProcThreadAttributes final
{
struct ProcThreadAttributeListDeleter
{
void operator()(LPPROC_THREAD_ATTRIBUTE_LIST aList)
{
::DeleteProcThreadAttributeList(aList);
delete[] reinterpret_cast<char*>(aList);
}
};
using ProcThreadAttributeListPtr =
UniquePtr<_PROC_THREAD_ATTRIBUTE_LIST, ProcThreadAttributeListDeleter>;
public:
ProcThreadAttributes()
: mMitigationPolicies(0)
{
}
~ProcThreadAttributes() = default;
ProcThreadAttributes(const ProcThreadAttributes&) = delete;
ProcThreadAttributes(ProcThreadAttributes&&) = delete;
ProcThreadAttributes& operator=(const ProcThreadAttributes&) = delete;
ProcThreadAttributes& operator=(ProcThreadAttributes&&) = delete;
void AddMitigationPolicy(DWORD64 aPolicy)
{
mMitigationPolicies |= aPolicy;
}
bool AddInheritableHandle(HANDLE aHandle)
{
return mInheritableHandles.append(aHandle);
}
template <size_t N>
bool AddInheritableHandles(HANDLE (&aHandles)[N])
{
return mInheritableHandles.append(aHandles, N);
}
/**
* @return Some(false) if the STARTUPINFOEXW::lpAttributeList was set to null
* as expected based on the state of |this|;
* Some(true) if the STARTUPINFOEXW::lpAttributeList was set to
* non-null;
* Nothing() if something went wrong in the assignment and we should
* not proceed.
*/
Maybe<bool> AssignTo(STARTUPINFOEXW& aSiex)
{
ZeroMemory(&aSiex, sizeof(STARTUPINFOEXW));
// We'll set the size to sizeof(STARTUPINFOW) until we determine whether the
// extended fields will be used.
aSiex.StartupInfo.cb = sizeof(STARTUPINFOW);
DWORD numAttributes = 0;
if (mMitigationPolicies) {
++numAttributes;
}
if (!mInheritableHandles.empty()) {
++numAttributes;
}
if (!numAttributes) {
return Some(false);
}
SIZE_T listSize = 0;
if (!::InitializeProcThreadAttributeList(nullptr, numAttributes, 0,
&listSize) &&
::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
return Nothing();
}
auto buf = MakeUnique<char[]>(listSize);
LPPROC_THREAD_ATTRIBUTE_LIST tmpList =
reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(buf.get());
if (!::InitializeProcThreadAttributeList(tmpList, numAttributes, 0,
&listSize)) {
return Nothing();
}
// Transfer buf to a ProcThreadAttributeListPtr - now that the list is
// initialized, we are no longer dealing with a plain old char array. We
// must now deinitialize the attribute list before deallocating the
// underlying buffer.
ProcThreadAttributeListPtr
attrList(reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(buf.release()));
if (mMitigationPolicies) {
if (!::UpdateProcThreadAttribute(attrList.get(), 0,
PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY,
&mMitigationPolicies,
sizeof(mMitigationPolicies), nullptr,
nullptr)) {
return Nothing();
}
}
if (!mInheritableHandles.empty()) {
if (!::UpdateProcThreadAttribute(attrList.get(), 0,
PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
mInheritableHandles.begin(),
mInheritableHandles.length() * sizeof(HANDLE),
nullptr, nullptr)) {
return Nothing();
}
}
mAttrList = Move(attrList);
aSiex.lpAttributeList = mAttrList.get();
aSiex.StartupInfo.cb = sizeof(STARTUPINFOEXW);
return Some(true);
}
private:
static const uint32_t kNumInline = 3; // Inline storage for the std handles
DWORD64 mMitigationPolicies;
Vector<HANDLE, kNumInline> mInheritableHandles;
ProcThreadAttributeListPtr mAttrList;
};
} // namespace mozilla
#endif // mozilla_ProcThreadAttributes_h

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

@ -62,6 +62,9 @@ if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
if CONFIG['OS_ARCH'] == 'WINNT':
RCINCLUDE = 'splash.rc'
DEFINES['MOZ_PHOENIX'] = True
SOURCES += [
'LauncherProcessWin.cpp',
]
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
# For sandbox includes and the include dependencies those have

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

@ -23,6 +23,8 @@
#include "nsIFile.h"
#ifdef XP_WIN
#include "LauncherProcessWin.h"
#define XRE_WANT_ENVIRON
#define strcasecmp _stricmp
#ifdef MOZ_SANDBOX

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

@ -8,7 +8,14 @@
PR_SetEnv requires its argument to be leaked, but does not appear on stacks. (See bug 793534.)
Memcheck:Leak
...
fun:_ZL9SaveToEnvPKc
fun:_ZN7mozilla9SaveToEnvEPKc
...
}
{
PR_SetEnv requires its argument to be leaked, but does not appear on stacks. (See bug 793534.)
Memcheck:Leak
...
fun:SaveToEnv
...
}
{

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

@ -1,12 +1,12 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Version 45.1
Version 46
Comparison: https://github.com/devtools-html/debugger.html/compare/release-45...release-45.1
Comparison: https://github.com/devtools-html/debugger.html/compare/release-45.1...release-46
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.0
- babel-plugin-transform-es2015-modules-commonjs @6.26.2
- babel-preset-react @6.24.1
- react @16.2.0
- react-dom @16.2.0

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

@ -1965,18 +1965,6 @@ html .toggle-button.end.vertical svg {
--comment-node-color: var(--theme-comment);
}
.theme-firebug {
--number-color: #000088;
--string-color: #FF0000;
--null-color: #787878;
--object-color: DarkGreen;
--caption-color: #444444;
--location-color: #555555;
--source-link-color: blue;
--node-color: rgb(0, 0, 136);
--reference-color: rgb(102, 102, 255);
}
/******************************************************************************/
.inline {
@ -2012,7 +2000,8 @@ html .toggle-button.end.vertical svg {
color: var(--string-color);
}
.objectBox-string a, .objectBox-string a:visited {
.objectBox-string a,
.objectBox-string a:visited {
color: currentColor;
text-decoration: none;
font-style: italic;
@ -2205,7 +2194,7 @@ button.open-inspector {
display: inline-block;
background-color: var(--comment-node-color);
height: 16px;
margin-left: .25em;
margin-left: 0.25em;
vertical-align: middle;
}
@ -2223,7 +2212,7 @@ button.jump-definition {
display: inline-block;
background-color: var(--comment-node-color);
height: 16px;
margin-left: .25em;
margin-left: 0.25em;
vertical-align: middle;
}
@ -2278,6 +2267,16 @@ button.jump-definition {
display: inline-block;
vertical-align: middle;
}
/* Focused styles */
.tree.object-inspector .tree-node.focused * {
color: inherit;
}
.tree-node.focused button.jump-definition,
.tree-node.focused button.open-inspector {
background-color: currentColor;
}
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -12,10 +12,13 @@ add_task(async function() {
await waitForPaused(dbg);
await waitForLoadedSource(dbg, "switching-02");
// MAP_FRAMES triggers a new Scopes panel render cycle, which introduces
// a race condition with the click event on the foo node.
await waitForDispatch(dbg, "MAP_FRAMES");
is(getLabel(dbg, 1), "secondCall");
is(getLabel(dbg, 2), "<this>");
is(getLabel(dbg, 4), "foo()");
await toggleScopeNode(dbg, 4);
is(getLabel(dbg, 5), "arguments");

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

@ -56,6 +56,5 @@ add_task(async function() {
// selecting another source keeps search open
await selectSource(dbg, "simple2");
pressKey(dbg, "Enter");
is(state.posFrom.line, 0);
ok(findElement(dbg, "searchField"), "Search field is still visible");
});

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

@ -1073,7 +1073,8 @@ const selectors = {
outlineItem: i =>
`.outline-list__element:nth-child(${i}) .function-signature`,
outlineItems: ".outline-list__element",
conditionalPanelInput: ".conditional-breakpoint-panel input"
conditionalPanelInput: ".conditional-breakpoint-panel input",
searchField: ".search-field",
};
function getSelector(elementName, ...args) {

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

@ -1,3 +1,87 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
.tree {
overflow: auto;
}
.tree.inline {
display: inline-block;
}
.tree.nowrap {
white-space: nowrap;
}
.tree.noselect {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.tree .tree-node {
display: flex;
}
.tree .tree-node:not(.focused):hover {
background-color: var(--theme-selection-background-hover);
}
.tree-indent {
display: inline-block;
width: 12px;
margin-inline-start: 5px;
border-inline-start: 1px solid #A2D1FF;
flex-shrink: 0;
}
/* Align with expandables siblings (where we have the arrow) */
.tree-node[data-expandable="false"] .tree-indent:last-of-type {
margin-inline-end: 15px;
}
/* For non expandable root nodes, we don't have .tree-indent elements, so we declare
the margin on the start of the node */
.tree-node[data-expandable="false"][aria-level="1"] {
padding-inline-start: 15px
}
.tree .tree-node[data-expandable="true"] {
cursor: default;
}
.tree-node img.arrow {
mask: url("chrome://devtools/skin/images/devtools-components/arrow.svg") no-repeat;
mask-size: 100%;
width: 9px;
height: 9px;
margin-inline-start: 1px;
margin-inline-end: 4px;
background-color: var(--theme-splitter-color, #9B9B9B);
transform: rotate(-90deg);
transition: transform 0.125s ease;
align-self: center;
}
html[dir="rtl"] .tree-node img.arrow {
transform: rotate(90deg);
}
.tree-node img.arrow.expanded.expanded {
transform: rotate(0deg);
}
.tree .tree-node.focused {
color: white;
background-color: var(--theme-selection-background, #0a84ff);
}
.tree-node.focused img.arrow {
background-color: currentColor;
}
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -52,7 +136,8 @@
color: var(--string-color);
}
.objectBox-string a, .objectBox-string a:visited {
.objectBox-string a,
.objectBox-string a:visited {
color: currentColor;
text-decoration: none;
font-style: italic;
@ -78,6 +163,12 @@
margin-top: 3px;
}
.objectBox-stackTrace-fn::before {
content: "\3BB"; /* The "lambda" symbol */
display: inline-block;
margin: 0 0.3em;
}
.objectBox-stackTrace-fn {
color: var(--console-output-color);
padding-inline-start: 17px;
@ -239,7 +330,7 @@ button.open-inspector {
display: inline-block;
background-color: var(--comment-node-color);
height: 16px;
margin-left: .25em;
margin-left: 0.25em;
vertical-align: middle;
}
@ -257,7 +348,7 @@ button.jump-definition {
display: inline-block;
background-color: var(--comment-node-color);
height: 16px;
margin-left: .25em;
margin-left: 0.25em;
vertical-align: middle;
}
@ -274,90 +365,6 @@ button.jump-definition {
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
.tree {
overflow: auto;
}
.tree.inline {
display: inline-block;
}
.tree.nowrap {
white-space: nowrap;
}
.tree.noselect {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.tree .tree-node {
display: flex;
}
.tree .tree-node:not(.focused):hover {
background-color: var(--theme-selection-background-hover);
}
.tree-indent {
display: inline-block;
width: 12px;
margin-inline-start: 5px;
border-inline-start: 1px solid #A2D1FF;
flex-shrink: 0;
}
/* Align with expandables siblings (where we have the arrow) */
.tree-node[data-expandable="false"] .tree-indent:last-of-type {
margin-inline-end: 15px;
}
/* For non expandable root nodes, we don't have .tree-indent elements, so we declare
the margin on the start of the node */
.tree-node[data-expandable="false"][aria-level="1"] {
padding-inline-start: 15px
}
.tree .tree-node[data-expandable="true"] {
cursor: default;
}
.tree-node img.arrow {
mask: url("chrome://devtools/skin/images/devtools-components/arrow.svg") no-repeat;
mask-size: 100%;
width: 9px;
height: 9px;
margin-inline-start: 1px;
margin-inline-end: 4px;
background-color: var(--theme-splitter-color, #9B9B9B);
transform: rotate(-90deg);
transition: transform 0.125s ease;
align-self: center;
}
html[dir="rtl"] .tree-node img.arrow {
transform: rotate(90deg);
}
.tree-node img.arrow.expanded.expanded {
transform: rotate(0deg);
}
.tree .tree-node.focused {
color: white;
background-color: var(--theme-selection-background, #0a84ff);
}
.tree-node.focused img.arrow {
background-color: currentColor;
}
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
.tree.object-inspector .node.object-node {
display: inline-block;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -7,7 +7,7 @@
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
@ -67,158 +67,22 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ __webpack_require__.p = "/assets/build";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 15);
/******/ return __webpack_require__(__webpack_require__.s = 3646);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
/******/ ({
var charenc = {
// UTF-8 encoding
utf8: {
// Convert a string to a byte array
stringToBytes: function(str) {
return charenc.bin.stringToBytes(unescape(encodeURIComponent(str)));
},
// Convert a byte array to a string
bytesToString: function(bytes) {
return decodeURIComponent(escape(charenc.bin.bytesToString(bytes)));
}
},
// Binary encoding
bin: {
// Convert a string to a byte array
stringToBytes: function(str) {
for (var bytes = [], i = 0; i < str.length; i++)
bytes.push(str.charCodeAt(i) & 0xFF);
return bytes;
},
// Convert a byte array to a string
bytesToString: function(bytes) {
for (var str = [], i = 0; i < bytes.length; i++)
str.push(String.fromCharCode(bytes[i]));
return str.join('');
}
}
};
module.exports = charenc;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const networkRequest = __webpack_require__(7);
const workerUtils = __webpack_require__(8);
module.exports = {
networkRequest,
workerUtils
};
/***/ }),
/* 2 */,
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const md5 = __webpack_require__(4);
function originalToGeneratedId(originalId) {
const match = originalId.match(/(.*)\/originalSource/);
return match ? match[1] : "";
}
function generatedToOriginalId(generatedId, url) {
return `${generatedId}/originalSource-${md5(url)}`;
}
function isOriginalId(id) {
return !!id.match(/\/originalSource/);
}
function isGeneratedId(id) {
return !isOriginalId(id);
}
/**
* Trims the query part or reference identifier of a URL string, if necessary.
*/
function trimUrlQuery(url) {
let length = url.length;
let q1 = url.indexOf("?");
let q2 = url.indexOf("&");
let q3 = url.indexOf("#");
let q = Math.min(q1 != -1 ? q1 : length, q2 != -1 ? q2 : length, q3 != -1 ? q3 : length);
return url.slice(0, q);
}
// Map suffix to content type.
const contentMap = {
"js": "text/javascript",
"jsm": "text/javascript",
"mjs": "text/javascript",
"ts": "text/typescript",
"tsx": "text/typescript-jsx",
"jsx": "text/jsx",
"coffee": "text/coffeescript",
"elm": "text/elm",
"cljs": "text/x-clojure"
};
/**
* Returns the content type for the specified URL. If no specific
* content type can be determined, "text/plain" is returned.
*
* @return String
* The content type.
*/
function getContentType(url) {
url = trimUrlQuery(url);
let dot = url.lastIndexOf(".");
if (dot >= 0) {
let name = url.substring(dot + 1);
if (name in contentMap) {
return contentMap[name];
}
}
return "text/plain";
}
module.exports = {
originalToGeneratedId,
generatedToOriginalId,
isOriginalId,
isGeneratedId,
getContentType,
contentMapForTesting: contentMap
};
/***/ }),
/* 4 */
/***/ 248:
/***/ (function(module, exports, __webpack_require__) {
(function(){
var crypt = __webpack_require__(5),
utf8 = __webpack_require__(0).utf8,
isBuffer = __webpack_require__(6),
bin = __webpack_require__(0).bin,
var crypt = __webpack_require__(249),
utf8 = __webpack_require__(250).utf8,
isBuffer = __webpack_require__(251),
bin = __webpack_require__(250).bin,
// The core
md5 = function (message, options) {
@ -377,7 +241,8 @@ module.exports = {
/***/ }),
/* 5 */
/***/ 249:
/***/ (function(module, exports) {
(function() {
@ -479,13 +344,54 @@ module.exports = {
/***/ }),
/* 6 */
/***/ 250:
/***/ (function(module, exports) {
var charenc = {
// UTF-8 encoding
utf8: {
// Convert a string to a byte array
stringToBytes: function(str) {
return charenc.bin.stringToBytes(unescape(encodeURIComponent(str)));
},
// Convert a byte array to a string
bytesToString: function(bytes) {
return decodeURIComponent(escape(charenc.bin.bytesToString(bytes)));
}
},
// Binary encoding
bin: {
// Convert a string to a byte array
stringToBytes: function(str) {
for (var bytes = [], i = 0; i < str.length; i++)
bytes.push(str.charCodeAt(i) & 0xFF);
return bytes;
},
// Convert a byte array to a string
bytesToString: function(bytes) {
for (var str = [], i = 0; i < bytes.length; i++)
str.push(String.fromCharCode(bytes[i]));
return str.join('');
}
}
};
module.exports = charenc;
/***/ }),
/***/ 251:
/***/ (function(module, exports) {
/*!
* Determine if an object is a Buffer
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
@ -506,13 +412,177 @@ function isSlowBuffer (obj) {
/***/ }),
/* 7 */
/***/ (function(module, exports) {
/***/ 3646:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
const {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId
} = __webpack_require__(3652);
const {
workerUtils: { WorkerDispatcher }
} = __webpack_require__(3651);
const dispatcher = new WorkerDispatcher();
const getOriginalURLs = dispatcher.task("getOriginalURLs");
const getGeneratedRanges = dispatcher.task("getGeneratedRanges", {
queue: true
});
const getGeneratedLocation = dispatcher.task("getGeneratedLocation", {
queue: true
});
const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", {
queue: true
});
const getOriginalLocation = dispatcher.task("getOriginalLocation");
const getLocationScopes = dispatcher.task("getLocationScopes");
const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
const applySourceMap = dispatcher.task("applySourceMap");
const clearSourceMaps = dispatcher.task("clearSourceMaps");
const hasMappedSource = dispatcher.task("hasMappedSource");
module.exports = {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId,
hasMappedSource,
getOriginalURLs,
getGeneratedRanges,
getGeneratedLocation,
getAllGeneratedLocations,
getOriginalLocation,
getLocationScopes,
getOriginalSourceText,
applySourceMap,
clearSourceMaps,
startSourceMapWorker: dispatcher.start.bind(dispatcher),
stopSourceMapWorker: dispatcher.stop.bind(dispatcher)
};
/***/ }),
/***/ 3651:
/***/ (function(module, exports, __webpack_require__) {
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const networkRequest = __webpack_require__(3653);
const workerUtils = __webpack_require__(3654);
module.exports = {
networkRequest,
workerUtils
};
/***/ }),
/***/ 3652:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
const md5 = __webpack_require__(248);
function originalToGeneratedId(originalId) {
const match = originalId.match(/(.*)\/originalSource/);
return match ? match[1] : "";
}
function generatedToOriginalId(generatedId, url) {
return `${generatedId}/originalSource-${md5(url)}`;
}
function isOriginalId(id) {
return !!id.match(/\/originalSource/);
}
function isGeneratedId(id) {
return !isOriginalId(id);
}
/**
* Trims the query part or reference identifier of a URL string, if necessary.
*/
function trimUrlQuery(url) {
const length = url.length;
const q1 = url.indexOf("?");
const q2 = url.indexOf("&");
const q3 = url.indexOf("#");
const q = Math.min(q1 != -1 ? q1 : length, q2 != -1 ? q2 : length, q3 != -1 ? q3 : length);
return url.slice(0, q);
}
// Map suffix to content type.
const contentMap = {
js: "text/javascript",
jsm: "text/javascript",
mjs: "text/javascript",
ts: "text/typescript",
tsx: "text/typescript-jsx",
jsx: "text/jsx",
coffee: "text/coffeescript",
elm: "text/elm",
cljs: "text/x-clojure"
};
/**
* Returns the content type for the specified URL. If no specific
* content type can be determined, "text/plain" is returned.
*
* @return String
* The content type.
*/
function getContentType(url) {
url = trimUrlQuery(url);
const dot = url.lastIndexOf(".");
if (dot >= 0) {
const name = url.substring(dot + 1);
if (name in contentMap) {
return contentMap[name];
}
}
return "text/plain";
}
module.exports = {
originalToGeneratedId,
generatedToOriginalId,
isOriginalId,
isGeneratedId,
getContentType,
contentMapForTesting: contentMap
};
/***/ }),
/***/ 3653:
/***/ (function(module, exports) {
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
function networkRequest(url, opts) {
return fetch(url, {
cache: opts.loadFromCache ? "default" : "no-cache"
@ -527,7 +597,8 @@ function networkRequest(url, opts) {
module.exports = networkRequest;
/***/ }),
/* 8 */
/***/ 3654:
/***/ (function(module, exports) {
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
@ -537,7 +608,7 @@ function WorkerDispatcher() {
this.worker = null;
} /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
WorkerDispatcher.prototype = {
start(url) {
@ -577,7 +648,11 @@ WorkerDispatcher.prototype = {
calls.length = 0;
const id = this.msgId++;
this.worker.postMessage({ id, method, calls: items.map(item => item[0]) });
this.worker.postMessage({
id,
method,
calls: items.map(item => item[0])
});
const listener = ({ data: result }) => {
if (result.id !== id) {
@ -620,9 +695,8 @@ function workerHandler(publicInterface) {
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => ({ error: err.toString() }));
} else {
return { response };
}
return { response };
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
@ -639,7 +713,7 @@ function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker
var _ref = _asyncToGenerator(function* (id, tasks) {
let isWorking = true;
const intervalId = setTimeout(function () {
const timeoutId = setTimeout(function () {
isWorking = false;
}, timeout);
@ -650,7 +724,7 @@ function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker
results.push(result);
}
worker.postMessage({ id, status: "pending", data: results });
clearInterval(intervalId);
clearTimeout(timeoutId);
if (tasks.length !== 0) {
yield streamingWorker(id, tasks);
@ -692,61 +766,7 @@ module.exports = {
streamingWorkerHandler
};
/***/ }),
/* 9 */,
/* 10 */,
/* 11 */,
/* 12 */,
/* 13 */,
/* 14 */,
/* 15 */
/***/ (function(module, exports, __webpack_require__) {
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId
} = __webpack_require__(3);
const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1);
const dispatcher = new WorkerDispatcher();
const getOriginalURLs = dispatcher.task("getOriginalURLs");
const getGeneratedRanges = dispatcher.task("getGeneratedRanges", { queue: true });
const getGeneratedLocation = dispatcher.task("getGeneratedLocation", { queue: true });
const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", { queue: true });
const getOriginalLocation = dispatcher.task("getOriginalLocation");
const getLocationScopes = dispatcher.task("getLocationScopes");
const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
const applySourceMap = dispatcher.task("applySourceMap");
const clearSourceMaps = dispatcher.task("clearSourceMaps");
const hasMappedSource = dispatcher.task("hasMappedSource");
module.exports = {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId,
hasMappedSource,
getOriginalURLs,
getGeneratedRanges,
getGeneratedLocation,
getAllGeneratedLocations,
getOriginalLocation,
getLocationScopes,
getOriginalSourceText,
applySourceMap,
clearSourceMaps,
startSourceMapWorker: dispatcher.start.bind(dispatcher),
stopSourceMapWorker: dispatcher.stop.bind(dispatcher)
};
/***/ })
/******/ ]);
/******/ });
});

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -606,7 +606,7 @@ static struct lutmABType *read_tag_lutmABType(struct mem_source *src, struct tag
// 24bits * 3 won't overflow either
clut_size = clut_size * num_out_channels;
if (clut_size > MAX_CLUT_SIZE)
if (clut_size == 0 || clut_size > MAX_CLUT_SIZE)
return NULL;
lut = malloc(sizeof(struct lutmABType) + (clut_size) * sizeof(float));

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

@ -2353,11 +2353,6 @@ extern "C" {
-> bool;
}
#[no_mangle]
pub extern "C" fn wr_shutdown_log_for_gpu_process() {
// log does not support shutdown
}
#[no_mangle]
pub extern "C" fn wr_root_scroll_node_id() -> usize {
// The PipelineId doesn't matter here, since we just want the numeric part of the id

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

@ -1587,10 +1587,6 @@ void wr_set_item_tag(WrState *aState,
uint16_t aHitInfo)
WR_FUNC;
WR_INLINE
void wr_shutdown_log_for_gpu_process()
WR_FUNC;
WR_INLINE
void wr_state_delete(WrState *aState)
WR_DESTRUCTOR_SAFE_FUNC;

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

@ -979,6 +979,10 @@ TraceParser(JSTracer* trc, AutoGCRooter* parser)
bool
ParserBase::setSourceMapInfo()
{
// Not all clients initialize ss. Can't update info to an object that isn't there.
if (!ss)
return true;
if (anyChars.hasDisplayURL()) {
if (!ss->setDisplayURL(context, anyChars.displayURL()))
return false;

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

@ -14,6 +14,7 @@ import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.dlc.catalog.DownloadContent;
import org.mozilla.gecko.dlc.catalog.DownloadContentBuilder;
import org.mozilla.gecko.dlc.catalog.DownloadContentCatalog;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@ -223,7 +224,7 @@ public class TestDownloadAction {
verify(connection).getInputStream();
verify(connection).setRequestProperty("Range", "bytes=1337-");
Assert.assertEquals("HelloWorld", new String(outputStream.toByteArray(), "UTF-8"));
Assert.assertEquals("HelloWorld", new String(outputStream.toByteArray(), StringUtils.UTF_8));
verify(action).openFile(eq(temporaryFile), eq(true));
verify(catalog).markAsDownloaded(content);
@ -635,7 +636,7 @@ public class TestDownloadAction {
HttpURLConnection connection = mock(HttpURLConnection.class);
doReturn(statusCode).when(connection).getResponseCode();
doReturn(new ByteArrayInputStream(content.getBytes("UTF-8"))).when(connection).getInputStream();
doReturn(new ByteArrayInputStream(content.getBytes(StringUtils.UTF_8))).when(connection).getInputStream();
return connection;
}

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

@ -13,6 +13,7 @@ import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RobolectricTestRunner;
import java.io.FileNotFoundException;
@ -37,7 +38,7 @@ public class TestDownloadContentCatalog {
@Test
public void testUntouchedCatalogHasNotChangedAndWillNotBePersisted() throws Exception {
AtomicFile file = mock(AtomicFile.class);
doReturn("{content:[]}".getBytes("UTF-8")).when(file).readFully();
doReturn("{content:[]}".getBytes(StringUtils.UTF_8)).when(file).readFully();
DownloadContentCatalog catalog = spy(new DownloadContentCatalog(file));
catalog.loadFromDisk();

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

@ -7,6 +7,7 @@ import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RuntimeEnvironment;
import java.io.File;
@ -57,7 +58,7 @@ public class TestPushState {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write("}".getBytes("UTF-8"));
fos.write("}".getBytes(StringUtils.UTF_8));
} finally {
if (fos != null) {
fos.close();

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

@ -43,6 +43,7 @@ import org.mozilla.gecko.sync.SynchronizerConfiguration;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.repositories.android.RepoUtils;
import org.mozilla.gecko.util.FileUtils;
import org.mozilla.gecko.util.StringUtils;
import static org.mozilla.gecko.db.DBUtils.qualifyColumn;
@ -1782,18 +1783,13 @@ public class BrowserDatabaseHelper extends SQLiteOpenHelper {
@RobocopTarget
public static String getReaderCacheFileNameForURL(String url) {
try {
// On KitKat and above we can use java.nio.charset.StandardCharsets.UTF_8 in place of "UTF8"
// which avoids having to handle UnsupportedCodingException
byte[] utf8 = url.getBytes("UTF8");
byte[] utf8 = url.getBytes(StringUtils.UTF_8);
final MessageDigest digester = MessageDigest.getInstance("MD5");
byte[] hash = digester.digest(utf8);
final String hashString = new Base32().encodeAsString(hash);
return hashString.substring(0, hashString.indexOf('=')) + ".json";
} catch (UnsupportedEncodingException e) {
// This should never happen
throw new IllegalStateException("UTF8 encoding not available - can't process readercache filename");
} catch (NoSuchAlgorithmException e) {
// This should also never happen
throw new IllegalStateException("MD5 digester unavailable - can't process readercache filename");

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

@ -498,7 +498,7 @@ public class LoginsProvider extends SharedBrowserDatabaseProvider {
private String encrypt(@NonNull String initialValue) {
try {
final Cipher cipher = getCipher(Cipher.ENCRYPT_MODE);
return Base64.encodeToString(cipher.doFinal(initialValue.getBytes("UTF-8")), Base64.URL_SAFE);
return Base64.encodeToString(cipher.doFinal(initialValue.getBytes(StringUtils.UTF_8)), Base64.URL_SAFE);
} catch (Exception e) {
debug("encryption failed : " + e);
throw new IllegalStateException("Logins encryption failed", e);
@ -509,7 +509,7 @@ public class LoginsProvider extends SharedBrowserDatabaseProvider {
try {
final Cipher cipher = getCipher(Cipher.DECRYPT_MODE);
return new String(cipher.doFinal(Base64.decode(
initialValue.getBytes("UTF-8"), Base64.URL_SAFE)), StringUtils.UTF_8);
initialValue.getBytes(StringUtils.UTF_8), Base64.URL_SAFE)), StringUtils.UTF_8);
} catch (Exception e) {
debug("Decryption failed : " + e);
throw new IllegalStateException("Logins decryption failed", e);

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

@ -14,12 +14,12 @@ import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.util.StringUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
@ -218,7 +218,7 @@ public class DownloadContentCatalog {
JSONObject catalog;
synchronized (file) {
catalog = new JSONObject(new String(file.readFully(), "UTF-8"));
catalog = new JSONObject(new String(file.readFully(), StringUtils.UTF_8));
}
JSONArray array = catalog.getJSONArray(JSON_KEY_CONTENT);
@ -233,10 +233,6 @@ public class DownloadContentCatalog {
Log.w(LOGTAG, "Unable to parse catalog JSON. Re-creating empty catalog.", e);
loadedContent = new ArrayMap<>();
hasCatalogChanged = true; // Indicate that we want to persist the new catalog
} catch (UnsupportedEncodingException e) {
AssertionError error = new AssertionError("Should not happen: This device does not speak UTF-8");
error.initCause(e);
throw error;
} catch (IOException e) {
Log.d(LOGTAG, "Can't read catalog due to IOException", e);
}
@ -275,15 +271,11 @@ public class DownloadContentCatalog {
JSONObject catalog = new JSONObject();
catalog.put(JSON_KEY_CONTENT, array);
outputStream.write(catalog.toString().getBytes("UTF-8"));
outputStream.write(catalog.toString().getBytes(StringUtils.UTF_8));
file.finishWrite(outputStream);
hasCatalogChanged = false;
} catch (UnsupportedEncodingException e) {
AssertionError error = new AssertionError("Should not happen: This device does not speak UTF-8");
error.initCause(e);
throw error;
} catch (IOException | JSONException e) {
Log.e(LOGTAG, "IOException during writing catalog", e);

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

@ -19,12 +19,12 @@ import org.mozilla.gecko.icons.IconRequest;
import org.mozilla.gecko.icons.IconResponse;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.util.IOUtils;
import org.mozilla.gecko.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
/**
@ -257,10 +257,10 @@ public class DiskStorage {
return null;
}
byte[] data = prefix.getBytes("UTF-8");
byte[] data = prefix.getBytes(StringUtils.UTF_8);
NativeCrypto.sha256update(ctx, data, data.length);
data = url.getBytes("UTF-8");
data = url.getBytes(StringUtils.UTF_8);
NativeCrypto.sha256update(ctx, data, data.length);
return Utils.byte2Hex(NativeCrypto.sha256finalize(ctx));
} catch (NoClassDefFoundError | ExceptionInInitializerError error) {
@ -269,15 +269,13 @@ public class DiskStorage {
// we will have a lot of other problems if we can't load libmozglue.so
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(prefix.getBytes("UTF-8"));
md.update(url.getBytes("UTF-8"));
md.update(prefix.getBytes(StringUtils.UTF_8));
md.update(url.getBytes(StringUtils.UTF_8));
return Utils.byte2Hex(md.digest());
} catch (Exception e) {
// Just give up. And let everyone know.
throw new RuntimeException(e);
}
} catch (UnsupportedEncodingException e) {
throw new AssertionError("Should not happen: Device does not understand UTF-8");
}
}

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

@ -13,6 +13,7 @@ import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.util.StringUtils;
import java.io.File;
import java.io.FileNotFoundException;
@ -46,7 +47,7 @@ public class PushState {
file = new AtomicFile(new File(context.getApplicationInfo().dataDir, fileName));
synchronized (file) {
try {
final String s = new String(file.readFully(), "UTF-8");
final String s = new String(file.readFully(), StringUtils.UTF_8);
final JSONObject temp = new JSONObject(s);
if (temp.optLong("version", 0L) != VERSION) {
throw new JSONException("Unknown version!");
@ -91,7 +92,7 @@ public class PushState {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = file.startWrite();
fileOutputStream.write(toJSONObject().toString().getBytes("UTF-8"));
fileOutputStream.write(toJSONObject().toString().getBytes(StringUtils.UTF_8));
file.finishWrite(fileOutputStream);
return true;
} catch (JSONException | IOException e) {

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

@ -79,6 +79,8 @@ class GeckoViewModule {
}
self.messageManager.removeMessageListener("GeckoView:ContentRegistered",
listener);
self.messageManager.sendAsyncMessage("GeckoView:UpdateSettings",
self.settings);
self._eventProxy.enableQueuing(false);
self._eventProxy.dispatchQueuedEvents();
});

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

@ -6,6 +6,7 @@ package org.mozilla.gecko.background.fxa;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.util.StringUtils;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
@ -25,7 +26,6 @@ public class FxAccount20CreateDelegate {
* @param preVerified
* true if account should be marked already verified; only effective
* for non-production auth servers.
* @throws UnsupportedEncodingException
* @throws GeneralSecurityException
*/
public FxAccount20CreateDelegate(byte[] emailUTF8, byte[] quickStretchedPW, boolean preVerified) throws UnsupportedEncodingException, GeneralSecurityException {
@ -34,19 +34,15 @@ public class FxAccount20CreateDelegate {
this.preVerified = preVerified;
}
public ExtendedJSONObject getCreateBody() throws FxAccountClientException {
public ExtendedJSONObject getCreateBody() {
final ExtendedJSONObject body = new ExtendedJSONObject();
try {
body.put("email", new String(emailUTF8, "UTF-8"));
body.put("authPW", Utils.byte2Hex(authPW));
if (preVerified) {
// Production endpoints do not allow preVerified; this assumes we only
// set it when it's okay to send it.
body.put("preVerified", preVerified);
}
return body;
} catch (UnsupportedEncodingException e) {
throw new FxAccountClientException(e);
body.put("email", new String(emailUTF8, StringUtils.UTF_8));
body.put("authPW", Utils.byte2Hex(authPW));
if (preVerified) {
// Production endpoints do not allow preVerified; this assumes we only
// set it when it's okay to send it.
body.put("preVerified", preVerified);
}
return body;
}
}

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

@ -6,6 +6,7 @@ package org.mozilla.gecko.background.fxa;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.util.StringUtils;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
@ -23,14 +24,10 @@ public class FxAccount20LoginDelegate {
this.authPW = FxAccountUtils.generateAuthPW(quickStretchedPW);
}
public ExtendedJSONObject getCreateBody() throws FxAccountClientException {
public ExtendedJSONObject getCreateBody() {
final ExtendedJSONObject body = new ExtendedJSONObject();
try {
body.put("email", new String(emailUTF8, "UTF-8"));
body.put("authPW", Utils.byte2Hex(authPW));
return body;
} catch (UnsupportedEncodingException e) {
throw new FxAccountClientException(e);
}
body.put("email", new String(emailUTF8, StringUtils.UTF_8));
body.put("authPW", Utils.byte2Hex(authPW));
return body;
}
}

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

@ -24,6 +24,7 @@ import org.mozilla.gecko.sync.net.HawkAuthHeaderProvider;
import org.mozilla.gecko.sync.net.Resource;
import org.mozilla.gecko.sync.net.SyncResponse;
import org.mozilla.gecko.sync.net.SyncStorageResponse;
import org.mozilla.gecko.util.StringUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@ -647,7 +648,7 @@ public class FxAccountClient20 implements FxAccountClient {
if (getKeys) {
keyFetchToken = Utils.hex2Byte(body.getString(JSON_KEY_KEYFETCHTOKEN));
}
LoginResponse loginResponse = new LoginResponse(new String(emailUTF8, "UTF-8"), uid, verified, sessionToken, keyFetchToken);
LoginResponse loginResponse = new LoginResponse(new String(emailUTF8, StringUtils.UTF_8), uid, verified, sessionToken, keyFetchToken);
delegate.handleSuccess(loginResponse);
}
@ -697,7 +698,7 @@ public class FxAccountClient20 implements FxAccountClient {
if (getKeys) {
keyFetchToken = Utils.hex2Byte(body.getString(JSON_KEY_KEYFETCHTOKEN));
}
LoginResponse loginResponse = new LoginResponse(new String(emailUTF8, "UTF-8"), uid, verified, sessionToken, keyFetchToken);
LoginResponse loginResponse = new LoginResponse(new String(emailUTF8, StringUtils.UTF_8), uid, verified, sessionToken, keyFetchToken);
delegate.handleSuccess(loginResponse);
}
@ -736,7 +737,7 @@ public class FxAccountClient20 implements FxAccountClient {
final RequestDelegate<LoginResponse> delegate) {
byte[] quickStretchedPW;
try {
FxAccountUtils.pii(LOG_TAG, "Trying user provided email: '" + new String(emailUTF8, "UTF-8") + "'" );
FxAccountUtils.pii(LOG_TAG, "Trying user provided email: '" + new String(emailUTF8, StringUtils.UTF_8) + "'" );
quickStretchedPW = stretcher.getQuickStretchedPW(emailUTF8);
} catch (Exception e) {
delegate.handleError(e);
@ -768,7 +769,7 @@ public class FxAccountClient20 implements FxAccountClient {
try {
// Nota bene: this is not recursive, since we call the fixed password
// signature here, which invokes a non-retrying version.
byte[] alternateEmailUTF8 = alternateEmail.getBytes("UTF-8");
byte[] alternateEmailUTF8 = alternateEmail.getBytes(StringUtils.UTF_8);
byte[] alternateQuickStretchedPW = stretcher.getQuickStretchedPW(alternateEmailUTF8);
login(alternateEmailUTF8, alternateQuickStretchedPW, getKeys, queryParameters, delegate);
} catch (Exception innerException) {

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

@ -20,6 +20,7 @@ import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.crypto.HKDF;
import org.mozilla.gecko.sync.crypto.KeyBundle;
import org.mozilla.gecko.sync.crypto.PBKDF2;
import org.mozilla.gecko.util.StringUtils;
import android.content.Context;
@ -49,21 +50,21 @@ public class FxAccountUtils {
}
}
public static String bytes(String string) throws UnsupportedEncodingException {
return Utils.byte2Hex(string.getBytes("UTF-8"));
public static String bytes(String string) {
return Utils.byte2Hex(string.getBytes(StringUtils.UTF_8));
}
public static byte[] KW(String name) throws UnsupportedEncodingException {
public static byte[] KW(String name) {
return Utils.concatAll(
KW_VERSION_STRING.getBytes("UTF-8"),
name.getBytes("UTF-8"));
KW_VERSION_STRING.getBytes(StringUtils.UTF_8),
name.getBytes(StringUtils.UTF_8));
}
public static byte[] KWE(String name, byte[] emailUTF8) throws UnsupportedEncodingException {
public static byte[] KWE(String name, byte[] emailUTF8) {
return Utils.concatAll(
KW_VERSION_STRING.getBytes("UTF-8"),
name.getBytes("UTF-8"),
":".getBytes("UTF-8"),
KW_VERSION_STRING.getBytes(StringUtils.UTF_8),
name.getBytes(StringUtils.UTF_8),
":".getBytes(StringUtils.UTF_8),
emailUTF8);
}
@ -71,8 +72,8 @@ public class FxAccountUtils {
* Calculate the SRP verifier <tt>x</tt> value.
*/
public static BigInteger srpVerifierLowercaseX(byte[] emailUTF8, byte[] srpPWBytes, byte[] srpSaltBytes)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
byte[] inner = Utils.sha256(Utils.concatAll(emailUTF8, ":".getBytes("UTF-8"), srpPWBytes));
throws NoSuchAlgorithmException {
byte[] inner = Utils.sha256(Utils.concatAll(emailUTF8, ":".getBytes(StringUtils.UTF_8), srpPWBytes));
byte[] outer = Utils.sha256(Utils.concatAll(srpSaltBytes, inner));
return new BigInteger(1, outer);
}

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

@ -10,6 +10,7 @@ import java.util.HashMap;
import java.util.Map;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.util.StringUtils;
public class QuickPasswordStretcher implements PasswordStretcher {
protected final String password;
@ -26,7 +27,7 @@ public class QuickPasswordStretcher implements PasswordStretcher {
}
String key = Utils.byte2Hex(emailUTF8);
if (!cache.containsKey(key)) {
byte[] value = FxAccountUtils.generateQuickStretchedPW(emailUTF8, password.getBytes("UTF-8"));
byte[] value = FxAccountUtils.generateQuickStretchedPW(emailUTF8, password.getBytes(StringUtils.UTF_8));
cache.put(key, Utils.byte2Hex(value));
return value;
}

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

@ -4,15 +4,16 @@
package org.mozilla.gecko.browserid;
import static org.mozilla.apache.commons.codec.binary.StringUtils.newStringUtf8;
import org.json.simple.JSONObject;
import org.mozilla.apache.commons.codec.binary.Base64;
import org.mozilla.apache.commons.codec.binary.StringUtils;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.sync.NonObjectJSONException;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.util.StringUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.TreeMap;
@ -32,21 +33,21 @@ public class JSONWebTokenUtils {
public static final String DEFAULT_CERTIFICATE_ISSUER = "127.0.0.1";
public static final String DEFAULT_ASSERTION_ISSUER = "127.0.0.1";
public static String encode(String payload, SigningPrivateKey privateKey) throws UnsupportedEncodingException, GeneralSecurityException {
public static String encode(String payload, SigningPrivateKey privateKey) throws GeneralSecurityException {
final ExtendedJSONObject header = new ExtendedJSONObject();
header.put("alg", privateKey.getAlgorithm());
String encodedHeader = Base64.encodeBase64URLSafeString(header.toJSONString().getBytes("UTF-8"));
String encodedPayload = Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8"));
String encodedHeader = Base64.encodeBase64URLSafeString(header.toJSONString().getBytes(StringUtils.UTF_8));
String encodedPayload = Base64.encodeBase64URLSafeString(payload.getBytes(StringUtils.UTF_8));
ArrayList<String> segments = new ArrayList<String>();
segments.add(encodedHeader);
segments.add(encodedPayload);
byte[] message = Utils.toDelimitedString(".", segments).getBytes("UTF-8");
byte[] message = Utils.toDelimitedString(".", segments).getBytes(StringUtils.UTF_8);
byte[] signature = privateKey.signMessage(message);
segments.add(Base64.encodeBase64URLSafeString(signature));
return Utils.toDelimitedString(".", segments);
}
public static String decode(String token, VerifyingPublicKey publicKey) throws GeneralSecurityException, UnsupportedEncodingException {
public static String decode(String token, VerifyingPublicKey publicKey) throws GeneralSecurityException {
if (token == null) {
throw new IllegalArgumentException("token must not be null");
}
@ -54,13 +55,13 @@ public class JSONWebTokenUtils {
if (segments == null || segments.length != 3) {
throw new GeneralSecurityException("malformed token");
}
byte[] message = (segments[0] + "." + segments[1]).getBytes("UTF-8");
byte[] message = (segments[0] + "." + segments[1]).getBytes(StringUtils.UTF_8);
byte[] signature = Base64.decodeBase64(segments[2]);
boolean verifies = publicKey.verifyMessage(message, signature);
if (!verifies) {
throw new GeneralSecurityException("bad signature");
}
String payload = StringUtils.newStringUtf8(Base64.decodeBase64(segments[1]));
String payload = newStringUtf8(Base64.decodeBase64(segments[1]));
return payload;
}

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

@ -45,6 +45,7 @@ import org.mozilla.gecko.sync.NonObjectJSONException;
import org.mozilla.gecko.sync.ThreadPool;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.setup.Constants;
import org.mozilla.gecko.util.StringUtils;
import org.mozilla.gecko.util.ThreadUtils;
import java.io.IOException;
@ -495,11 +496,7 @@ public class AndroidFxAccount {
public ExtendedJSONObject toJSONObject() {
ExtendedJSONObject o = unbundle();
o.put("email", account.name);
try {
o.put("emailUTF8", Utils.byte2Hex(account.name.getBytes("UTF-8")));
} catch (UnsupportedEncodingException e) {
// Ignore.
}
o.put("emailUTF8", Utils.byte2Hex(account.name.getBytes(StringUtils.UTF_8)));
o.put("fxaDeviceId", getDeviceId());
o.put("fxaDeviceRegistrationVersion", getDeviceRegistrationVersion());
o.put("fxaDeviceRegistrationTimestamp", getDeviceRegistrationTimestamp());

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

@ -57,6 +57,7 @@ import org.mozilla.gecko.tokenserver.TokenServerClient;
import org.mozilla.gecko.tokenserver.TokenServerClientDelegate;
import org.mozilla.gecko.tokenserver.TokenServerException;
import org.mozilla.gecko.tokenserver.TokenServerToken;
import org.mozilla.gecko.util.StringUtils;
import java.net.URI;
import java.net.URISyntaxException;
@ -408,7 +409,7 @@ public class FxAccountSyncAdapter extends AbstractThreadedSyncAdapter {
// so we explicitly do not send payload verification hashes to the
// Sync storage endpoint.
final boolean includePayloadVerificationHash = false;
final AuthHeaderProvider authHeaderProvider = new HawkAuthHeaderProvider(token.id, token.key.getBytes("UTF-8"), includePayloadVerificationHash, storageServerSkew);
final AuthHeaderProvider authHeaderProvider = new HawkAuthHeaderProvider(token.id, token.key.getBytes(StringUtils.UTF_8), includePayloadVerificationHash, storageServerSkew);
final Context context = getContext();
final SyncConfiguration syncConfig = new SyncConfiguration(token.uid, authHeaderProvider, sharedPrefs, syncKeyBundle);

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

@ -21,8 +21,8 @@ import org.mozilla.gecko.sync.repositories.NullCursorException;
import org.mozilla.gecko.sync.repositories.android.ClientsDatabaseAccessor;
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
import org.mozilla.gecko.sync.telemetry.TelemetryEventCollector;
import org.mozilla.gecko.util.StringUtils;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
@ -267,10 +267,10 @@ public class CommandProcessor {
extra.put("flowID", command.flowID);
}
try {
extra.put("deviceID", Utils.byte2Hex(Utils.sha256(clientID.concat(hashedFxAUID).getBytes("UTF-8"))));
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
extra.put("deviceID", Utils.byte2Hex(Utils.sha256(clientID.concat(hashedFxAUID).getBytes(StringUtils.UTF_8))));
} catch (NoSuchAlgorithmException e) {
// Should not happen.
Log.e(LOG_TAG, "Either UTF-8 or SHA-256 are not supported", e);
Log.e(LOG_TAG, "SHA-256 is not supported", e);
}
TelemetryEventCollector.recordEvent(context, "sendcommand", command.commandType, null, extra);

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

@ -5,7 +5,6 @@
package org.mozilla.gecko.sync;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.json.simple.JSONObject;
import org.mozilla.apache.commons.codec.binary.Base64;
@ -56,11 +55,10 @@ public class CryptoRecord extends Record {
* Input: JSONObject containing a valid payload (cipherText, IV, HMAC),
* KeyBundle with keys for decryption. Output: byte[] clearText
* @throws CryptoException
* @throws UnsupportedEncodingException
*/
private static byte[] decryptPayload(ExtendedJSONObject payload, KeyBundle keybundle) throws CryptoException, UnsupportedEncodingException {
byte[] ciphertext = Base64.decodeBase64(((String) payload.get(KEY_CIPHERTEXT)).getBytes("UTF-8"));
byte[] iv = Base64.decodeBase64(((String) payload.get(KEY_IV)).getBytes("UTF-8"));
private static byte[] decryptPayload(ExtendedJSONObject payload, KeyBundle keybundle) throws CryptoException {
byte[] ciphertext = Base64.decodeBase64(((String) payload.get(KEY_CIPHERTEXT)).getBytes(StringUtils.UTF_8));
byte[] iv = Base64.decodeBase64(((String) payload.get(KEY_IV)).getBytes(StringUtils.UTF_8));
byte[] hmac = Utils.hex2Byte((String) payload.get(KEY_HMAC));
return CryptoInfo.decrypt(ciphertext, iv, hmac, keybundle).getMessage();
@ -131,7 +129,7 @@ public class CryptoRecord extends Record {
*/
public static CryptoRecord fromJSONRecord(String jsonRecord)
throws NonObjectJSONException, IOException, RecordParseException {
byte[] bytes = jsonRecord.getBytes("UTF-8");
byte[] bytes = jsonRecord.getBytes(StringUtils.UTF_8);
ExtendedJSONObject object = ExtendedJSONObject.parseUTF8AsJSONObject(bytes);
return CryptoRecord.fromJSONRecord(object);
@ -201,7 +199,7 @@ public class CryptoRecord extends Record {
return this;
}
public CryptoRecord encrypt() throws CryptoException, UnsupportedEncodingException {
public CryptoRecord encrypt() throws CryptoException {
if (this.keyBundle == null) {
throw new NoKeyBundleException();
}

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

@ -10,6 +10,7 @@ import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.mozilla.apache.commons.codec.binary.Base64;
import org.mozilla.gecko.sync.UnexpectedJSONException.BadRequiredFieldJSONException;
import org.mozilla.gecko.util.StringUtils;
import java.io.IOException;
import java.io.Reader;
@ -138,7 +139,7 @@ public class ExtendedJSONObject implements Cloneable {
*/
public static ExtendedJSONObject parseUTF8AsJSONObject(byte[] in)
throws NonObjectJSONException, IOException {
return new ExtendedJSONObject(new String(in, "UTF-8"));
return new ExtendedJSONObject(new String(in, StringUtils.UTF_8));
}
public ExtendedJSONObject() {

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

@ -7,7 +7,6 @@ package org.mozilla.gecko.sync;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URLDecoder;
@ -127,11 +126,9 @@ public class Utils {
* An input string. Will be decoded as UTF-8.
* @return
* A byte array of decoded values.
* @throws UnsupportedEncodingException
* Should not occur.
*/
public static byte[] decodeBase64(String base64) throws UnsupportedEncodingException {
return Base64.decodeBase64(base64.getBytes("UTF-8"));
public static byte[] decodeBase64(String base64) {
return Base64.decodeBase64(base64.getBytes(StringUtils.UTF_8));
}
public static byte[] decodeFriendlyBase32(String base32) {
@ -202,8 +199,8 @@ public class Utils {
}
protected static byte[] sha1(final String utf8)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
final byte[] bytes = utf8.getBytes("UTF-8");
throws NoSuchAlgorithmException {
final byte[] bytes = utf8.getBytes(StringUtils.UTF_8);
try {
return NativeCrypto.sha1(bytes);
} catch (final LinkageError e) {
@ -213,12 +210,12 @@ public class Utils {
Logger.warn(LOG_TAG, "Got throwable stretching password using native sha1 implementation; " +
"ignoring and using Java implementation.", e);
final MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
return sha1.digest(utf8.getBytes("UTF-8"));
return sha1.digest(utf8.getBytes(StringUtils.UTF_8));
}
}
protected static String sha1Base32(final String utf8)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
throws NoSuchAlgorithmException {
return new Base32().encodeAsString(sha1(utf8)).toLowerCase(Locale.US);
}
@ -229,10 +226,9 @@ public class Utils {
* An account string.
* @return
* An acceptable string.
* @throws UnsupportedEncodingException
* @throws NoSuchAlgorithmException
*/
public static String usernameFromAccount(final String account) throws NoSuchAlgorithmException, UnsupportedEncodingException {
public static String usernameFromAccount(final String account) throws NoSuchAlgorithmException {
if (account == null || account.equals("")) {
throw new IllegalArgumentException("No account name provided.");
}
@ -252,10 +248,9 @@ public class Utils {
* @param version the version of preferences to reference.
* @return the path.
* @throws NoSuchAlgorithmException
* @throws UnsupportedEncodingException
*/
public static String getPrefsPath(final String product, final String accountKey, final String serverURL, final String profile, final long version)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
throws NoSuchAlgorithmException {
final String encodedAccount = sha1Base32(serverURL + ":" + usernameFromAccount(accountKey));
if (version <= 0) {
@ -515,13 +510,13 @@ public class Utils {
* This is the format produced by desktop Firefox when exchanging credentials
* containing non-ASCII characters.
*/
public static String decodeUTF8(final String in) throws UnsupportedEncodingException {
public static String decodeUTF8(final String in) {
final int length = in.length();
final byte[] asciiBytes = new byte[length];
for (int i = 0; i < length; ++i) {
asciiBytes[i] = (byte) in.codePointAt(i);
}
return new String(asciiBytes, "UTF-8");
return new String(asciiBytes, StringUtils.UTF_8);
}
/**

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

@ -12,6 +12,7 @@ import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.util.StringUtils;
/*
* A standards-compliant implementation of RFC 5869
@ -25,11 +26,7 @@ public class HKDF {
* Used for conversion in cases in which you *know* the encoding exists.
*/
public static final byte[] bytes(String in) {
try {
return in.getBytes("UTF-8");
} catch (java.io.UnsupportedEncodingException e) {
return null;
}
return in.getBytes(StringUtils.UTF_8);
}
public static final int BLOCKSIZE = 256 / 8;

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

@ -4,7 +4,6 @@
package org.mozilla.gecko.sync.crypto;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
@ -14,6 +13,7 @@ import javax.crypto.Mac;
import org.mozilla.apache.commons.codec.binary.Base64;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.util.StringUtils;
public class KeyBundle {
private static final String KEY_ALGORITHM_SPEC = "AES";
@ -44,7 +44,7 @@ public class KeyBundle {
// Hash appropriately.
try {
username = Utils.usernameFromAccount(username);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("Invalid username.");
}
@ -77,9 +77,9 @@ public class KeyBundle {
*
* @return A KeyBundle with the specified keys.
*/
public static KeyBundle fromBase64EncodedKeys(String base64EncryptionKey, String base64HmacKey) throws UnsupportedEncodingException {
return new KeyBundle(Base64.decodeBase64(base64EncryptionKey.getBytes("UTF-8")),
Base64.decodeBase64(base64HmacKey.getBytes("UTF-8")));
public static KeyBundle fromBase64EncodedKeys(String base64EncryptionKey, String base64HmacKey) {
return new KeyBundle(Base64.decodeBase64(base64EncryptionKey.getBytes(StringUtils.UTF_8)),
Base64.decodeBase64(base64HmacKey.getBytes(StringUtils.UTF_8)));
}
/**

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

@ -4,7 +4,6 @@
package org.mozilla.gecko.sync.middleware;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.ExecutorService;
import org.mozilla.gecko.sync.CryptoRecord;
@ -161,7 +160,7 @@ public class Crypto5MiddlewareRepositorySession extends MiddlewareRepositorySess
rec.keyBundle = this.keyBundle;
try {
rec.encrypt();
} catch (UnsupportedEncodingException | CryptoException e) {
} catch (CryptoException e) {
storeDelegate.onRecordStoreFailed(e, record.guid);
return;
}

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

@ -16,6 +16,7 @@ import javax.crypto.spec.SecretKeySpec;
import org.mozilla.apache.commons.codec.binary.Base64;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.util.StringUtils;
import ch.boye.httpclientandroidlib.Header;
import ch.boye.httpclientandroidlib.client.methods.HttpRequestBase;
@ -197,11 +198,10 @@ public class HMACAuthHeaderProvider implements AuthHeaderProvider {
* @return signature as base-64 encoded string.
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws UnsupportedEncodingException
*/
protected static String getSignature(String requestString, String key)
throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
String macString = Base64.encodeBase64String(sha1(requestString.getBytes("UTF-8"), key.getBytes("UTF-8")));
throws InvalidKeyException, NoSuchAlgorithmException {
String macString = Base64.encodeBase64String(sha1(requestString.getBytes(StringUtils.UTF_8), key.getBytes(StringUtils.UTF_8)));
return macString;
}

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

@ -20,6 +20,7 @@ import javax.crypto.spec.SecretKeySpec;
import org.mozilla.apache.commons.codec.binary.Base64;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.util.StringUtils;
import ch.boye.httpclientandroidlib.Header;
import ch.boye.httpclientandroidlib.HttpEntity;
@ -151,7 +152,7 @@ public class HawkAuthHeaderProvider implements AuthHeaderProvider {
String app = null;
String dlg = null;
String requestString = getRequestString(request, "header", timestamp, nonce, payloadHash, extra, app, dlg);
String macString = getSignature(requestString.getBytes("UTF-8"), this.key);
String macString = getSignature(requestString.getBytes(StringUtils.UTF_8), this.key);
StringBuilder sb = new StringBuilder();
sb.append("Hawk id=\"");
@ -191,12 +192,11 @@ public class HawkAuthHeaderProvider implements AuthHeaderProvider {
* to compute hash for.
* @return verification hash, or null if the request does not enclose an entity.
* @throws IllegalArgumentException if the request does not enclose a valid non-null entity.
* @throws UnsupportedEncodingException
* @throws NoSuchAlgorithmException
* @throws IOException
*/
protected static String getPayloadHashString(HttpRequestBase request)
throws UnsupportedEncodingException, NoSuchAlgorithmException, IOException, IllegalArgumentException {
throws NoSuchAlgorithmException, IOException, IllegalArgumentException {
final boolean shouldComputePayloadHash = request instanceof HttpEntityEnclosingRequest;
if (!shouldComputePayloadHash) {
Logger.debug(LOG_TAG, "Not computing payload verification hash for non-enclosing request.");
@ -278,14 +278,14 @@ public class HawkAuthHeaderProvider implements AuthHeaderProvider {
* @return hash.
* @throws IllegalArgumentException if entity is not repeatable.
*/
protected static byte[] getPayloadHash(HttpEntity entity) throws UnsupportedEncodingException, IOException, NoSuchAlgorithmException {
protected static byte[] getPayloadHash(HttpEntity entity) throws IOException, NoSuchAlgorithmException {
if (!entity.isRepeatable()) {
throw new IllegalArgumentException("entity must be repeatable");
}
final MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(("hawk." + HAWK_HEADER_VERSION + ".payload\n").getBytes("UTF-8"));
digest.update(getBaseContentType(entity.getContentType()).getBytes("UTF-8"));
digest.update("\n".getBytes("UTF-8"));
digest.update(("hawk." + HAWK_HEADER_VERSION + ".payload\n").getBytes(StringUtils.UTF_8));
digest.update(getBaseContentType(entity.getContentType()).getBytes(StringUtils.UTF_8));
digest.update("\n".getBytes(StringUtils.UTF_8));
InputStream stream = entity.getContent();
try {
int numRead;
@ -295,7 +295,7 @@ public class HawkAuthHeaderProvider implements AuthHeaderProvider {
digest.update(buffer, 0, numRead);
}
}
digest.update("\n".getBytes("UTF-8")); // Trailing newline is specified by Hawk.
digest.update("\n".getBytes(StringUtils.UTF_8)); // Trailing newline is specified by Hawk.
return digest.digest();
} finally {
stream.close();

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

@ -11,6 +11,7 @@ import java.io.UnsupportedEncodingException;
import org.json.simple.JSONObject;
import org.mozilla.gecko.sync.CryptoRecord;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.util.StringUtils;
/**
* Record is the abstract base class for all entries that Sync processes:
@ -259,12 +260,7 @@ public abstract class Record {
}
public static byte[] stringToJSONBytes(String in) {
try {
return in.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
// Can't happen.
return null;
}
return in.getBytes(StringUtils.UTF_8);
}
/**

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

@ -11,7 +11,6 @@ import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
@ -672,8 +671,6 @@ public class SyncClientsEngineStage extends AbstractSessionManagingSyncStage {
return null;
}
return cryptoRecord.encrypt();
} catch (UnsupportedEncodingException e) {
doAbort(e, encryptionFailure + " Unsupported encoding.");
} catch (CryptoException e) {
doAbort(e, encryptionFailure);
}

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

@ -18,8 +18,8 @@ import org.mozilla.gecko.sync.net.SyncStorageResponse;
import org.mozilla.gecko.sync.repositories.FetchFailedException;
import org.mozilla.gecko.sync.repositories.StoreFailedException;
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
import org.mozilla.gecko.util.StringUtils;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
@ -77,11 +77,11 @@ public class TelemetryCollector {
this.hashedUID = uid;
try {
this.hashedDeviceID = Utils.byte2Hex(Utils.sha256(
deviceID.concat(uid).getBytes("UTF-8")
deviceID.concat(uid).getBytes(StringUtils.UTF_8)
));
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
} catch (NoSuchAlgorithmException e) {
// Should not happen.
Log.e(LOG_TAG, "Either UTF-8 or SHA-256 are not supported", e);
Log.e(LOG_TAG, "SHA-256 is not supported", e);
}
}
@ -128,11 +128,11 @@ public class TelemetryCollector {
try {
device.putString(
TelemetryContract.KEY_DEVICE_ID,
Utils.byte2Hex(Utils.sha256(clientAndUid.getBytes("UTF-8")))
Utils.byte2Hex(Utils.sha256(clientAndUid.getBytes(StringUtils.UTF_8)))
);
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
} catch (NoSuchAlgorithmException e) {
// Should not happen.
Log.e(LOG_TAG, "Either UTF-8 or SHA-256 are not supported", e);
Log.e(LOG_TAG, "SHA-256 is not supported", e);
}
devices.add(device);
}

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

@ -21,6 +21,7 @@ import org.mozilla.gecko.sync.SharedPreferencesClientsDataDelegate;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.delegates.ClientsDataDelegate;
import org.mozilla.gecko.sync.net.BaseResource;
import org.mozilla.gecko.util.StringUtils;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
@ -126,10 +127,10 @@ public class TelemetryEventCollector {
final ClientsDataDelegate clientsDataDelegate = new SharedPreferencesClientsDataDelegate(sharedPrefs, context);
try {
final String hashedDeviceID = Utils.byte2Hex(Utils.sha256(
clientsDataDelegate.getAccountGUID().concat(hashedFxAUID).getBytes("UTF-8")
clientsDataDelegate.getAccountGUID().concat(hashedFxAUID).getBytes(StringUtils.UTF_8)
));
event.putString(TelemetryContract.KEY_LOCAL_DEVICE_ID, hashedDeviceID);
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
} catch (NoSuchAlgorithmException e) {
// Should not happen.
Log.e(LOG_TAG, "Either UTF-8 or SHA-256 are not supported", e);
return false;

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

@ -22,7 +22,6 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;
@ -330,10 +329,6 @@ public final class PRNGFixes {
if (serial != null) {
result.append(serial);
}
try {
return result.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("UTF-8 encoding not supported");
}
return result.toString().getBytes(StringUtils.UTF_8);
}
}

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

@ -9,6 +9,7 @@ import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.sync.NonObjectJSONException;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RobolectricTestRunner;
import java.io.IOException;
@ -53,7 +54,7 @@ public class TestCredentialsEndToEnd {
final String decoded = Utils.decodeUTF8(password);
final byte[] expectedBytes = Utils.decodeBase64(BTOA_PASSWORD);
final String expected = new String(expectedBytes, "UTF-8");
final String expected = new String(expectedBytes, StringUtils.UTF_8);
assertEquals(DESKTOP_ASSERTED_SIZE, password.length());
assertEquals(expected, decoded);

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

@ -13,6 +13,7 @@ import org.mozilla.gecko.sync.NoCollectionKeysSetException;
import org.mozilla.gecko.sync.NonObjectJSONException;
import org.mozilla.gecko.sync.crypto.CryptoException;
import org.mozilla.gecko.sync.crypto.KeyBundle;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RobolectricTestRunner;
import java.io.IOException;
@ -80,7 +81,7 @@ public class TestCollectionKeys {
rec.encrypt();
CollectionKeys ck = new CollectionKeys();
ck.setKeyPairsFromWBO(rec, syncKeyBundle);
byte[] input = "3fI6k1exImMgAKjilmMaAWxGqEIzFX/9K5EjEgH99vc=".getBytes("UTF-8");
byte[] input = "3fI6k1exImMgAKjilmMaAWxGqEIzFX/9K5EjEgH99vc=".getBytes(StringUtils.UTF_8);
byte[] expected = Base64.decodeBase64(input);
assertSame(expected, ck.defaultKeyBundle().getEncryptionKey());
}

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

@ -17,6 +17,7 @@ import org.mozilla.gecko.sync.crypto.KeyBundle;
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
import org.mozilla.gecko.sync.repositories.domain.HistoryRecord;
import org.mozilla.gecko.sync.repositories.domain.Record;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RobolectricTestRunner;
import java.io.IOException;
@ -109,8 +110,8 @@ public class TestCryptoRecord {
payload.put("hmac", base16Hmac);
body.put("payload", payload.toJSONString());
CryptoRecord record = CryptoRecord.fromJSONRecord(body);
byte[] decodedKey = Base64.decodeBase64(base64EncryptionKey.getBytes("UTF-8"));
byte[] decodedHMAC = Base64.decodeBase64(base64HmacKey.getBytes("UTF-8"));
byte[] decodedKey = Base64.decodeBase64(base64EncryptionKey.getBytes(StringUtils.UTF_8));
byte[] decodedHMAC = Base64.decodeBase64(base64HmacKey.getBytes(StringUtils.UTF_8));
record.keyBundle = new KeyBundle(decodedKey, decodedHMAC);
record.decrypt();
@ -125,14 +126,14 @@ public class TestCryptoRecord {
String user = "c6o7dvmr2c4ud2fyv6woz2u4zi22bcyd";
// Check our friendly base32 decoding.
assertTrue(Arrays.equals(Utils.decodeFriendlyBase32(key), Base64.decodeBase64("8xbKrJfQYwbFkguKmlSm/g==".getBytes("UTF-8"))));
assertTrue(Arrays.equals(Utils.decodeFriendlyBase32(key), Base64.decodeBase64("8xbKrJfQYwbFkguKmlSm/g==".getBytes(StringUtils.UTF_8))));
KeyBundle bundle = new KeyBundle(user, key);
String expectedEncryptKeyBase64 = "/8RzbFT396htpZu5rwgIg2WKfyARgm7dLzsF5pwrVz8=";
String expectedHMACKeyBase64 = "NChGjrqoXYyw8vIYP2334cvmMtsjAMUZNqFwV2LGNkM=";
byte[] computedEncryptKey = bundle.getEncryptionKey();
byte[] computedHMACKey = bundle.getHMACKey();
assertTrue(Arrays.equals(computedEncryptKey, Base64.decodeBase64(expectedEncryptKeyBase64.getBytes("UTF-8"))));
assertTrue(Arrays.equals(computedHMACKey, Base64.decodeBase64(expectedHMACKeyBase64.getBytes("UTF-8"))));
assertTrue(Arrays.equals(computedEncryptKey, Base64.decodeBase64(expectedEncryptKeyBase64.getBytes(StringUtils.UTF_8))));
assertTrue(Arrays.equals(computedHMACKey, Base64.decodeBase64(expectedHMACKeyBase64.getBytes(StringUtils.UTF_8))));
}
@Test
@ -264,8 +265,8 @@ public class TestCryptoRecord {
JSONArray keys = new ExtendedJSONObject(decrypted.payload.toJSONString()).getArray("default");
KeyBundle keyBundle = KeyBundle.fromBase64EncodedKeys((String)keys.get(0), (String)keys.get(1));
assertArrayEquals(Base64.decodeBase64(expectedBase64EncryptionKey.getBytes("UTF-8")), keyBundle.getEncryptionKey());
assertArrayEquals(Base64.decodeBase64(expectedBase64HmacKey.getBytes("UTF-8")), keyBundle.getHMACKey());
assertArrayEquals(Base64.decodeBase64(expectedBase64EncryptionKey.getBytes(StringUtils.UTF_8)), keyBundle.getEncryptionKey());
assertArrayEquals(Base64.decodeBase64(expectedBase64HmacKey.getBytes(StringUtils.UTF_8)), keyBundle.getHMACKey());
}
@Test

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

@ -16,6 +16,7 @@ import org.mozilla.gecko.fxa.login.FxAccountLoginStateMachine.LoginStateMachineD
import org.mozilla.gecko.fxa.login.FxAccountLoginTransition.Transition;
import org.mozilla.gecko.fxa.login.State.StateLabel;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RobolectricTestRunner;
import java.security.NoSuchAlgorithmException;
@ -39,10 +40,10 @@ public class TestFxAccountLoginStateMachine {
@Before
public void setUp() throws Exception {
if (TEST_EMAIL_UTF8 == null) {
TEST_EMAIL_UTF8 = TEST_EMAIL.getBytes("UTF-8");
TEST_EMAIL_UTF8 = TEST_EMAIL.getBytes(StringUtils.UTF_8);
}
if (TEST_PASSWORD_UTF8 == null) {
TEST_PASSWORD_UTF8 = TEST_PASSWORD.getBytes("UTF-8");
TEST_PASSWORD_UTF8 = TEST_PASSWORD.getBytes(StringUtils.UTF_8);
}
if (TEST_QUICK_STRETCHED_PW == null) {
TEST_QUICK_STRETCHED_PW = FxAccountUtils.generateQuickStretchedPW(TEST_EMAIL_UTF8, TEST_PASSWORD_UTF8);

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

@ -10,6 +10,7 @@ import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.crypto.CryptoException;
import org.mozilla.gecko.sync.crypto.CryptoInfo;
import org.mozilla.gecko.sync.crypto.KeyBundle;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RobolectricTestRunner;
import java.io.UnsupportedEncodingException;
@ -24,17 +25,17 @@ import static org.junit.Assert.assertTrue;
public class TestCryptoInfo {
@Test
public void testEncryptedHMACIsSet() throws CryptoException, UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
public void testEncryptedHMACIsSet() throws CryptoException, InvalidKeyException, NoSuchAlgorithmException {
KeyBundle kb = KeyBundle.withRandomKeys();
CryptoInfo encrypted = CryptoInfo.encrypt("plaintext".getBytes("UTF-8"), kb);
CryptoInfo encrypted = CryptoInfo.encrypt("plaintext".getBytes(StringUtils.UTF_8), kb);
assertSame(kb, encrypted.getKeys());
assertTrue(encrypted.generatedHMACIsHMAC());
}
@Test
public void testRandomEncryptedDecrypted() throws CryptoException, UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
public void testRandomEncryptedDecrypted() throws CryptoException, InvalidKeyException, NoSuchAlgorithmException {
KeyBundle kb = KeyBundle.withRandomKeys();
byte[] plaintext = "plaintext".getBytes("UTF-8");
byte[] plaintext = "plaintext".getBytes(StringUtils.UTF_8);
CryptoInfo info = CryptoInfo.encrypt(plaintext, kb);
byte[] iv = info.getIV();
info.decrypt();
@ -141,4 +142,4 @@ public class TestCryptoInfo {
assertArrayEquals(Base64.decodeBase64(base64CipherText), encrypted.getMessage());
assertArrayEquals(Utils.hex2Byte(base16Hmac), encrypted.getHMAC());
}
}
}

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

@ -8,6 +8,7 @@ import org.junit.runner.RunWith;
import org.mozilla.apache.commons.codec.binary.Base64;
import org.mozilla.gecko.sync.crypto.CryptoException;
import org.mozilla.gecko.sync.crypto.KeyBundle;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RobolectricTestRunner;
import java.io.UnsupportedEncodingException;
@ -30,8 +31,8 @@ public class TestKeyBundle {
"dKj0O+b0fwI=";
KeyBundle keys = new KeyBundle(username, friendlyBase32SyncKey);
assertArrayEquals(keys.getEncryptionKey(), Base64.decodeBase64(base64EncryptionKey.getBytes("UTF-8")));
assertArrayEquals(keys.getHMACKey(), Base64.decodeBase64(base64HmacKey.getBytes("UTF-8")));
assertArrayEquals(keys.getEncryptionKey(), Base64.decodeBase64(base64EncryptionKey.getBytes(StringUtils.UTF_8)));
assertArrayEquals(keys.getHMACKey(), Base64.decodeBase64(base64HmacKey.getBytes(StringUtils.UTF_8)));
}
/*

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

@ -32,7 +32,7 @@ public class TestHMACAuthHeaderProvider {
}
public static String getSignature(String requestString, String key)
throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
throws InvalidKeyException, NoSuchAlgorithmException {
return HMACAuthHeaderProvider.getSignature(requestString, key);
}
}

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

@ -15,6 +15,7 @@ import ch.boye.httpclientandroidlib.protocol.BasicHttpContext;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mozilla.gecko.sync.net.HawkAuthHeaderProvider;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RobolectricTestRunner;
import java.io.IOException;
@ -46,7 +47,7 @@ public class TestHawkAuthHeaderProvider {
// Public for testing.
public static String getSignature(String requestString, String key)
throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
return HawkAuthHeaderProvider.getSignature(requestString.getBytes("UTF-8"), key.getBytes("UTF-8"));
return HawkAuthHeaderProvider.getSignature(requestString.getBytes(StringUtils.UTF_8), key.getBytes(StringUtils.UTF_8));
}
// Public for testing.
@ -106,7 +107,7 @@ public class TestHawkAuthHeaderProvider {
@Test
public void testSpecPayloadExample() throws Exception {
LeakyHawkAuthHeaderProvider provider = new LeakyHawkAuthHeaderProvider("dh37fgj492je", "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes("UTF-8"));
LeakyHawkAuthHeaderProvider provider = new LeakyHawkAuthHeaderProvider("dh37fgj492je", "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes(StringUtils.UTF_8));
URI uri = new URI("http://example.com:8000/resource/1?b=1&a=2");
HttpPost req = new HttpPost(uri);
String body = "Thank you for flying Hawk";
@ -119,7 +120,7 @@ public class TestHawkAuthHeaderProvider {
@Test
public void testSpecAuthorizationHeader() throws Exception {
LeakyHawkAuthHeaderProvider provider = new LeakyHawkAuthHeaderProvider("dh37fgj492je", "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes("UTF-8"));
LeakyHawkAuthHeaderProvider provider = new LeakyHawkAuthHeaderProvider("dh37fgj492je", "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes(StringUtils.UTF_8));
URI uri = new URI("http://example.com:8000/resource/1?b=1&a=2");
HttpGet req = new HttpGet(uri);
Header header = provider.getAuthHeader(req, null, null, 1353832234L, "j4h3g2", "some-app-ext-data", false);

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

@ -19,6 +19,7 @@ import org.mozilla.gecko.sync.net.BaseResourceDelegate;
import org.mozilla.gecko.sync.net.HawkAuthHeaderProvider;
import org.mozilla.gecko.sync.net.Resource;
import org.mozilla.gecko.sync.net.SyncResponse;
import org.mozilla.gecko.util.StringUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@ -39,7 +40,7 @@ public class TestLiveHawkAuth {
public void testHawkUsage() throws Exception {
// Id and credentials are hard-coded in example/usage.js.
final String id = "dh37fgj492je";
final byte[] key = "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes("UTF-8");
final byte[] key = "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes(StringUtils.UTF_8);
final BaseResource resource = new BaseResource("http://localhost:8000/", false);
// Basic GET.

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

@ -18,6 +18,7 @@ import org.mozilla.gecko.sync.net.SyncStorageResponse;
import org.mozilla.gecko.sync.repositories.FetchFailedException;
import org.mozilla.gecko.sync.repositories.StoreFailedException;
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RobolectricTestRunner;
import java.util.ArrayList;
@ -51,7 +52,7 @@ public class TelemetryCollectorTest {
assertEquals(uid, bundle.get("uid"));
// Expect device ID to be hashed with the UID.
assertEquals(
Utils.byte2Hex(Utils.sha256(deviceID.concat(uid).getBytes("UTF-8"))),
Utils.byte2Hex(Utils.sha256(deviceID.concat(uid).getBytes(StringUtils.UTF_8))),
bundle.get("deviceID")
);
}
@ -79,7 +80,7 @@ public class TelemetryCollectorTest {
ArrayList<Bundle> devices = data.getParcelableArrayList("devices");
assertEquals(1, devices.size());
assertEquals(
Utils.byte2Hex(Utils.sha256("client1-guid".concat("hashed-uid").getBytes("UTF-8"))),
Utils.byte2Hex(Utils.sha256("client1-guid".concat("hashed-uid").getBytes(StringUtils.UTF_8))),
devices.get(0).getString("id")
);
assertEquals("iOS", devices.get(0).getString("os"));
@ -98,14 +99,14 @@ public class TelemetryCollectorTest {
assertEquals("iOS", devices.get(0).getString("os"));
assertEquals("1.33.7", devices.get(0).getString("version"));
assertEquals(
Utils.byte2Hex(Utils.sha256("client1-guid".concat("hashed-uid").getBytes("UTF-8"))),
Utils.byte2Hex(Utils.sha256("client1-guid".concat("hashed-uid").getBytes(StringUtils.UTF_8))),
devices.get(0).getString("id")
);
assertEquals("Android", devices.get(1).getString("os"));
assertEquals("55.0a1", devices.get(1).getString("version"));
assertEquals(
Utils.byte2Hex(Utils.sha256("client2-guid".concat("hashed-uid").getBytes("UTF-8"))),
Utils.byte2Hex(Utils.sha256("client2-guid".concat("hashed-uid").getBytes(StringUtils.UTF_8))),
devices.get(1).getString("id")
);
}
@ -346,4 +347,4 @@ public class TelemetryCollectorTest {
assertEquals("othererror", error.getString("name"));
assertEquals("store:IllegalStateException", error.getString("error"));
}
}
}

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

@ -11,6 +11,7 @@ import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.sync.NonArrayJSONException;
import org.mozilla.gecko.sync.NonObjectJSONException;
import org.mozilla.gecko.sync.UnexpectedJSONException.BadRequiredFieldJSONException;
import org.mozilla.gecko.util.StringUtils;
import org.robolectric.RobolectricTestRunner;
import java.io.IOException;
@ -102,7 +103,7 @@ public class TestExtendedJSONObject {
public void testParseUTF8AsJSONObject() throws Exception {
String TEST = "{\"key\":\"value\"}";
ExtendedJSONObject o = ExtendedJSONObject.parseUTF8AsJSONObject(TEST.getBytes("UTF-8"));
ExtendedJSONObject o = ExtendedJSONObject.parseUTF8AsJSONObject(TEST.getBytes(StringUtils.UTF_8));
assertNotNull(o);
assertEquals("value", o.getString("key"));
}
@ -117,7 +118,7 @@ public class TestExtendedJSONObject {
}
try {
ExtendedJSONObject.parseUTF8AsJSONObject("{".getBytes("UTF-8"));
ExtendedJSONObject.parseUTF8AsJSONObject("{".getBytes(StringUtils.UTF_8));
fail();
} catch (NonObjectJSONException e) {
// Do nothing.

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

@ -20,6 +20,7 @@ import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.db.URLMetadata;
import org.mozilla.gecko.db.URLImageDataTable;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.util.StringUtils;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
@ -195,7 +196,7 @@ public class testBrowserProvider extends ContentProviderTest {
faviconEntry.put(BrowserContract.Favicons.PAGE_URL, pageUrl);
faviconEntry.put(BrowserContract.Favicons.URL, pageUrl + "/favicon.ico");
faviconEntry.put(BrowserContract.Favicons.DATA, data.getBytes("UTF8"));
faviconEntry.put(BrowserContract.Favicons.DATA, data.getBytes(StringUtils.UTF_8));
return faviconEntry;
}
@ -204,7 +205,7 @@ public class testBrowserProvider extends ContentProviderTest {
ContentValues thumbnailEntry = new ContentValues();
thumbnailEntry.put(BrowserContract.Thumbnails.URL, pageUrl);
thumbnailEntry.put(BrowserContract.Thumbnails.DATA, data.getBytes("UTF8"));
thumbnailEntry.put(BrowserContract.Thumbnails.DATA, data.getBytes(StringUtils.UTF_8));
return thumbnailEntry;
}

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

@ -19,6 +19,7 @@ import java.security.NoSuchAlgorithmException;
import org.mozilla.gecko.background.nativecode.NativeCrypto;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.tests.helpers.GeckoHelper;
import org.mozilla.gecko.util.StringUtils;
import android.os.SystemClock;
@ -238,9 +239,9 @@ public class testNativeCrypto extends UITest {
}
}
private void _testSHA256WithMultipleUpdatesFromStream() throws UnsupportedEncodingException {
private void _testSHA256WithMultipleUpdatesFromStream() {
final String input = "HelloWorldThisIsASuperLongStringThatIsReadAsAStreamOfBytes";
final ByteArrayInputStream stream = new ByteArrayInputStream(input.getBytes("UTF-8"));
final ByteArrayInputStream stream = new ByteArrayInputStream(input.getBytes(StringUtils.UTF_8));
final String expected = "8b5cb76b80f7eb6fb83ee138bfd31e2922e71dd245daa21a8d9876e8dee9eef5";
byte[] buffer = new byte[10];

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

@ -9,7 +9,6 @@
#include "mozilla/Assertions.h"
#include "mozilla/Types.h"
#include "mozilla/StaticPtr.h"
namespace mozilla {
namespace interceptor {
@ -165,7 +164,8 @@ public:
return;
}
MOZ_RELEASE_ASSERT(sPerProcVM->append(ProcMapEntry(aArgs...)));
bool appended = sPerProcVM->append(ProcMapEntry(aArgs...));
MOZ_RELEASE_ASSERT(appended);
}
explicit operator bool() const
@ -173,7 +173,8 @@ public:
AutoCriticalSection lock(&sCS);
ProcMapEntry* entry;
MOZ_RELEASE_ASSERT(find(mPid, &entry));
bool found = find(mPid, &entry);
MOZ_RELEASE_ASSERT(found);
return !!entry->mVMPolicy;
}
@ -183,7 +184,8 @@ public:
AutoCriticalSection lock(&sCS);
ProcMapEntry* entry;
MOZ_RELEASE_ASSERT(find(mPid, &entry));
bool found = find(mPid, &entry);
MOZ_RELEASE_ASSERT(found);
return entry->mVMPolicy;
}
@ -241,7 +243,8 @@ public:
AutoCriticalSection lock(&sCS);
ProcMapEntry* entry;
MOZ_RELEASE_ASSERT(find(mPid, &entry));
bool found = find(mPid, &entry);
MOZ_RELEASE_ASSERT(found);
TrampolineCollection<MMPolicy> items(Move(entry->mVMPolicy.Items()));
@ -292,12 +295,12 @@ private:
static DWORD GetPid(HANDLE aHandle) { return ::GetProcessId(aHandle); }
DWORD mPid;
static StaticAutoPtr<MapT> sPerProcVM;
static MapT* sPerProcVM;
static CRITICAL_SECTION sCS;
};
template <typename MMPolicy, uint32_t kChunkSize>
StaticAutoPtr<typename VMSharingPolicyShared<MMPolicy, kChunkSize>::MapT>
typename VMSharingPolicyShared<MMPolicy, kChunkSize>::MapT *
VMSharingPolicyShared<MMPolicy, kChunkSize>::sPerProcVM;
template <typename MMPolicy, uint32_t kChunkSize>

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

@ -88,7 +88,7 @@ enum
};
template <typename VMPolicy =
mozilla::interceptor::VMSharingPolicyUnique<
mozilla::interceptor::VMSharingPolicyShared<
mozilla::interceptor::MMPolicyInProcess, kDefaultTrampolineSize>>
class WindowsDllInterceptor final
{

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

@ -66,6 +66,7 @@ enum class SHA1ModeResult {
enum class DistrustedCAPolicy : uint32_t {
Permit = 0,
DistrustSymantecRoots = 1,
DistrustSymantecRootsRegardlessOfDate = 2,
};
enum class NetscapeStepUpPolicy : uint32_t;

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

@ -891,7 +891,7 @@ NSSCertDBTrustDomain::IsChainValid(const DERArray& certArray, Time time,
// handshake. To determine this, we check mHostname: If it isn't set, this is
// not TLS, so don't run the algorithm.
if (mHostname && CertDNIsInList(root.get(), RootSymantecDNs) &&
mDistrustedCAPolicy == DistrustedCAPolicy::DistrustSymantecRoots) {
mDistrustedCAPolicy != DistrustedCAPolicy::Permit) {
rootCert = nullptr; // Clear the state for Segment...
nsCOMPtr<nsIX509CertList> intCerts;
@ -907,8 +907,13 @@ NSSCertDBTrustDomain::IsChainValid(const DERArray& certArray, Time time,
// (new Date("2016-06-01T00:00:00Z")).getTime() * 1000
static const PRTime JUNE_1_2016 = 1464739200000000;
PRTime permitAfterDate = 0; // 0 indicates there is no permitAfterDate
if (mDistrustedCAPolicy == DistrustedCAPolicy::DistrustSymantecRoots) {
permitAfterDate = JUNE_1_2016;
}
bool isDistrusted = false;
nsrv = CheckForSymantecDistrust(intCerts, eeCert, JUNE_1_2016,
nsrv = CheckForSymantecDistrust(intCerts, eeCert, permitAfterDate,
RootAppleAndGoogleSPKIs, isDistrusted);
if (NS_FAILED(nsrv)) {
return Result::FATAL_ERROR_LIBRARY_FAILURE;

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

@ -1694,6 +1694,7 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting)
switch(distrustedCAPolicy) {
case DistrustedCAPolicy::Permit:
case DistrustedCAPolicy::DistrustSymantecRoots:
case DistrustedCAPolicy::DistrustSymantecRootsRegardlessOfDate:
break;
default:
distrustedCAPolicy = defaultCAPolicyMode;

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

@ -39,6 +39,23 @@ add_connection_test("symantec-not-whitelisted-before-cutoff.example.com",
MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED,
null, null);
// Enable the Firefox 63 total distrust; before or after cutoff should now all
// behave the same.
add_test(function() {
clearSessionCache();
Services.prefs.setIntPref("security.pki.distrust_ca_policy",
/* DistrustedCAPolicy::DistrustSymantecRootsRegardlessOfDate */ 2);
run_next_test();
});
add_connection_test("symantec-not-whitelisted-before-cutoff.example.com",
MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED,
null, null);
add_connection_test("symantec-not-whitelisted-after-cutoff.example.com",
MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED,
null, null);
// Disable the distrust, should be back to the console warning
add_test(function() {
clearSessionCache();
@ -77,6 +94,7 @@ add_task(async function() {
// (as an external fetch is bad in the tests), disable OCSP first.
Services.prefs.setIntPref("security.OCSP.enabled", 0);
// Try with the policy for 60
Services.prefs.setIntPref("security.pki.distrust_ca_policy",
/* DistrustedCAPolicy::DistrustSymantecRoots */ 1);
@ -85,4 +103,11 @@ add_task(async function() {
await checkCertErrorGenericAtTime(certDB, whitelistedCert, PRErrorCodeSuccess,
certificateUsageSSLServer, VALIDATION_TIME);
// Try with the policy for 63
Services.prefs.setIntPref("security.pki.distrust_ca_policy",
/* DistrustedCAPolicy::DistrustSymantecRootsRegardlessOfDate */ 2);
await checkCertErrorGenericAtTime(certDB, whitelistedCert, PRErrorCodeSuccess,
certificateUsageSSLServer, VALIDATION_TIME);
});

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

@ -12,24 +12,6 @@ transforms:
kind-dependencies:
- build
only-for-build-platforms:
- linux64/opt
- linux64/debug
- linux64-nightly/opt
- linux-nightly/opt
- linux64-devedition-nightly/opt
- linux-devedition-nightly/opt
- android-aarch64-nightly/opt
- android-api-16/opt
- android-api-16-nightly/opt
- android-x86-nightly/opt
- macosx64-nightly/opt
- macosx64-devedition-nightly/opt
- win32-nightly/opt
- win64-nightly/opt
- win32-devedition-nightly/opt
- win64-devedition-nightly/opt
job-template:
description: Upload Symbols
worker-type: aws-provisioner-v1/gecko-{level}-b-linux
@ -53,4 +35,7 @@ job-template:
run-on-projects:
by-build-platform:
.*devedition.*: ['mozilla-beta', 'maple']
default: ['all']
# Only upload symbols for nightlies on most branches.
.*(?<!-devedition)-nightly: ['all']
# Allow symbol upload for any build type on try.
default: ['try']

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

@ -40,14 +40,6 @@ def filter_on_platforms(task, platforms):
return (platform in platforms)
def filter_upload_symbols(task, parameters):
# Filters out symbols when there are not part of a nightly or a release build
# TODO Remove this too specific filter (bug 1353296)
return '-upload-symbols' not in task.label or \
task.attributes.get('nightly') or \
parameters.get('project') in ('mozilla-beta', 'mozilla-release')
def filter_beta_release_tasks(task, parameters, ignore_kinds=None, allow_l10n=False):
if not standard_filter(task, parameters):
return False
@ -65,6 +57,8 @@ def filter_beta_release_tasks(task, parameters, ignore_kinds=None, allow_l10n=Fa
# On beta, Nightly builds are already PGOs
'linux-pgo', 'linux64-pgo',
'win32-pgo', 'win64-pgo',
# ASAN is central-only
'linux64-asan-reporter-nightly',
):
return False
if str(platform).startswith('android') and 'nightly' in str(platform):
@ -94,7 +88,7 @@ def filter_beta_release_tasks(task, parameters, ignore_kinds=None, allow_l10n=Fa
def standard_filter(task, parameters):
return all(
filter_func(task, parameters) for filter_func in
(filter_out_nightly, filter_for_project, filter_upload_symbols)
(filter_out_nightly, filter_for_project)
)

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

@ -1473,6 +1473,7 @@ def build_task(config, tasks):
extra['parent'] = os.environ.get('TASK_ID', '')
task_th = task.get('treeherder')
if task_th:
extra.setdefault('treeherder-platform', task_th['platform'])
treeherder = extra.setdefault('treeherder', {})
machine_platform, collection = task_th['platform'].split('/', 1)

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

@ -33,20 +33,20 @@ def fill_template(config, tasks):
attributes = task.setdefault('attributes', {})
attributes['build_platform'] = build_platform
attributes['build_type'] = build_type
if 'nightly' in build_platform:
if dep.attributes.get('nightly'):
attributes['nightly'] = True
treeherder = task.get('treeherder', {})
th = dep.task.get('extra')['treeherder']
treeherder.setdefault('platform',
"{}/{}".format(th['machine']['platform'],
build_type))
th_platform = dep.task['extra'].get('treeherder-platform',
"{}/{}".format(th['machine']['platform'], build_type))
treeherder.setdefault('platform', th_platform)
treeherder.setdefault('tier', th['tier'])
treeherder.setdefault('kind', th['jobKind'])
if dep.attributes.get('nightly'):
treeherder.setdefault('symbol', 'SymN')
else:
treeherder.setdefault('symbol', 'Sym')
# Disambiguate the treeherder symbol.
build_sym = th['symbol']
sym = 'Sym' + (build_sym[1:] if build_sym.startswith('B') else build_sym)
treeherder.setdefault('symbol', sym)
task['treeherder'] = treeherder
# clear out the stuff that's not part of a task description

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

@ -304,6 +304,7 @@ class cpstartup(PageloaderTest):
tploadnocache = True
unit = 'ms'
preferences = {
'addon.test.cpstartup.webserver': '${webserver}',
# By default, Talos is configured to open links from
# content in new windows. We're overriding them so that
# they open in new tabs instead.

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

@ -6,7 +6,9 @@ ChromeUtils.import("resource://gre/modules/Services.jsm");
const PREALLOCATED_PREF = "dom.ipc.processPrelaunch.enabled";
const TARGET_URI = "chrome://cpstartup/content/target.html";
const TARGET_PATH = "tests/cpstartup/content/target.html";
const WEBSERVER = Services.prefs.getCharPref("addon.test.cpstartup.webserver");
const TARGET_URI = `${WEBSERVER}/${TARGET_PATH}`;
/**
* The purpose of this test it to measure the performance of a content process startup.

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

@ -14,6 +14,7 @@
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "rpcrt4.lib")
#include "mozilla/CmdLineAndEnvUtils.h"
#include "nsWindowsHelpers.h"
#include "workmonitor.h"
@ -31,7 +32,6 @@
// Updates usually take less than a minute so this seems like a
// significantly large and safe amount of time to wait.
static const int TIME_TO_WAIT_ON_UPDATER = 15 * 60 * 1000;
wchar_t* MakeCommandLine(int argc, wchar_t** argv);
BOOL WriteStatusFailure(LPCWSTR updateDirPath, int errorCode);
BOOL PathGetSiblingFilePath(LPWSTR destinationBuffer, LPCWSTR siblingFilePath,
LPCWSTR newFileName);
@ -190,7 +190,7 @@ StartUpdateProcess(int argc,
// The updater command line is of the form:
// updater.exe update-dir apply [wait-pid [callback-dir callback-path args]]
LPWSTR cmdLine = MakeCommandLine(argc, argv);
auto cmdLine = mozilla::MakeCommandLine(argc, argv);
int index = 3;
if (IsOldCommandline(argc, argv)) {
@ -212,8 +212,8 @@ StartUpdateProcess(int argc,
// do anything special that it needs to do for service updates.
// Search in updater.cpp for more info on MOZ_USING_SERVICE.
putenv(const_cast<char*>("MOZ_USING_SERVICE=1"));
LOG(("Starting service with cmdline: %ls", cmdLine));
processStarted = CreateProcessW(argv[0], cmdLine,
LOG(("Starting service with cmdline: %ls", cmdLine.get()));
processStarted = CreateProcessW(argv[0], cmdLine.get(),
nullptr, nullptr, FALSE,
CREATE_DEFAULT_ERROR_MODE,
nullptr,
@ -279,13 +279,12 @@ StartUpdateProcess(int argc,
DWORD lastError = GetLastError();
LOG_WARN(("Could not create process as current user, "
"updaterPath: %ls; cmdLine: %ls. (%d)",
argv[0], cmdLine, lastError));
argv[0], cmdLine.get(), lastError));
}
// Empty value on putenv is how you remove an env variable in Windows
putenv(const_cast<char*>("MOZ_USING_SERVICE="));
free(cmdLine);
return updateWasSuccessful;
}

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

@ -12,6 +12,7 @@ import sys
import atexit
import shared_telemetry_utils as utils
from ctypes import c_int
from shared_telemetry_utils import ParserError
from collections import OrderedDict
atexit.register(ParserError.exit_func)
@ -517,6 +518,11 @@ associated with the histogram. Returns None if no guarding is necessary."""
ParserError('Value for key "{0}" in histogram "{1}" should be {2}.'
.format(key, name, nice_type_name(key_type))).handle_later()
# Make sure the max range is lower than or equal to INT_MAX
if "high" in definition and not c_int(definition["high"]).value > 0:
ParserError('Value for high in histogram "{0}" should be lower or equal to INT_MAX.'
.format(nice_type_name(c_int))).handle_later()
for key, key_type in type_checked_list_fields.iteritems():
if key not in definition:
continue

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

@ -122,6 +122,29 @@ class TestParser(unittest.TestCase):
parse_histograms.whitelists = None
def test_high_value(self):
SAMPLE_HISTOGRAM = {
"TEST_HISTOGRAM_WHITELIST_N_BUCKETS": {
"record_in_processes": ["main", "content"],
"alert_emails": ["team@mozilla.xyz"],
"bug_numbers": [1383793],
"expires_in_version": "never",
"kind": "exponential",
"low": 1024,
"high": 2 ** 64,
"n_buckets": 100,
"description": "Test histogram",
}
}
histograms = load_histogram(SAMPLE_HISTOGRAM)
parse_histograms.load_whitelist()
parse_histograms.Histogram('TEST_HISTOGRAM_WHITELIST_N_BUCKETS',
histograms['TEST_HISTOGRAM_WHITELIST_N_BUCKETS'],
strict_type_checks=True)
self.assertRaises(SystemExit, ParserError.exit_func)
def test_high_n_buckets(self):
SAMPLE_HISTOGRAM = {
"TEST_HISTOGRAM_WHITELIST_N_BUCKETS": {

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

@ -92,10 +92,6 @@ def main():
# Allow overwriting of the upload url with an environmental variable
if 'SOCORRO_SYMBOL_UPLOAD_URL' in os.environ:
url = os.environ['SOCORRO_SYMBOL_UPLOAD_URL']
elif os.environ.get('MOZ_SCM_LEVEL', '1') == '1':
# Use the Tecken staging server for try uploads for now.
# This will eventually be changed in bug 1138617.
url = 'https://symbols.stage.mozaws.net/upload/'
else:
url = DEFAULT_URL

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

@ -3092,7 +3092,7 @@ int NS_main(int argc, NS_tchar **argv)
return 1;
}
wchar_t *cmdLine = MakeCommandLine(argc - 1, argv + 1);
auto cmdLine = mozilla::MakeCommandLine(argc - 1, argv + 1);
if (!cmdLine) {
CloseHandle(elevatedFileHandle);
return 1;
@ -3238,12 +3238,11 @@ int NS_main(int argc, NS_tchar **argv)
SEE_MASK_NOCLOSEPROCESS;
sinfo.hwnd = nullptr;
sinfo.lpFile = argv[0];
sinfo.lpParameters = cmdLine;
sinfo.lpParameters = cmdLine.get();
sinfo.lpVerb = L"runas";
sinfo.nShow = SW_SHOWNORMAL;
bool result = ShellExecuteEx(&sinfo);
free(cmdLine);
if (result) {
WaitForSingleObject(sinfo.hProcess, INFINITE);

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

@ -17,3 +17,8 @@
.toolbar-landscape-page {
list-style-image: url("moz-icon://stock/gtk-orientation-landscape?size=button");
}
#pageNumber {
/* 3 chars + 4px padding left + 2px padding right + 2*6px border */
width: calc(18px + 3ch);
}

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

@ -0,0 +1,390 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#ifndef mozilla_CmdLineAndEnvUtils_h
#define mozilla_CmdLineAndEnvUtils_h
// NB: This code may be used outside of xul and thus must not depend on XPCOM
#if defined(MOZILLA_INTERNAL_API)
#include "prenv.h"
#include "prprf.h"
#include <string.h>
#elif defined(XP_WIN)
#include <stdlib.h>
#endif
#if defined(XP_WIN)
#include "mozilla/Move.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Vector.h"
#include <wchar.h>
#endif // defined(XP_WIN)
#include "mozilla/TypedEnumBits.h"
#include <ctype.h>
#include <stdint.h>
// Undo X11/X.h's definition of None
#undef None
namespace mozilla {
enum ArgResult {
ARG_NONE = 0,
ARG_FOUND = 1,
ARG_BAD = 2 // you wanted a param, but there isn't one
};
template <typename CharT>
inline void
RemoveArg(int& argc, CharT **argv)
{
do {
*argv = *(argv + 1);
++argv;
} while (*argv);
--argc;
}
namespace internal {
template <typename FuncT, typename CharT>
inline bool
strimatch(FuncT aToLowerFn, const CharT* lowerstr, const CharT* mixedstr)
{
while(*lowerstr) {
if (!*mixedstr) return false; // mixedstr is shorter
if (static_cast<CharT>(aToLowerFn(*mixedstr)) != *lowerstr) return false; // no match
++lowerstr;
++mixedstr;
}
if (*mixedstr) return false; // lowerstr is shorter
return true;
}
} // namespace internal
inline bool
strimatch(const char* lowerstr, const char* mixedstr)
{
return internal::strimatch(&tolower, lowerstr, mixedstr);
}
inline bool
strimatch(const wchar_t* lowerstr, const wchar_t* mixedstr)
{
return internal::strimatch(&towlower, lowerstr, mixedstr);
}
enum class FlagLiteral
{
osint,
safemode
};
template <typename CharT, FlagLiteral Literal>
inline const CharT* GetLiteral();
#define DECLARE_FLAG_LITERAL(enum_name, literal) \
template <> inline \
const char* GetLiteral<char, FlagLiteral::enum_name>() \
{ \
return literal; \
} \
\
template <> inline \
const wchar_t* GetLiteral<wchar_t, FlagLiteral::enum_name>() \
{ \
return L##literal; \
}
DECLARE_FLAG_LITERAL(osint, "osint")
DECLARE_FLAG_LITERAL(safemode, "safe-mode")
enum class CheckArgFlag : uint32_t
{
None = 0,
CheckOSInt = (1 << 0), // Retrun ARG_BAD if osint arg is also present.
RemoveArg = (1 << 1) // Remove the argument from the argv array.
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CheckArgFlag)
/**
* Check for a commandline flag. If the flag takes a parameter, the
* parameter is returned in aParam. Flags may be in the form -arg or
* --arg (or /arg on win32).
*
* @param aArgc The argc value.
* @param aArgv The original argv.
* @param aArg the parameter to check. Must be lowercase.
* @param aParam if non-null, the -arg <data> will be stored in this pointer.
* This is *not* allocated, but rather a pointer to the argv data.
* @param aFlags Flags @see CheckArgFlag
*/
template <typename CharT>
inline ArgResult
CheckArg(int& aArgc, CharT** aArgv, const CharT* aArg, const CharT **aParam,
CheckArgFlag aFlags)
{
MOZ_ASSERT(aArgv && aArg);
CharT **curarg = aArgv + 1; // skip argv[0]
ArgResult ar = ARG_NONE;
while (*curarg) {
CharT *arg = curarg[0];
if (arg[0] == '-'
#if defined(XP_WIN)
|| *arg == '/'
#endif
) {
++arg;
if (*arg == '-') {
++arg;
}
if (strimatch(aArg, arg)) {
if (aFlags & CheckArgFlag::RemoveArg) {
RemoveArg(aArgc, curarg);
} else {
++curarg;
}
if (!aParam) {
ar = ARG_FOUND;
break;
}
if (*curarg) {
if (**curarg == '-'
#if defined(XP_WIN)
|| **curarg == '/'
#endif
) {
return ARG_BAD;
}
*aParam = *curarg;
if (aFlags & CheckArgFlag::RemoveArg) {
RemoveArg(aArgc, curarg);
}
ar = ARG_FOUND;
break;
}
return ARG_BAD;
}
}
++curarg;
}
if ((aFlags & CheckArgFlag::CheckOSInt) && ar == ARG_FOUND) {
ArgResult arOSInt = CheckArg(aArgc, aArgv,
GetLiteral<CharT, FlagLiteral::osint>(),
static_cast<const CharT**>(nullptr),
CheckArgFlag::None);
if (arOSInt == ARG_FOUND) {
ar = ARG_BAD;
#if defined(MOZILLA_INTERNAL_API)
PR_fprintf(PR_STDERR, "Error: argument --osint is invalid\n");
#endif // defined(MOZILLA_INTERNAL_API)
}
}
return ar;
}
#if defined(XP_WIN)
namespace internal {
/**
* Get the length that the string will take and takes into account the
* additional length if the string needs to be quoted and if characters need to
* be escaped.
*/
inline int
ArgStrLen(const wchar_t *s)
{
int backslashes = 0;
int i = wcslen(s);
bool hasDoubleQuote = wcschr(s, L'"') != nullptr;
// Only add doublequotes if the string contains a space or a tab
bool addDoubleQuotes = wcspbrk(s, L" \t") != nullptr;
if (addDoubleQuotes) {
i += 2; // initial and final duoblequote
}
if (hasDoubleQuote) {
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes preceding the doublequote
i += backslashes + 1;
}
backslashes = 0;
}
++s;
}
}
return i;
}
/**
* Copy string "s" to string "d", quoting the argument as appropriate and
* escaping doublequotes along with any backslashes that immediately precede
* doublequotes.
* The CRT parses this to retrieve the original argc/argv that we meant,
* see STDARGV.C in the MSVC CRT sources.
*
* @return the end of the string
*/
inline wchar_t*
ArgToString(wchar_t *d, const wchar_t *s)
{
int backslashes = 0;
bool hasDoubleQuote = wcschr(s, L'"') != nullptr;
// Only add doublequotes if the string contains a space or a tab
bool addDoubleQuotes = wcspbrk(s, L" \t") != nullptr;
if (addDoubleQuotes) {
*d = '"'; // initial doublequote
++d;
}
if (hasDoubleQuote) {
int i;
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes preceding the doublequote
for (i = 0; i <= backslashes; ++i) {
*d = '\\';
++d;
}
}
backslashes = 0;
}
*d = *s;
++d; ++s;
}
} else {
wcscpy(d, s);
d += wcslen(s);
}
if (addDoubleQuotes) {
*d = '"'; // final doublequote
++d;
}
return d;
}
} // namespace internal
/**
* Creates a command line from a list of arguments.
*/
inline UniquePtr<wchar_t[]>
MakeCommandLine(int argc, wchar_t **argv)
{
int i;
int len = 0;
// The + 1 of the last argument handles the allocation for null termination
for (i = 0; i < argc; ++i) {
len += internal::ArgStrLen(argv[i]) + 1;
}
// Protect against callers that pass 0 arguments
if (len == 0) {
len = 1;
}
auto s = MakeUnique<wchar_t[]>(len);
if (!s) {
return nullptr;
}
wchar_t *c = s.get();
for (i = 0; i < argc; ++i) {
c = internal::ArgToString(c, argv[i]);
if (i + 1 != argc) {
*c = ' ';
++c;
}
}
*c = '\0';
return Move(s);
}
#endif // defined(XP_WIN)
// Save literal putenv string to environment variable.
inline void
SaveToEnv(const char *aEnvString)
{
#if defined(MOZILLA_INTERNAL_API)
char *expr = strdup(aEnvString);
if (expr) {
PR_SetEnv(expr);
}
// We intentionally leak |expr| here since it is required by PR_SetEnv.
MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(expr);
#elif defined(XP_WIN)
// This is the same as the NSPR implementation
// (Note that we don't need to do a strdup for this case; the CRT makes a copy)
_putenv(aEnvString);
#else
#error "Not implemented for this configuration"
#endif
}
inline bool
EnvHasValue(const char* aVarName)
{
#if defined(MOZILLA_INTERNAL_API)
const char* val = PR_GetEnv(aVarName);
return val && *val;
#elif defined(XP_WIN)
// This is the same as the NSPR implementation
const char* val = getenv(aVarName);
return val && *val;
#else
#error "Not implemented for this configuration"
#endif
}
} // namespace mozilla
#endif // mozilla_CmdLineAndEnvUtils_h

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

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#ifndef mozilla_PolicyChecks_h
#define mozilla_PolicyChecks_h
#if defined(XP_WIN)
#include <windows.h>
// NB: This code must be able to run apart from XPCOM
namespace mozilla {
inline bool
PolicyHasRegValue(HKEY aKey, LPCWSTR aName, DWORD* aValue)
{
DWORD len = sizeof(DWORD);
LONG ret = ::RegGetValueW(aKey, L"SOFTWARE\\Policies\\Mozilla\\Firefox", aName,
RRF_RT_DWORD, nullptr, aValue, &len);
return ret == ERROR_SUCCESS;
}
inline bool
PolicyCheckBoolean(LPCWSTR aPolicyName)
{
DWORD value;
if (PolicyHasRegValue(HKEY_LOCAL_MACHINE, aPolicyName, &value)) {
return value == 1;
}
if (PolicyHasRegValue(HKEY_CURRENT_USER, aPolicyName, &value)) {
return value == 1;
}
return false;
}
} // namespace mozilla
#endif // defined(XP_WIN)
#endif // mozilla_PolicyChecks_h

93
toolkit/xre/SafeMode.h Normal file
Просмотреть файл

@ -0,0 +1,93 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#ifndef mozilla_SafeMode_h
#define mozilla_SafeMode_h
// NB: This code must be able to run apart from XPCOM
#include "mozilla/CmdLineAndEnvUtils.h"
#include "mozilla/Maybe.h"
#if defined(XP_WIN)
#include "mozilla/PolicyChecks.h"
#include <windows.h>
#endif // defined(XP_WIN)
// Undo X11/X.h's definition of None
#undef None
namespace mozilla {
enum class SafeModeFlag : uint32_t
{
None = 0,
Unset = (1 << 0)
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SafeModeFlag)
template <typename CharT>
inline Maybe<bool>
IsSafeModeRequested(int& aArgc, CharT* aArgv[],
const SafeModeFlag aFlags = SafeModeFlag::Unset)
{
CheckArgFlag checkArgFlags = CheckArgFlag::CheckOSInt;
if (aFlags & SafeModeFlag::Unset) {
checkArgFlags |= CheckArgFlag::RemoveArg;
}
ArgResult ar = CheckArg(aArgc, aArgv,
GetLiteral<CharT, FlagLiteral::safemode>(),
static_cast<const CharT**>(nullptr),
checkArgFlags);
if (ar == ARG_BAD) {
return Nothing();
}
bool result = ar == ARG_FOUND;
#if defined(XP_WIN)
// If the shift key is pressed and the ctrl and / or alt keys are not pressed
// during startup, start in safe mode. GetKeyState returns a short and the high
// order bit will be 1 if the key is pressed. By masking the returned short
// with 0x8000 the result will be 0 if the key is not pressed and non-zero
// otherwise.
if ((GetKeyState(VK_SHIFT) & 0x8000) &&
!(GetKeyState(VK_CONTROL) & 0x8000) &&
!(GetKeyState(VK_MENU) & 0x8000) &&
!EnvHasValue("MOZ_DISABLE_SAFE_MODE_KEY")) {
result = true;
}
if (result && PolicyCheckBoolean(L"DisableSafeMode")) {
result = false;
}
#endif // defined(XP_WIN)
#if defined(XP_MACOSX)
if ((GetCurrentEventKeyModifiers() & optionKey) &&
!EnvHasValue("MOZ_DISABLE_SAFE_MODE_KEY")) {
result = true;
}
#endif // defined(XP_MACOSX)
// The Safe Mode Policy should not be enforced for the env var case
// (used by updater and crash-recovery).
if (EnvHasValue("MOZ_SAFE_MODE_RESTART")) {
result = true;
if (aFlags & SafeModeFlag::Unset) {
// unset the env variable
SaveToEnv("MOZ_SAFE_MODE_RESTART=");
}
}
return Some(result);
}
} // namespace mozilla
#endif // mozilla_SafeMode_h

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

@ -30,13 +30,19 @@ EXPORTS += [
'nsIAppStartupNotifier.h',
]
EXPORTS.mozilla += ['AutoSQLiteLifetime.h', 'Bootstrap.h']
EXPORTS.mozilla += [
'AutoSQLiteLifetime.h',
'Bootstrap.h',
'CmdLineAndEnvUtils.h',
'SafeMode.h',
]
if CONFIG['MOZ_INSTRUMENT_EVENT_LOOP']:
EXPORTS += ['EventTracer.h']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
EXPORTS.mozilla += [
'PolicyChecks.h',
'WinDllServices.h',
]
SOURCES += [

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

@ -10,6 +10,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/Attributes.h"
#include "mozilla/ChaosMode.h"
#include "mozilla/CmdLineAndEnvUtils.h"
#include "mozilla/IOInterposer.h"
#include "mozilla/Likely.h"
#include "mozilla/MemoryChecking.h"
@ -232,6 +233,7 @@
#endif
#include "mozilla/mozalloc_oom.h"
#include "SafeMode.h"
extern uint32_t gRestartMode;
extern void InstallSignalHandlers(const char *ProgramName);
@ -306,25 +308,6 @@ using mozilla::dom::ContentParent;
using mozilla::dom::ContentChild;
using mozilla::intl::LocaleService;
// Save literal putenv string to environment variable.
static void
SaveToEnv(const char *putenv)
{
char *expr = strdup(putenv);
if (expr)
PR_SetEnv(expr);
// We intentionally leak |expr| here since it is required by PR_SetEnv.
MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(expr);
}
// Tests that an environment variable exists and has a value
static bool
EnvHasValue(const char *name)
{
const char *val = PR_GetEnv(name);
return (val && *val);
}
// Save the given word to the specified environment variable.
static void
SaveWordToEnv(const char *name, const nsACString & word)
@ -400,22 +383,6 @@ SaveFileToEnvIfUnset(const char *name, nsIFile *file)
SaveFileToEnv(name, file);
}
static bool
strimatch(const char* lowerstr, const char* mixedstr)
{
while(*lowerstr) {
if (!*mixedstr) return false; // mixedstr is shorter
if (tolower(*mixedstr) != *lowerstr) return false; // no match
++lowerstr;
++mixedstr;
}
if (*mixedstr) return false; // lowerstr is shorter
return true;
}
static bool gIsExpectedExit = false;
void MozExpectedExit() {
@ -482,94 +449,22 @@ enum RemoteResult {
REMOTE_ARG_BAD = 2
};
enum ArgResult {
ARG_NONE = 0,
ARG_FOUND = 1,
ARG_BAD = 2 // you wanted a param, but there isn't one
};
static void RemoveArg(char **argv)
{
do {
*argv = *(argv + 1);
++argv;
} while (*argv);
--gArgc;
}
/**
* Check for a commandline flag. If the flag takes a parameter, the
* parameter is returned in aParam. Flags may be in the form -arg or
* --arg (or /arg on win32).
*
* @param aArg the parameter to check. Must be lowercase.
* @param aCheckOSInt if true returns ARG_BAD if the osint argument is present
* when aArg is also present.
* @param aParam if non-null, the -arg <data> will be stored in this pointer.
* This is *not* allocated, but rather a pointer to the argv data.
* @param aRemArg if true, the argument is removed from the gArgv array.
* @param aFlags flags @see CheckArgFlag
*/
static ArgResult
CheckArg(const char* aArg, bool aCheckOSInt = false, const char **aParam = nullptr, bool aRemArg = true)
CheckArg(const char* aArg, const char** aParam = nullptr,
CheckArgFlag aFlags = CheckArgFlag::RemoveArg)
{
MOZ_ASSERT(gArgv, "gArgv must be initialized before CheckArg()");
char **curarg = gArgv + 1; // skip argv[0]
ArgResult ar = ARG_NONE;
while (*curarg) {
char *arg = curarg[0];
if (arg[0] == '-'
#if defined(XP_WIN)
|| *arg == '/'
#endif
) {
++arg;
if (*arg == '-')
++arg;
if (strimatch(aArg, arg)) {
if (aRemArg)
RemoveArg(curarg);
else
++curarg;
if (!aParam) {
ar = ARG_FOUND;
break;
}
if (*curarg) {
if (**curarg == '-'
#if defined(XP_WIN)
|| **curarg == '/'
#endif
)
return ARG_BAD;
*aParam = *curarg;
if (aRemArg)
RemoveArg(curarg);
ar = ARG_FOUND;
break;
}
return ARG_BAD;
}
}
++curarg;
}
if (aCheckOSInt && ar == ARG_FOUND) {
ArgResult arOSInt = CheckArg("osint");
if (arOSInt == ARG_FOUND) {
ar = ARG_BAD;
PR_fprintf(PR_STDERR, "Error: argument --osint is invalid\n");
}
}
return ar;
return CheckArg(gArgc, gArgv, aArg, aParam, aFlags);
}
/**
@ -582,38 +477,7 @@ CheckArg(const char* aArg, bool aCheckOSInt = false, const char **aParam = nullp
static ArgResult
CheckArgExists(const char* aArg)
{
char **curarg = gArgv + 1; // skip argv[0]
while (*curarg) {
char *arg = curarg[0];
if (arg[0] == '-'
#if defined(XP_WIN)
|| *arg == '/'
#endif
) {
++arg;
if (*arg == '-')
++arg;
char delimiter = '=';
#if defined(XP_WIN)
delimiter = ':';
#endif
int i;
for (i = 0; arg[i] && arg[i] != delimiter; i++) {}
char tmp = arg[i];
arg[i] = '\0';
bool found = strimatch(aArg, arg);
arg[i] = tmp;
if (found) {
return ARG_FOUND;
}
}
++curarg;
}
return ARG_NONE;
return CheckArg(aArg, nullptr, CheckArgFlag::None);
}
#if defined(XP_WIN)
@ -1799,14 +1663,14 @@ ParseRemoteCommandLine(nsCString& program,
{
ArgResult ar;
ar = CheckArg("p", false, profile, false);
ar = CheckArg("p", profile, CheckArgFlag::None);
if (ar == ARG_BAD) {
// Leave it to the normal command line handling to handle this situation.
return REMOTE_NOT_FOUND;
}
const char *temp = nullptr;
ar = CheckArg("a", true, &temp);
ar = CheckArg("a", &temp, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -a requires an application name\n");
return REMOTE_ARG_BAD;
@ -1815,7 +1679,7 @@ ParseRemoteCommandLine(nsCString& program,
program.Assign(temp);
}
ar = CheckArg("u", true, username);
ar = CheckArg("u", username, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -u requires a username\n");
return REMOTE_ARG_BAD;
@ -2322,7 +2186,7 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
*aResult = nullptr;
*aStartOffline = false;
ar = CheckArg("offline", true);
ar = CheckArg("offline", nullptr, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --offline is invalid when argument --osint is specified\n");
return NS_ERROR_FAILURE;
@ -2344,7 +2208,7 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
}
// reset-profile and migration args need to be checked before any profiles are chosen below.
ar = CheckArg("reset-profile", true);
ar = CheckArg("reset-profile", nullptr, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --reset-profile is invalid when argument --osint is specified\n");
return NS_ERROR_FAILURE;
@ -2353,7 +2217,7 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
gDoProfileReset = true;
}
ar = CheckArg("migration", true);
ar = CheckArg("migration", nullptr, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --migration is invalid when argument --osint is specified\n");
return NS_ERROR_FAILURE;
@ -2380,8 +2244,8 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
// Clear out flags that we handled (or should have handled!) last startup.
const char *dummy;
CheckArg("p", false, &dummy);
CheckArg("profile", false, &dummy);
CheckArg("p", &dummy);
CheckArg("profile", &dummy);
CheckArg("profilemanager");
if (gDoProfileReset) {
@ -2410,7 +2274,7 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
return NS_LockProfilePath(lf, localDir, nullptr, aResult);
}
ar = CheckArg("profile", true, &arg);
ar = CheckArg("profile", &arg, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --profile requires a path\n");
return NS_ERROR_FAILURE;
@ -2444,7 +2308,7 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
return ProfileLockedDialog(lf, lf, unlocker, aNative, aResult);
}
ar = CheckArg("createprofile", true, &arg);
ar = CheckArg("createprofile", &arg, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --createprofile requires a profile name\n");
return NS_ERROR_FAILURE;
@ -2500,7 +2364,7 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
rv = aProfileSvc->GetProfileCount(&count);
NS_ENSURE_SUCCESS(rv, rv);
ar = CheckArg("p", false, &arg);
ar = CheckArg("p", &arg);
if (ar == ARG_BAD) {
ar = CheckArg("osint");
if (ar == ARG_FOUND) {
@ -2565,7 +2429,7 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
}
}
ar = CheckArg("profilemanager", true);
ar = CheckArg("profilemanager", nullptr, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --profilemanager is invalid when argument --osint is specified\n");
return NS_ERROR_FAILURE;
@ -3161,33 +3025,6 @@ public:
#endif
};
#ifdef XP_WIN
namespace {
bool PolicyHasRegValue(HKEY aKey, LPCWSTR aName, DWORD* aValue)
{
DWORD len = sizeof(DWORD);
LONG ret = ::RegGetValueW(aKey, L"SOFTWARE\\Policies\\Mozilla\\Firefox", aName,
RRF_RT_DWORD, nullptr, aValue, &len);
return ret == ERROR_SUCCESS;
}
bool SafeModeBlockedByPolicy()
{
LPCTSTR policyName = L"DisableSafeMode";
DWORD value;
if (PolicyHasRegValue(HKEY_LOCAL_MACHINE, policyName, &value)) {
return value == 1;
}
if (PolicyHasRegValue(HKEY_CURRENT_USER, policyName, &value)) {
return value == 1;
}
return false;
}
} // anonymous namespace
#endif // XP_WIN
#if defined(XP_UNIX) && !defined(ANDROID)
static SmprintfPointer
FormatUid(uid_t aId)
@ -3366,7 +3203,7 @@ XREMain::XRE_mainInit(bool* aExitFlag)
// Check for application.ini overrides
const char* override = nullptr;
ar = CheckArg("override", true, &override);
ar = CheckArg("override", &override, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
Output(true, "Incorrect number of arguments passed to --override");
return 1;
@ -3586,49 +3423,12 @@ XREMain::XRE_mainInit(bool* aExitFlag)
gRestartArgv[gRestartArgc] = nullptr;
ar = CheckArg("safe-mode", true);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --safe-mode is invalid when argument --osint is specified\n");
Maybe<bool> safeModeRequested = IsSafeModeRequested(gArgc, gArgv);
if (!safeModeRequested) {
return 1;
}
if (ar == ARG_FOUND) {
gSafeMode = true;
}
#ifdef XP_WIN
// If the shift key is pressed and the ctrl and / or alt keys are not pressed
// during startup start in safe mode. GetKeyState returns a short and the high
// order bit will be 1 if the key is pressed. By masking the returned short
// with 0x8000 the result will be 0 if the key is not pressed and non-zero
// otherwise.
if ((GetKeyState(VK_SHIFT) & 0x8000) &&
!(GetKeyState(VK_CONTROL) & 0x8000) &&
!(GetKeyState(VK_MENU) & 0x8000) &&
!EnvHasValue("MOZ_DISABLE_SAFE_MODE_KEY")) {
gSafeMode = true;
}
#endif
#ifdef XP_MACOSX
if ((GetCurrentEventKeyModifiers() & optionKey) &&
!EnvHasValue("MOZ_DISABLE_SAFE_MODE_KEY"))
gSafeMode = true;
#endif
#ifdef XP_WIN
if (gSafeMode && SafeModeBlockedByPolicy()) {
gSafeMode = false;
}
#endif
// The Safe Mode Policy should not be enforced for the env var case
// (used by updater and crash-recovery).
if (EnvHasValue("MOZ_SAFE_MODE_RESTART")) {
gSafeMode = true;
// unset the env variable
SaveToEnv("MOZ_SAFE_MODE_RESTART=");
}
gSafeMode = safeModeRequested.value();
#ifdef XP_WIN
{
@ -3681,7 +3481,7 @@ if (gSafeMode && SafeModeBlockedByPolicy()) {
// Handle --no-remote and --new-instance command line arguments. Setup
// the environment to better accommodate other components and various
// restart scenarios.
ar = CheckArg("no-remote", true);
ar = CheckArg("no-remote", nullptr, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --no-remote is invalid when argument --osint is specified\n");
return 1;
@ -3690,7 +3490,7 @@ if (gSafeMode && SafeModeBlockedByPolicy()) {
SaveToEnv("MOZ_NO_REMOTE=1");
}
ar = CheckArg("new-instance", true);
ar = CheckArg("new-instance", nullptr, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --new-instance is invalid when argument --osint is specified\n");
return 1;
@ -3717,7 +3517,7 @@ if (gSafeMode && SafeModeBlockedByPolicy()) {
NS_ENSURE_SUCCESS(rv, 1);
// Check for --register, which registers chrome and then exits immediately.
ar = CheckArg("register", true);
ar = CheckArg("register", nullptr, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --register is invalid when argument --osint is specified\n");
return 1;
@ -4253,7 +4053,7 @@ XREMain::XRE_mainStartup(bool* aExitFlag)
// to make sure that the maintenance service successfully launches the
// callback application.
const char *logFile = nullptr;
if (ARG_FOUND == CheckArg("dump-args", false, &logFile)) {
if (ARG_FOUND == CheckArg("dump-args", &logFile)) {
FILE* logFP = fopen(logFile, "wb");
if (logFP) {
for (int i = 1; i < gRestartArgc; ++i) {
@ -5108,7 +4908,7 @@ XRE_InitCommandLine(int aArgc, char* aArgv[])
#endif
const char *path = nullptr;
ArgResult ar = CheckArg("greomni", false, &path);
ArgResult ar = CheckArg("greomni", &path);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --greomni requires a path argument\n");
return NS_ERROR_FAILURE;
@ -5124,7 +4924,7 @@ XRE_InitCommandLine(int aArgc, char* aArgv[])
return rv;
}
ar = CheckArg("appomni", false, &path);
ar = CheckArg("appomni", &path);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --appomni requires a path argument\n");
return NS_ERROR_FAILURE;

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

@ -11,6 +11,7 @@
#define nsWindowsRestart_cpp
#endif
#include "mozilla/CmdLineAndEnvUtils.h"
#include "nsUTF8Utils.h"
#include <shellapi.h>
@ -19,135 +20,6 @@
#include <userenv.h>
#pragma comment(lib, "userenv.lib")
/**
* Get the length that the string will take and takes into account the
* additional length if the string needs to be quoted and if characters need to
* be escaped.
*/
static int ArgStrLen(const wchar_t *s)
{
int backslashes = 0;
int i = wcslen(s);
BOOL hasDoubleQuote = wcschr(s, L'"') != nullptr;
// Only add doublequotes if the string contains a space or a tab
BOOL addDoubleQuotes = wcspbrk(s, L" \t") != nullptr;
if (addDoubleQuotes) {
i += 2; // initial and final duoblequote
}
if (hasDoubleQuote) {
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes preceding the doublequote
i += backslashes + 1;
}
backslashes = 0;
}
++s;
}
}
return i;
}
/**
* Copy string "s" to string "d", quoting the argument as appropriate and
* escaping doublequotes along with any backslashes that immediately precede
* doublequotes.
* The CRT parses this to retrieve the original argc/argv that we meant,
* see STDARGV.C in the MSVC CRT sources.
*
* @return the end of the string
*/
static wchar_t* ArgToString(wchar_t *d, const wchar_t *s)
{
int backslashes = 0;
BOOL hasDoubleQuote = wcschr(s, L'"') != nullptr;
// Only add doublequotes if the string contains a space or a tab
BOOL addDoubleQuotes = wcspbrk(s, L" \t") != nullptr;
if (addDoubleQuotes) {
*d = '"'; // initial doublequote
++d;
}
if (hasDoubleQuote) {
int i;
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes preceding the doublequote
for (i = 0; i <= backslashes; ++i) {
*d = '\\';
++d;
}
}
backslashes = 0;
}
*d = *s;
++d; ++s;
}
} else {
wcscpy(d, s);
d += wcslen(s);
}
if (addDoubleQuotes) {
*d = '"'; // final doublequote
++d;
}
return d;
}
/**
* Creates a command line from a list of arguments. The returned
* string is allocated with "malloc" and should be "free"d.
*
* argv is UTF8
*/
wchar_t*
MakeCommandLine(int argc, wchar_t **argv)
{
int i;
int len = 0;
// The + 1 of the last argument handles the allocation for null termination
for (i = 0; i < argc; ++i)
len += ArgStrLen(argv[i]) + 1;
// Protect against callers that pass 0 arguments
if (len == 0)
len = 1;
wchar_t *s = (wchar_t*) malloc(len * sizeof(wchar_t));
if (!s)
return nullptr;
wchar_t *c = s;
for (i = 0; i < argc; ++i) {
c = ArgToString(c, argv[i]);
if (i + 1 != argc) {
*c = ' ';
++c;
}
}
*c = '\0';
return s;
}
/**
* Convert UTF8 to UTF16 without using the normal XPCOM goop, which we
* can't link to updater.exe.
@ -222,10 +94,9 @@ WinLaunchChild(const wchar_t *exePath,
HANDLE userToken,
HANDLE *hProcess)
{
wchar_t *cl;
BOOL ok;
cl = MakeCommandLine(argc, argv);
mozilla::UniquePtr<wchar_t[]> cl(mozilla::MakeCommandLine(argc, argv));
if (!cl) {
return FALSE;
}
@ -237,7 +108,7 @@ WinLaunchChild(const wchar_t *exePath,
if (userToken == nullptr) {
ok = CreateProcessW(exePath,
cl,
cl.get(),
nullptr, // no special security attributes
nullptr, // no special thread attributes
FALSE, // don't inherit filehandles
@ -256,7 +127,7 @@ WinLaunchChild(const wchar_t *exePath,
ok = CreateProcessAsUserW(userToken,
exePath,
cl,
cl.get(),
nullptr, // no special security attributes
nullptr, // no special thread attributes
FALSE, // don't inherit filehandles
@ -294,7 +165,5 @@ WinLaunchChild(const wchar_t *exePath,
LocalFree(lpMsgBuf);
}
free(cl);
return ok;
}

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

@ -2,6 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsWindowsWMain_cpp
#define nsWindowsWMain_cpp
// This file is a .cpp file meant to be included in nsBrowserApp.cpp and other
// similar bootstrap code. It converts wide-character windows wmain into UTF-8
// narrow-character strings.
@ -101,6 +104,14 @@ int wmain(int argc, WCHAR **argv)
SanitizeEnvironmentVariables();
SetDllDirectoryW(L"");
// Only run this code if LauncherProcessWin.h was included beforehand, thus
// signalling that the hosting process should support launcher mode.
#if defined(mozilla_LauncherProcessWin_h)
if (mozilla::RunAsLauncherProcess(argc, argv)) {
return mozilla::LauncherMain(argc, argv);
}
#endif // defined(mozilla_LauncherProcessWin_h)
char **argvConverted = new char*[argc + 1];
if (!argvConverted)
return 127;
@ -134,3 +145,5 @@ int wmain(int argc, WCHAR **argv)
return result;
}
#endif // nsWindowsWMain_cpp

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

@ -69,10 +69,10 @@ verifyCmdLineCreation(wchar_t *inCmdLine,
wcscat(inCmdLineNew, inCmdLine);
LPWSTR *inArgv = CommandLineToArgvW(inCmdLineNew, &inArgc);
wchar_t *outCmdLine = MakeCommandLine(inArgc - 1, inArgv + 1);
wchar_t *outCmdLineNew = (wchar_t *) malloc((wcslen(DUMMY_ARG1) + wcslen(outCmdLine) + 1) * sizeof(wchar_t));
auto outCmdLine = mozilla::MakeCommandLine(inArgc - 1, inArgv + 1);
wchar_t *outCmdLineNew = (wchar_t *) malloc((wcslen(DUMMY_ARG1) + wcslen(outCmdLine.get()) + 1) * sizeof(wchar_t));
wcscpy(outCmdLineNew, DUMMY_ARG1);
wcscat(outCmdLineNew, outCmdLine);
wcscat(outCmdLineNew, outCmdLine.get());
LPWSTR *outArgv = CommandLineToArgvW(outCmdLineNew, &outArgc);
if (VERBOSE) {
@ -80,7 +80,7 @@ verifyCmdLineCreation(wchar_t *inCmdLine,
wprintf(L"Verbose Output\n");
wprintf(L"--------------\n");
wprintf(L"Input command line : >%s<\n", inCmdLine);
wprintf(L"MakeComandLine output: >%s<\n", outCmdLine);
wprintf(L"MakeComandLine output: >%s<\n", outCmdLine.get());
wprintf(L"Expected command line: >%s<\n", compareCmdLine);
wprintf(L"input argc : %d\n", inArgc - 1);
@ -107,7 +107,6 @@ verifyCmdLineCreation(wchar_t *inCmdLine,
LocalFree(outArgv);
free(inCmdLineNew);
free(outCmdLineNew);
free(outCmdLine);
return rv;
}
@ -123,12 +122,11 @@ verifyCmdLineCreation(wchar_t *inCmdLine,
LocalFree(outArgv);
free(inCmdLineNew);
free(outCmdLineNew);
free(outCmdLine);
return rv;
}
}
isEqual = (wcscmp(outCmdLine, compareCmdLine) == 0);
isEqual = (wcscmp(outCmdLine.get(), compareCmdLine) == 0);
if (!isEqual) {
wprintf(L"TEST-%s-FAIL | %s | Command Line Comparison (check %2d)\n",
passes ? L"UNEXPECTED" : L"KNOWN", TEST_NAME, testNum);
@ -139,7 +137,6 @@ verifyCmdLineCreation(wchar_t *inCmdLine,
LocalFree(outArgv);
free(inCmdLineNew);
free(outCmdLineNew);
free(outCmdLine);
return rv;
}
@ -156,7 +153,6 @@ verifyCmdLineCreation(wchar_t *inCmdLine,
LocalFree(outArgv);
free(inCmdLineNew);
free(outCmdLineNew);
free(outCmdLine);
return rv;
}