зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
Коммит
228a150262
|
@ -16,7 +16,6 @@ builtin(include, build/autoconf/codeset.m4)dnl
|
|||
builtin(include, build/autoconf/altoptions.m4)dnl
|
||||
builtin(include, build/autoconf/mozprog.m4)dnl
|
||||
builtin(include, build/autoconf/mozheader.m4)dnl
|
||||
builtin(include, build/autoconf/lto.m4)dnl
|
||||
builtin(include, build/autoconf/frameptr.m4)dnl
|
||||
builtin(include, build/autoconf/compiler-opts.m4)dnl
|
||||
builtin(include, build/autoconf/expandlibs.m4)dnl
|
||||
|
|
|
@ -20,7 +20,6 @@ const kDumpAllStacks = false;
|
|||
const whitelist = {
|
||||
components: new Set([
|
||||
"ContentProcessSingleton.js",
|
||||
"extension-process-script.js",
|
||||
]),
|
||||
modules: new Set([
|
||||
"chrome://mochikit/content/ShutdownLeaksCollector.jsm",
|
||||
|
@ -68,6 +67,7 @@ const whitelist = {
|
|||
"resource://gre/modules/TelemetryUtils.jsm", // bug 1470339
|
||||
|
||||
// Extensions
|
||||
"resource://gre/modules/ExtensionProcessScript.jsm",
|
||||
"resource://gre/modules/ExtensionUtils.jsm",
|
||||
"resource://gre/modules/MessageChannel.jsm",
|
||||
]),
|
||||
|
|
|
@ -307,12 +307,7 @@ export default class AddressForm extends PaymentStateSubscriberMixin(PaymentRequ
|
|||
}
|
||||
let span = container.querySelector(".label-text");
|
||||
span.setAttribute("fieldRequiredSymbol", this.dataset.fieldRequiredSymbol);
|
||||
let required = field.required && !field.disabled;
|
||||
if (required) {
|
||||
container.setAttribute("required", "true");
|
||||
} else {
|
||||
container.removeAttribute("required");
|
||||
}
|
||||
container.toggleAttribute("required", field.required && !field.disabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -421,12 +421,7 @@ export default class BasicCardForm extends PaymentStateSubscriberMixin(PaymentRe
|
|||
continue;
|
||||
}
|
||||
span.setAttribute("fieldRequiredSymbol", this.dataset.fieldRequiredSymbol);
|
||||
let required = field.required && !field.disabled;
|
||||
if (required) {
|
||||
container.setAttribute("required", "true");
|
||||
} else {
|
||||
container.removeAttribute("required");
|
||||
}
|
||||
container.toggleAttribute("required", field.required && !field.disabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -511,11 +511,7 @@ export default class PaymentDialog extends PaymentStateSubscriberMixin(HTMLEleme
|
|||
page.hidden = state.page.id != page.id;
|
||||
}
|
||||
|
||||
if (state.changesPrevented) {
|
||||
this.setAttribute("changes-prevented", "");
|
||||
} else {
|
||||
this.removeAttribute("changes-prevented");
|
||||
}
|
||||
this.toggleAttribute("changes-prevented", state.changesPrevented);
|
||||
this.setAttribute("complete-status", request.completeStatus);
|
||||
this._disabledOverlay.hidden = !state.changesPrevented;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
This is the PDF.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 2.1.97
|
||||
Current extension version is: 2.1.117
|
||||
|
||||
Taken from upstream commit: 45c01974
|
||||
Taken from upstream commit: 417c234c
|
||||
|
|
|
@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '2.1.97';
|
||||
var pdfjsBuild = '45c01974';
|
||||
var pdfjsVersion = '2.1.117';
|
||||
var pdfjsBuild = '417c234c';
|
||||
|
||||
var pdfjsSharedUtil = __w_pdfjs_require__(1);
|
||||
|
||||
|
@ -5141,7 +5141,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
|
|||
|
||||
return worker.messageHandler.sendWithPromise('GetDocRequest', {
|
||||
docId,
|
||||
apiVersion: '2.1.97',
|
||||
apiVersion: '2.1.117',
|
||||
source: {
|
||||
data: source.data,
|
||||
url: source.url,
|
||||
|
@ -6860,9 +6860,9 @@ const InternalRenderTask = function InternalRenderTaskClosure() {
|
|||
return InternalRenderTask;
|
||||
}();
|
||||
|
||||
const version = '2.1.97';
|
||||
const version = '2.1.117';
|
||||
exports.version = version;
|
||||
const build = '45c01974';
|
||||
const build = '417c234c';
|
||||
exports.build = build;
|
||||
|
||||
/***/ }),
|
||||
|
|
|
@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '2.1.97';
|
||||
var pdfjsBuild = '45c01974';
|
||||
var pdfjsVersion = '2.1.117';
|
||||
var pdfjsBuild = '417c234c';
|
||||
|
||||
var pdfjsCoreWorker = __w_pdfjs_require__(1);
|
||||
|
||||
|
@ -375,7 +375,7 @@ var WorkerMessageHandler = {
|
|||
var cancelXHRs = null;
|
||||
var WorkerTasks = [];
|
||||
let apiVersion = docParams.apiVersion;
|
||||
let workerVersion = '2.1.97';
|
||||
let workerVersion = '2.1.117';
|
||||
|
||||
if (apiVersion !== workerVersion) {
|
||||
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
|
||||
|
@ -22045,6 +22045,7 @@ class WidgetAnnotation extends Annotation {
|
|||
data.readOnly = this.hasFieldFlag(_util.AnnotationFieldFlag.READONLY);
|
||||
|
||||
if (data.fieldType === 'Sig') {
|
||||
data.fieldValue = null;
|
||||
this.setFlags(_util.AnnotationFlag.HIDDEN);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1930,7 +1930,7 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * {
|
|||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-resolution: 2dppx) {
|
||||
@media screen and (min-resolution: 1.1dppx) {
|
||||
/* Rules for Retina screens */
|
||||
.toolbarButton::before {
|
||||
transform: scale(0.5);
|
||||
|
|
|
@ -323,6 +323,7 @@ var _view_history = __webpack_require__(32);
|
|||
const DEFAULT_SCALE_DELTA = 1.1;
|
||||
const DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000;
|
||||
const FORCE_PAGES_LOADED_TIMEOUT = 10000;
|
||||
const WHEEL_ZOOM_DISABLED_TIMEOUT = 1000;
|
||||
const DefaultExternalServices = {
|
||||
updateFindControlState(data) {},
|
||||
|
||||
|
@ -1423,6 +1424,7 @@ let PDFViewerApplication = {
|
|||
});
|
||||
};
|
||||
|
||||
window.addEventListener('visibilitychange', webViewerVisibilityChange);
|
||||
window.addEventListener('wheel', webViewerWheel);
|
||||
window.addEventListener('click', webViewerClick);
|
||||
window.addEventListener('keydown', webViewerKeyDown);
|
||||
|
@ -1482,6 +1484,7 @@ let PDFViewerApplication = {
|
|||
let {
|
||||
_boundEvents
|
||||
} = this;
|
||||
window.removeEventListener('visibilitychange', webViewerVisibilityChange);
|
||||
window.removeEventListener('wheel', webViewerWheel);
|
||||
window.removeEventListener('click', webViewerClick);
|
||||
window.removeEventListener('keydown', webViewerKeyDown);
|
||||
|
@ -1917,8 +1920,23 @@ function webViewerPageChanging(evt) {
|
|||
}
|
||||
}
|
||||
|
||||
let zoomDisabled = false,
|
||||
zoomDisabledTimeout;
|
||||
function webViewerVisibilityChange(evt) {
|
||||
if (document.visibilityState === 'visible') {
|
||||
setZoomDisabledTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
let zoomDisabledTimeout = null;
|
||||
|
||||
function setZoomDisabledTimeout() {
|
||||
if (zoomDisabledTimeout) {
|
||||
clearTimeout(zoomDisabledTimeout);
|
||||
}
|
||||
|
||||
zoomDisabledTimeout = setTimeout(function () {
|
||||
zoomDisabledTimeout = null;
|
||||
}, WHEEL_ZOOM_DISABLED_TIMEOUT);
|
||||
}
|
||||
|
||||
function webViewerWheel(evt) {
|
||||
let pdfViewer = PDFViewerApplication.pdfViewer;
|
||||
|
@ -1936,7 +1954,7 @@ function webViewerWheel(evt) {
|
|||
|
||||
evt.preventDefault();
|
||||
|
||||
if (zoomDisabled) {
|
||||
if (zoomDisabledTimeout || document.visibilityState === 'hidden') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1962,11 +1980,7 @@ function webViewerWheel(evt) {
|
|||
pdfViewer.container.scrollTop += dy * scaleCorrectionFactor;
|
||||
}
|
||||
} else {
|
||||
zoomDisabled = true;
|
||||
clearTimeout(zoomDisabledTimeout);
|
||||
zoomDisabledTimeout = setTimeout(function () {
|
||||
zoomDisabled = false;
|
||||
}, 1000);
|
||||
setZoomDisabledTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2209,6 +2223,10 @@ function webViewerKeyDown(evt) {
|
|||
case 82:
|
||||
PDFViewerApplication.rotatePages(90);
|
||||
break;
|
||||
|
||||
case 115:
|
||||
PDFViewerApplication.pdfSidebar.toggle();
|
||||
break;
|
||||
}
|
||||
|
||||
if (turnPage !== 0 && (!turnOnlyIfPageFit || pdfViewer.currentScaleValue === 'page-fit')) {
|
||||
|
|
|
@ -20,7 +20,7 @@ origin:
|
|||
|
||||
# Human-readable identifier for this version/release
|
||||
# Generally "version NNN", "tag SSS", "bookmark SSS"
|
||||
release: version 2.1.97
|
||||
release: version 2.1.117
|
||||
|
||||
# The package's license, where possible using the mnemonic from
|
||||
# https://spdx.org/licenses/
|
||||
|
|
|
@ -359,7 +359,6 @@
|
|||
|
||||
; [Extensions]
|
||||
@RESPATH@/components/extensions-toolkit.manifest
|
||||
@RESPATH@/components/extension-process-script.js
|
||||
@RESPATH@/browser/components/extensions-browser.manifest
|
||||
|
||||
; [Normandy]
|
||||
|
|
|
@ -1552,6 +1552,7 @@ Function .onInit
|
|||
|
||||
!ifdef HAVE_64BIT_BUILD
|
||||
${Unless} ${RunningX64}
|
||||
${AndUnless} ${IsNativeARM64}
|
||||
MessageBox MB_OKCANCEL|MB_ICONSTOP "$(WARN_MIN_SUPPORTED_OSVER_MSG)" IDCANCEL +2
|
||||
ExecShell "open" "${URLSystemRequirements}"
|
||||
Quit
|
||||
|
|
|
@ -181,6 +181,7 @@ Section "MaintenanceService"
|
|||
; Since the Maintenance service can be installed either x86 or x64,
|
||||
; always use the 64-bit registry.
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
; Previous versions always created the uninstall key in the 32-bit registry.
|
||||
; Clean those old entries out if they still exist.
|
||||
SetRegView 32
|
||||
|
@ -218,6 +219,7 @@ Section "MaintenanceService"
|
|||
; WriteRegStr HKLM "${FallbackKey}\0" "name" "Mozilla Corporation"
|
||||
; WriteRegStr HKLM "${FallbackKey}\0" "issuer" "DigiCert SHA2 Assured ID Code Signing CA"
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
SetRegView lastused
|
||||
${EndIf}
|
||||
SectionEnd
|
||||
|
@ -318,6 +320,7 @@ Section "Uninstall"
|
|||
RMDir /REBOOTOK "$INSTDIR"
|
||||
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
SetRegView 64
|
||||
${EndIf}
|
||||
DeleteRegKey HKLM "${MaintUninstallKey}"
|
||||
|
@ -325,6 +328,7 @@ Section "Uninstall"
|
|||
DeleteRegValue HKLM "Software\Mozilla\MaintenanceService" "FFPrefetchDisabled"
|
||||
DeleteRegKey HKLM "${FallbackKey}\"
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
SetRegView lastused
|
||||
${EndIf}
|
||||
SectionEnd
|
||||
|
|
|
@ -128,11 +128,13 @@
|
|||
; Since the Maintenance service can be installed either x86 or x64,
|
||||
; always use the 64-bit registry for checking if an attempt was made.
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
SetRegView 64
|
||||
${EndIf}
|
||||
ReadRegDWORD $5 HKLM "Software\Mozilla\MaintenanceService" "Attempted"
|
||||
ClearErrors
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
SetRegView lastused
|
||||
${EndIf}
|
||||
|
||||
|
@ -590,6 +592,7 @@
|
|||
|
||||
; Running Firefox 32 bit
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
; Running Firefox 32 bit on a Windows 64 bit system
|
||||
ClearErrors
|
||||
ReadRegDWORD $2 HKLM "Software\Mozilla\${AppName}\32to64DidMigrate" "$1"
|
||||
|
@ -903,6 +906,7 @@
|
|||
; if the binary is replaced with a different certificate.
|
||||
; We always use the 64bit registry for certs.
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
SetRegView 64
|
||||
${EndIf}
|
||||
|
||||
|
@ -925,6 +929,7 @@
|
|||
WriteRegStr HKLM "$R0\1" "name" "${CERTIFICATE_NAME_PREVIOUS}"
|
||||
WriteRegStr HKLM "$R0\1" "issuer" "${CERTIFICATE_ISSUER_PREVIOUS}"
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
SetRegView lastused
|
||||
${EndIf}
|
||||
ClearErrors
|
||||
|
|
|
@ -194,6 +194,7 @@ Function un.UninstallServiceIfNotUsed
|
|||
|
||||
; The maintenance service always uses the 64-bit registry on x64 systems
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
SetRegView 64
|
||||
${EndIf}
|
||||
|
||||
|
@ -209,6 +210,7 @@ Function un.UninstallServiceIfNotUsed
|
|||
|
||||
; Restore back the registry view
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
SetRegView lastUsed
|
||||
${EndIf}
|
||||
|
||||
|
@ -219,11 +221,13 @@ Function un.UninstallServiceIfNotUsed
|
|||
ReadRegStr $1 HKLM ${MaintUninstallKey} "UninstallString"
|
||||
SetRegView lastused
|
||||
|
||||
${If} $1 == ""
|
||||
${AndIf} ${RunningX64}
|
||||
SetRegView 64
|
||||
ReadRegStr $1 HKLM ${MaintUninstallKey} "UninstallString"
|
||||
SetRegView lastused
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
${If} $1 == ""
|
||||
SetRegView 64
|
||||
ReadRegStr $1 HKLM ${MaintUninstallKey} "UninstallString"
|
||||
SetRegView lastused
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
; If the uninstall string does not exist, skip executing it
|
||||
|
@ -475,10 +479,12 @@ Section "Uninstall"
|
|||
${If} $MaintCertKey != ""
|
||||
; Always use the 64bit registry for certs on 64bit systems.
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
SetRegView 64
|
||||
${EndIf}
|
||||
DeleteRegKey HKLM "$MaintCertKey"
|
||||
${If} ${RunningX64}
|
||||
${OrIf} ${IsNativeARM64}
|
||||
SetRegView lastused
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
dnl This Source Code Form is subject to the terms of the Mozilla Public
|
||||
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
dnl check if the build is using lto. This is really primitive and only detects llvm based
|
||||
dnl compilers right now.
|
||||
AC_DEFUN([MOZ_DOING_LTO],
|
||||
[
|
||||
cat > conftest.c <<EOF
|
||||
int foo = 1;
|
||||
EOF
|
||||
$1=no
|
||||
if ${CC-cc} ${CFLAGS} -S conftest.c -o conftest.s >/dev/null 2>&1; then
|
||||
if grep '^target triple =' conftest.s; then
|
||||
$1=yes
|
||||
fi
|
||||
fi
|
||||
rm -f conftest.[cs]
|
||||
])
|
|
@ -247,7 +247,7 @@ def build_one_stage(cc, cxx, asm, ld, ar, ranlib, libtool,
|
|||
"-DCMAKE_OSX_ARCHITECTURES=x86_64",
|
||||
"-DDARWIN_osx_ARCHS=x86_64",
|
||||
"-DDARWIN_osx_SYSROOT=%s" % slashify_path(os.getenv("CROSS_SYSROOT")),
|
||||
"-DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-apple-darwin11"
|
||||
"-DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-darwin11"
|
||||
]
|
||||
return cmake_args
|
||||
|
||||
|
@ -704,7 +704,7 @@ if __name__ == "__main__":
|
|||
extra_cxxflags = ["-stdlib=libc++"]
|
||||
extra_cxxflags2 = ["-stdlib=libc++"]
|
||||
|
||||
extra_flags = ["-target", "x86_64-apple-darwin11", "-mlinker-version=137",
|
||||
extra_flags = ["-target", "x86_64-darwin11", "-mlinker-version=137",
|
||||
"-B", "%s/bin" % os.getenv("CROSS_CCTOOLS_PATH"),
|
||||
"-isysroot", os.getenv("CROSS_SYSROOT"),
|
||||
# technically the sysroot flag there should be enough to deduce this,
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
"cc": "/builds/worker/workspace/build/src/clang/bin/clang",
|
||||
"cxx": "/builds/worker/workspace/build/src/clang/bin/clang++",
|
||||
"as": "/builds/worker/workspace/build/src/clang/bin/clang",
|
||||
"ar": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin11-ar",
|
||||
"ranlib": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin11-ranlib",
|
||||
"libtool": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin11-libtool",
|
||||
"ar": "/builds/worker/workspace/build/src/cctools/bin/x86_64-darwin11-ar",
|
||||
"ranlib": "/builds/worker/workspace/build/src/cctools/bin/x86_64-darwin11-ranlib",
|
||||
"libtool": "/builds/worker/workspace/build/src/cctools/bin/x86_64-darwin11-libtool",
|
||||
"ld": "/builds/worker/workspace/build/src/clang/bin/clang",
|
||||
"patches": [
|
||||
"static-llvm-symbolizer.patch",
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
"cc": "/builds/worker/workspace/build/src/clang/bin/clang",
|
||||
"cxx": "/builds/worker/workspace/build/src/clang/bin/clang++",
|
||||
"as": "/builds/worker/workspace/build/src/clang/bin/clang",
|
||||
"ar": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin11-ar",
|
||||
"ranlib": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin11-ranlib",
|
||||
"libtool": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin11-libtool",
|
||||
"ar": "/builds/worker/workspace/build/src/cctools/bin/x86_64-darwin11-ar",
|
||||
"ranlib": "/builds/worker/workspace/build/src/cctools/bin/x86_64-darwin11-ranlib",
|
||||
"libtool": "/builds/worker/workspace/build/src/cctools/bin/x86_64-darwin11-libtool",
|
||||
"ld": "/builds/worker/workspace/build/src/clang/bin/clang",
|
||||
"patches": [
|
||||
]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Add `-target x86_64-apple-darwin11' to the compiler-rt overridden CFLAGS
|
||||
Add `-target x86_64-darwin11' to the compiler-rt overridden CFLAGS
|
||||
|
||||
diff --git a/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake
|
||||
index 28d398672..aac68bf36 100644
|
||||
|
@ -9,7 +9,7 @@ index 28d398672..aac68bf36 100644
|
|||
set(DARWIN_EXCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Darwin-excludes)
|
||||
|
||||
- set(CFLAGS "-fPIC -O3 -fvisibility=hidden -DVISIBILITY_HIDDEN -Wall -fomit-frame-pointer")
|
||||
+ set(CFLAGS "-fPIC -O3 -fvisibility=hidden -DVISIBILITY_HIDDEN -Wall -fomit-frame-pointer -target x86_64-apple-darwin11 -isysroot ${CMAKE_OSX_SYSROOT} -I${CMAKE_OSX_SYSROOT}/usr/include")
|
||||
+ set(CFLAGS "-fPIC -O3 -fvisibility=hidden -DVISIBILITY_HIDDEN -Wall -fomit-frame-pointer -target x86_64-darwin11 -isysroot ${CMAKE_OSX_SYSROOT} -I${CMAKE_OSX_SYSROOT}/usr/include")
|
||||
set(CMAKE_C_FLAGS "")
|
||||
set(CMAKE_CXX_FLAGS "")
|
||||
set(CMAKE_ASM_FLAGS "")
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if ! git remote -v | grep origin | grep -q cctools-port; then
|
||||
echo "must be in a cctools-port checkout"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir build-cctools
|
||||
cd build-cctools
|
||||
|
||||
CFLAGS='-mcpu=generic -mtune=generic' MACOSX_DEPLOYMENT_TARGET=10.7 ../cctools/configure --target=x86_64-apple-darwin11
|
||||
env MACOSX_DEPLOYMENT_TARGET=10.7 make -s -j4
|
||||
|
||||
if test ! -e ld64/src/ld/ld; then
|
||||
echo "ld did not get built"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gtar jcf cctools.tar.bz2 ld64/src/ld/ld --transform 's#ld64/src/ld#cctools/bin#'
|
||||
|
||||
cd ../
|
||||
|
||||
echo "build from $(git show --pretty=format:%H -s HEAD) complete!"
|
||||
echo "upload the build-cctools/cctools.tar.bz2 file to tooltool"
|
|
@ -6,13 +6,12 @@ MOZ_AUTOMATION_L10N_CHECK=0
|
|||
|
||||
. "$topsrcdir/build/mozconfig.common"
|
||||
|
||||
# Rust requires dsymutil into PATH
|
||||
mk_add_options "export PATH=$topsrcdir/llvm-dsymutil/bin:$PATH"
|
||||
# cctools for ld, ar, and other related tools ; dsymutil for rust.
|
||||
mk_add_options "export PATH=$topsrcdir/cctools/bin:$topsrcdir/llvm-dsymutil/bin:$PATH"
|
||||
|
||||
# ld needs libLTO.so from llvm
|
||||
mk_add_options "export LD_LIBRARY_PATH=$topsrcdir/clang/lib"
|
||||
|
||||
CROSS_CCTOOLS_PATH=$topsrcdir/cctools
|
||||
# This SDK was copied from a local XCode install and uploaded to tooltool.
|
||||
# Generate the tarball by running this command with the proper SDK version:
|
||||
# sdk_path=$(xcrun --sdk macosx10.12 --show-sdk-path)
|
||||
|
@ -21,29 +20,23 @@ CROSS_CCTOOLS_PATH=$topsrcdir/cctools
|
|||
# `browser/config/tooltool-manifests/macosx64/cross-releng.manifest`.
|
||||
CROSS_SYSROOT=$topsrcdir/MacOSX10.11.sdk
|
||||
CROSS_PRIVATE_FRAMEWORKS=$CROSS_SYSROOT/System/Library/PrivateFrameworks
|
||||
FLAGS="-target x86_64-apple-darwin11 -B $CROSS_CCTOOLS_PATH/bin -isysroot $CROSS_SYSROOT"
|
||||
|
||||
export CC="$topsrcdir/clang/bin/clang $FLAGS"
|
||||
export CXX="$topsrcdir/clang/bin/clang++ $FLAGS"
|
||||
export CPP="$topsrcdir/clang/bin/clang $FLAGS -E"
|
||||
export CC="$topsrcdir/clang/bin/clang"
|
||||
export CXX="$topsrcdir/clang/bin/clang++"
|
||||
export LLVMCONFIG=$topsrcdir/clang/bin/llvm-config
|
||||
export LDFLAGS="-Wl,-syslibroot,$CROSS_SYSROOT -Wl,-dead_strip"
|
||||
export BINDGEN_CFLAGS="$FLAGS"
|
||||
export TOOLCHAIN_PREFIX=$CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin11-
|
||||
export BINDGEN_CFLAGS="-isysroot $CROSS_SYSROOT"
|
||||
export DSYMUTIL=$topsrcdir/build/macosx/llvm-dsymutil
|
||||
mk_add_options "export REAL_DSYMUTIL=$topsrcdir/llvm-dsymutil/bin/dsymutil"
|
||||
export MKFSHFS=$topsrcdir/hfsplus-tools/newfs_hfs
|
||||
export DMG_TOOL=$topsrcdir/dmg/dmg
|
||||
export HFS_TOOL=$topsrcdir/dmg/hfsplus
|
||||
|
||||
export HOST_CC="$topsrcdir/clang/bin/clang"
|
||||
export HOST_CXX="$topsrcdir/clang/bin/clang++"
|
||||
export HOST_CPP="$topsrcdir/clang/bin/clang -E"
|
||||
export HOST_CFLAGS="-g"
|
||||
export HOST_CXXFLAGS="-g"
|
||||
export HOST_LDFLAGS="-g"
|
||||
|
||||
ac_add_options --target=x86_64-apple-darwin
|
||||
ac_add_options --target=x86_64-apple-darwin11
|
||||
ac_add_options --with-macos-sdk=$CROSS_SYSROOT
|
||||
ac_add_options --with-macos-private-frameworks=$CROSS_PRIVATE_FRAMEWORKS
|
||||
|
||||
if [ "x$MOZ_PKG_SPECIAL" != "xasan" -a -z "$MOZ_AUTOMATION_ARTIFACT_BUILDS" ]; then
|
||||
|
|
|
@ -240,8 +240,6 @@ def old_configure_options(*options):
|
|||
'--with-ios-sdk',
|
||||
'--with-jitreport-granularity',
|
||||
'--with-macbundlename-prefix',
|
||||
'--with-macos-private-frameworks',
|
||||
'--with-macos-sdk',
|
||||
'--with-nspr-cflags',
|
||||
'--with-nspr-exec-prefix',
|
||||
'--with-nspr-libs',
|
||||
|
|
|
@ -198,28 +198,65 @@ def compiling_android(compile_env, build_project):
|
|||
|
||||
include('android-ndk.configure', when=compiling_android)
|
||||
|
||||
# MacOS deployment target version
|
||||
# ==============================================================
|
||||
# This needs to happen before any compilation test is done.
|
||||
with only_when(target_is_osx):
|
||||
# MacOS deployment target version
|
||||
# ==============================================================
|
||||
# This needs to happen before any compilation test is done.
|
||||
|
||||
option('--enable-macos-target', env='MACOSX_DEPLOYMENT_TARGET', nargs=1,
|
||||
default='10.9', help='Set the minimum MacOS version needed at runtime')
|
||||
option('--enable-macos-target', env='MACOSX_DEPLOYMENT_TARGET', nargs=1,
|
||||
default='10.9', help='Set the minimum MacOS version needed at runtime')
|
||||
|
||||
|
||||
@depends('--enable-macos-target', target)
|
||||
@imports(_from='os', _import='environ')
|
||||
def macos_target(value, target):
|
||||
if value and target.os == 'OSX':
|
||||
# Ensure every compiler process we spawn uses this value.
|
||||
environ['MACOSX_DEPLOYMENT_TARGET'] = value[0]
|
||||
@depends('--enable-macos-target')
|
||||
@imports(_from='os', _import='environ')
|
||||
def macos_target(value):
|
||||
if value:
|
||||
# Ensure every compiler process we spawn uses this value.
|
||||
environ['MACOSX_DEPLOYMENT_TARGET'] = value[0]
|
||||
return value[0]
|
||||
|
||||
|
||||
set_config('MACOSX_DEPLOYMENT_TARGET', macos_target)
|
||||
add_old_configure_assignment('MACOSX_DEPLOYMENT_TARGET', macos_target)
|
||||
|
||||
# MacOS SDK
|
||||
# =========
|
||||
|
||||
option('--with-macos-sdk', nargs=1, help='Location of platform SDK to use')
|
||||
|
||||
@depends_if('--with-macos-sdk')
|
||||
@imports(_from='os.path', _import='isdir')
|
||||
def macos_sdk(value):
|
||||
if not isdir(value[0]):
|
||||
die('SDK not found in %s. When using --with-macos-sdk, you must specify a '
|
||||
'valid SDK. SDKs are installed when the optional cross-development '
|
||||
'tools are selected during the Xcode/Developer Tools installation.'
|
||||
% value[0])
|
||||
return value[0]
|
||||
if value and value.origin != 'default':
|
||||
die('--enable-macos-target cannot be used when targeting %s',
|
||||
target.os)
|
||||
|
||||
set_config('MACOS_SDK_DIR', macos_sdk)
|
||||
|
||||
with only_when(cross_compiling):
|
||||
option('--with-macos-private-frameworks', nargs=1,
|
||||
help='Location of private frameworks to use')
|
||||
|
||||
@depends_if('--with-macos-private-frameworks')
|
||||
@imports(_from='os.path', _import='isdir')
|
||||
def macos_private_frameworks(value):
|
||||
if value and not isdir(value[0]):
|
||||
die('PrivateFrameworks not found not found in %s. When using '
|
||||
'--with-macos-private-frameworks, you must specify a valid '
|
||||
'directory', value[0])
|
||||
return value[0]
|
||||
|
||||
@depends(macos_private_frameworks)
|
||||
def macos_private_frameworks(value):
|
||||
if value:
|
||||
return value
|
||||
return '/System/Library/PrivateFrameworks'
|
||||
|
||||
set_config('MACOS_PRIVATE_FRAMEWORKS_DIR', macos_private_frameworks)
|
||||
|
||||
set_config('MACOSX_DEPLOYMENT_TARGET', macos_target)
|
||||
add_old_configure_assignment('MACOSX_DEPLOYMENT_TARGET', macos_target)
|
||||
|
||||
# Xcode state
|
||||
# ===========
|
||||
|
@ -387,8 +424,8 @@ def toolchain_prefix(value, target, cross_compiling):
|
|||
def first_toolchain_prefix(toolchain_prefix, target):
|
||||
# Pass TOOLCHAIN_PREFIX down to the build system if it was given from the
|
||||
# command line/environment (in which case there's only one value in the tuple),
|
||||
# or when cross-compiling for Android.
|
||||
if toolchain_prefix and (target.os == 'Android' or len(toolchain_prefix) == 1):
|
||||
# or when cross-compiling for Android or OSX.
|
||||
if toolchain_prefix and (target.os in ('Android', 'OSX') or len(toolchain_prefix) == 1):
|
||||
return toolchain_prefix[0]
|
||||
|
||||
|
||||
|
@ -939,11 +976,11 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
|
|||
input=provided_compiler.program,
|
||||
paths=toolchain_search_path)
|
||||
|
||||
@depends(compiler, provided_compiler, compiler_wrapper, host_or_target)
|
||||
@depends(compiler, provided_compiler, compiler_wrapper, host_or_target, macos_sdk)
|
||||
@checking('whether %s can be used' % what, lambda x: bool(x))
|
||||
@imports(_from='mozbuild.shellutil', _import='quote')
|
||||
def valid_compiler(compiler, provided_compiler, compiler_wrapper,
|
||||
host_or_target):
|
||||
host_or_target, macos_sdk):
|
||||
wrapper = list(compiler_wrapper or ())
|
||||
if provided_compiler:
|
||||
provided_wrapper = list(provided_compiler.wrapper)
|
||||
|
@ -957,6 +994,9 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
|
|||
else:
|
||||
flags = []
|
||||
|
||||
if not flags and macos_sdk and host_or_target.os == 'OSX':
|
||||
flags = ['-isysroot', macos_sdk]
|
||||
|
||||
# Ideally, we'd always use the absolute path, but unfortunately, on
|
||||
# Windows, the compiler is very often in a directory containing spaces.
|
||||
# Unfortunately, due to the way autoconf does its compiler tests with
|
||||
|
@ -1851,9 +1891,22 @@ def select_linker(linker, c_compiler, developer_options, enable_gold,
|
|||
return result
|
||||
|
||||
|
||||
set_config('LD_IS_BFD', depends(select_linker.KIND)
|
||||
(lambda x: x == 'bfd' or None))
|
||||
add_old_configure_assignment('LINKER_LDFLAGS', select_linker.LINKER_FLAG)
|
||||
set_config('LINKER_KIND', select_linker.KIND)
|
||||
|
||||
|
||||
@depends_if(select_linker, macos_sdk)
|
||||
def linker_ldflags(linker, macos_sdk):
|
||||
flags = list(linker.LINKER_FLAG or [])
|
||||
if macos_sdk:
|
||||
if linker.KIND == 'ld64':
|
||||
flags.append('-Wl,-syslibroot,%s' % macos_sdk)
|
||||
else:
|
||||
flags.append('-Wl,--sysroot=%s' % macos_sdk)
|
||||
|
||||
return flags
|
||||
|
||||
|
||||
add_old_configure_assignment('LINKER_LDFLAGS', linker_ldflags)
|
||||
|
||||
|
||||
# There's a wrinkle with MinGW: linker configuration is not enabled, so
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
from buildconfig import substs
|
||||
from mozbuild.base import MozbuildObject
|
||||
|
@ -96,7 +97,12 @@ if __name__ == '__main__':
|
|||
cmdargs=['data:text/html,<script>Quitter.quit()</script>'],
|
||||
env=env)
|
||||
runner.start()
|
||||
runner.wait()
|
||||
ret = runner.wait()
|
||||
if ret:
|
||||
print("Firefox exited with code %d during profile initialization"
|
||||
% ret)
|
||||
httpd.stop()
|
||||
sys.exit(ret)
|
||||
|
||||
jarlog = os.getenv("JARLOG_FILE")
|
||||
if jarlog:
|
||||
|
@ -109,5 +115,8 @@ if __name__ == '__main__':
|
|||
cmdargs=cmdargs,
|
||||
env=env)
|
||||
runner.start(debug_args=debug_args, interactive=interactive)
|
||||
runner.wait()
|
||||
ret = runner.wait()
|
||||
httpd.stop()
|
||||
if ret:
|
||||
print("Firefox exited with code %d during profiling" % ret)
|
||||
sys.exit(ret)
|
||||
|
|
|
@ -88,10 +88,10 @@ add_task(async function() {
|
|||
await resume(dbg);
|
||||
await addExpression(dbg, "location");
|
||||
|
||||
is(findAllElements(dbg, "expressionNodes").length, 34);
|
||||
is(findAllElements(dbg, "expressionNodes").length, 1);
|
||||
|
||||
await toggleExpressionNode(dbg, 1);
|
||||
is(findAllElements(dbg, "expressionNodes").length, 1);
|
||||
is(findAllElements(dbg, "expressionNodes").length, 34);
|
||||
|
||||
await deleteExpression(dbg, "location");
|
||||
is(findAllElements(dbg, "expressionNodes").length, 0);
|
||||
|
|
|
@ -27,5 +27,5 @@ add_task(async function() {
|
|||
|
||||
await stepOver(dbg);
|
||||
is(getLabel(dbg, 4), "foo()");
|
||||
is(getLabel(dbg, 11), "Window");
|
||||
is(getLabel(dbg, 5), "Window");
|
||||
});
|
||||
|
|
|
@ -31,16 +31,26 @@ add_task(async function() {
|
|||
|
||||
info("Toggling ON the CSS grid highlighter from the layout panel.");
|
||||
const onHighlighterShown = highlighters.once("grid-highlighter-shown");
|
||||
const onCheckboxChange = waitUntilState(store, state =>
|
||||
let onCheckboxChange = waitUntilState(store, state =>
|
||||
state.grids.length == 1 &&
|
||||
state.grids[0].highlighted);
|
||||
checkbox.click();
|
||||
await onHighlighterShown;
|
||||
await onCheckboxChange;
|
||||
|
||||
info("Toggling OFF the CSS grid highlighter from the layout panel.");
|
||||
const onHighlighterHidden = highlighters.once("grid-highlighter-hidden");
|
||||
onCheckboxChange = waitUntilState(store, state =>
|
||||
state.grids.length == 1 &&
|
||||
!state.grids[0].highlighted);
|
||||
checkbox.click();
|
||||
await onHighlighterHidden;
|
||||
await onCheckboxChange;
|
||||
|
||||
checkResults();
|
||||
});
|
||||
|
||||
function checkResults() {
|
||||
checkTelemetry("devtools.grid.gridinspector.opened", "", 1, "scalar");
|
||||
checkTelemetry("DEVTOOLS_GRID_HIGHLIGHTER_TIME_ACTIVE_SECONDS", "", null, "hasentries");
|
||||
}
|
||||
|
|
|
@ -43,6 +43,11 @@ class HighlightersOverlay {
|
|||
// associated with any NodeFront.
|
||||
this.extraGridHighlighterPool = [];
|
||||
|
||||
// Boolean flag to keep track of whether or not the telemetry timer for the grid
|
||||
// highlighter active time is active. We keep track of this to avoid re-starting a
|
||||
// new timer when an additional grid highlighter is turned on.
|
||||
this.isGridHighlighterTimerActive = false;
|
||||
|
||||
// Collection of instantiated in-context editors, like ShapesInContextEditor, which
|
||||
// behave like highlighters but with added editing capabilities that need to map value
|
||||
// changes to properties in the Rule view.
|
||||
|
@ -518,6 +523,12 @@ class HighlightersOverlay {
|
|||
|
||||
this._toggleRuleViewIcon(node, true, ".ruleview-grid");
|
||||
|
||||
if (!this.isGridHighlighterTimerActive) {
|
||||
this.telemetry.toolOpened("grid_highlighter", this.inspector.toolbox.sessionId,
|
||||
this);
|
||||
this.isGridHighlighterTimerActive = true;
|
||||
}
|
||||
|
||||
if (trigger === "grid") {
|
||||
this.telemetry.scalarAdd("devtools.grid.gridinspector.opened", 1);
|
||||
} else if (trigger === "markup") {
|
||||
|
@ -562,6 +573,12 @@ class HighlightersOverlay {
|
|||
|
||||
this._toggleRuleViewIcon(node, false, ".ruleview-grid");
|
||||
|
||||
if (this.isGridHighlighterTimerActive && !this.gridHighlighters.size) {
|
||||
this.telemetry.toolClosed("grid_highlighter", this.inspector.toolbox.sessionId,
|
||||
this);
|
||||
this.isGridHighlighterTimerActive = false;
|
||||
}
|
||||
|
||||
// Emit the NodeFront of the grid container element that the grid highlighter was
|
||||
// hidden for.
|
||||
this.emit("grid-highlighter-hidden", node);
|
||||
|
|
|
@ -2512,6 +2512,13 @@ function reducer(state = initialState(), action = {}) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
// NOTE: we clear the state on resume because otherwise the scopes pane
|
||||
// would be out of date. Bug 1514760
|
||||
if (type === "RESUME" || type == "NAVIGATE") {
|
||||
return initialState();
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
|
|
@ -738,6 +738,7 @@ function getChartsFromToolId(id) {
|
|||
countHist = `DEVTOOLS_${id}_OPENED_COUNT`;
|
||||
break;
|
||||
case "FLEXBOX_HIGHLIGHTER":
|
||||
case "GRID_HIGHLIGHTER":
|
||||
timerHist = `DEVTOOLS_${id}_TIME_ACTIVE_SECONDS`;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -286,10 +286,3 @@
|
|||
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
-moz-appearance: scrollcorner;
|
||||
}
|
||||
|
||||
/* This scrollable element doesn't need to have its size influenced by its
|
||||
children, so we can give it "contain: layout size" to make it a containment
|
||||
boundary and to hint that it can be a reflow root. */
|
||||
.CodeMirror-scroll {
|
||||
contain: layout size;
|
||||
}
|
||||
|
|
|
@ -9,3 +9,10 @@ DevToolsModules(
|
|||
'graphics.js',
|
||||
'replay.js',
|
||||
)
|
||||
|
||||
XPIDL_MODULE = 'devtools_rr'
|
||||
|
||||
XPIDL_SOURCES = [
|
||||
'rrIGraphics.idl',
|
||||
'rrIReplay.idl',
|
||||
]
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(941b2e20-8558-4881-b5ad-dc3a1f2d9678)]
|
||||
interface rrIGraphics : nsISupports {
|
||||
void UpdateCanvas(in jsval buffer, in long width, in long height,
|
||||
in boolean hadFailure);
|
||||
};
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(8b86b71f-8471-472e-9997-c5f21f9d0598)]
|
||||
interface rrIReplay : nsISupports {
|
||||
jsval ProcessRequest(in jsval request);
|
||||
|
||||
void EnsurePositionHandler(in jsval position);
|
||||
|
||||
void ClearPositionHandlers();
|
||||
|
||||
void ClearPausedState();
|
||||
|
||||
jsval GetEntryPosition(in jsval position);
|
||||
};
|
|
@ -212,7 +212,7 @@ static bool IsNodeInEditableRegion(nsINode* aNode) {
|
|||
}
|
||||
|
||||
bool SVGAElement::IsSVGFocusable(bool* aIsFocusable, int32_t* aTabIndex) {
|
||||
if (nsSVGElement::IsSVGFocusable(aIsFocusable, aTabIndex)) {
|
||||
if (SVGGraphicsElement::IsSVGFocusable(aIsFocusable, aTabIndex)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,11 @@ class SVGDefsElement final : public SVGGraphicsElement {
|
|||
// nsIContent
|
||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
|
||||
// defs elements are not focusable.
|
||||
bool IsFocusableInternal(int32_t* aTabIndex, bool aWithMouse) override {
|
||||
return nsIContent::IsFocusableInternal(aTabIndex, aWithMouse);
|
||||
}
|
||||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
};
|
||||
|
||||
|
|
|
@ -28,5 +28,39 @@ SVGGraphicsElement::SVGGraphicsElement(
|
|||
|
||||
SVGGraphicsElement::~SVGGraphicsElement() {}
|
||||
|
||||
bool SVGGraphicsElement::IsSVGFocusable(bool* aIsFocusable,
|
||||
int32_t* aTabIndex) {
|
||||
nsIDocument* doc = GetComposedDoc();
|
||||
if (!doc || doc->HasFlag(NODE_IS_EDITABLE)) {
|
||||
// In designMode documents we only allow focusing the document.
|
||||
if (aTabIndex) {
|
||||
*aTabIndex = -1;
|
||||
}
|
||||
|
||||
*aIsFocusable = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t tabIndex = TabIndex();
|
||||
|
||||
if (aTabIndex) {
|
||||
*aTabIndex = tabIndex;
|
||||
}
|
||||
|
||||
// If a tabindex is specified at all, or the default tabindex is 0, we're
|
||||
// focusable
|
||||
*aIsFocusable = tabIndex >= 0 || HasAttr(nsGkAtoms::tabindex);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SVGGraphicsElement::IsFocusableInternal(int32_t* aTabIndex,
|
||||
bool aWithMouse) {
|
||||
bool isFocusable = false;
|
||||
IsSVGFocusable(&isFocusable, aTabIndex);
|
||||
return isFocusable;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -25,6 +25,8 @@ class SVGGraphicsElement : public SVGGraphicsElementBase, public SVGTests {
|
|||
// interfaces:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
virtual bool IsSVGFocusable(bool* aIsFocusable, int32_t* aTabIndex);
|
||||
bool IsFocusableInternal(int32_t* aTabIndex, bool aWithMouse) override;
|
||||
nsSVGElement* AsSVGElement() final { return this; }
|
||||
};
|
||||
|
||||
|
|
|
@ -1017,38 +1017,6 @@ already_AddRefed<SVGAnimatedString> nsSVGElement::ClassName() {
|
|||
return mClassAttribute.ToDOMAnimatedString(this);
|
||||
}
|
||||
|
||||
bool nsSVGElement::IsSVGFocusable(bool* aIsFocusable, int32_t* aTabIndex) {
|
||||
nsIDocument* doc = GetComposedDoc();
|
||||
if (!doc || doc->HasFlag(NODE_IS_EDITABLE)) {
|
||||
// In designMode documents we only allow focusing the document.
|
||||
if (aTabIndex) {
|
||||
*aTabIndex = -1;
|
||||
}
|
||||
|
||||
*aIsFocusable = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t tabIndex = TabIndex();
|
||||
|
||||
if (aTabIndex) {
|
||||
*aTabIndex = tabIndex;
|
||||
}
|
||||
|
||||
// If a tabindex is specified at all, or the default tabindex is 0, we're
|
||||
// focusable
|
||||
*aIsFocusable = tabIndex >= 0 || HasAttr(nsGkAtoms::tabindex);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nsSVGElement::IsFocusableInternal(int32_t* aTabIndex, bool aWithMouse) {
|
||||
bool isFocusable = false;
|
||||
IsSVGFocusable(&isFocusable, aTabIndex);
|
||||
return isFocusable;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Helper class: MappedAttrParser, for parsing values of mapped attributes
|
||||
|
||||
|
|
|
@ -304,10 +304,6 @@ class nsSVGElement : public nsSVGElementBase // nsIContent
|
|||
nsSVGElement* GetViewportElement();
|
||||
already_AddRefed<mozilla::dom::SVGAnimatedString> ClassName();
|
||||
|
||||
virtual bool IsSVGFocusable(bool* aIsFocusable, int32_t* aTabIndex);
|
||||
virtual bool IsFocusableInternal(int32_t* aTabIndex,
|
||||
bool aWithMouse) override;
|
||||
|
||||
void UpdateContentDeclarationBlock();
|
||||
const mozilla::DeclarationBlock* GetContentDeclarationBlock() const;
|
||||
|
||||
|
|
|
@ -8,6 +8,12 @@ EXPORTS.mozilla.dom += [
|
|||
'txMozillaXSLTProcessor.h'
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_xslt'
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'txIEXSLTFunctions.idl',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'txBufferingHandler.cpp',
|
||||
'txCurrentFunctionCall.cpp',
|
||||
|
|
|
@ -15,10 +15,12 @@
|
|||
#include "txExecutionState.h"
|
||||
#include "txExpr.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "txIEXSLTFunctions.h"
|
||||
#include "txNodeSet.h"
|
||||
#include "txOutputFormat.h"
|
||||
#include "txRtfHandler.h"
|
||||
#include "txXPathTreeWalker.h"
|
||||
#include "nsImportModule.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsContentCID.h"
|
||||
|
@ -662,60 +664,18 @@ nsresult txEXSLTRegExFunctionCall::evaluate(txIEvalContext* aContext,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
if (!jsapi.Init(xpc::PrivilegedJunkScope())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
xpc::SandboxOptions options;
|
||||
options.sandboxName.AssignLiteral("txEXSLTRegExFunctionCall sandbox");
|
||||
options.invisibleToDebugger = true;
|
||||
JS::RootedValue v(cx);
|
||||
rv = CreateSandboxObject(cx, &v, nsXPConnect::SystemPrincipal(), options);
|
||||
MOZ_ALWAYS_SUCCEEDS(rv);
|
||||
JS::RootedObject sandbox(cx, js::UncheckedUnwrap(&v.toObject()));
|
||||
|
||||
JSAutoRealm ar(cx, sandbox);
|
||||
ErrorResult er;
|
||||
GlobalObject global(cx, sandbox);
|
||||
Optional<JS::HandleObject> targetObj(cx, sandbox);
|
||||
JS::RootedObject obj(cx);
|
||||
ChromeUtils::Import(
|
||||
global,
|
||||
NS_LITERAL_STRING("resource://gre/modules/txEXSLTRegExFunctions.jsm"),
|
||||
targetObj, &obj, er);
|
||||
MOZ_ALWAYS_TRUE(!er.Failed());
|
||||
|
||||
JS::RootedString str(
|
||||
cx, JS_NewUCStringCopyZ(cx, PromiseFlatString(string).get()));
|
||||
JS::RootedString re(cx,
|
||||
JS_NewUCStringCopyZ(cx, PromiseFlatString(regex).get()));
|
||||
JS::RootedString fl(cx,
|
||||
JS_NewUCStringCopyZ(cx, PromiseFlatString(flags).get()));
|
||||
nsCOMPtr<txIEXSLTFunctions> funcs =
|
||||
do_ImportModule("resource://gre/modules/txEXSLTRegExFunctions.jsm");
|
||||
MOZ_ALWAYS_TRUE(funcs);
|
||||
|
||||
switch (mType) {
|
||||
case txEXSLTType::MATCH: {
|
||||
nsCOMPtr<nsIDocument> sourceDoc = getSourceDocument(aContext);
|
||||
NS_ENSURE_STATE(sourceDoc);
|
||||
|
||||
JS::RootedValue doc(cx);
|
||||
if (!GetOrCreateDOMReflector(cx, sourceDoc, &doc)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::AutoValueArray<4> args(cx);
|
||||
args[0].setString(str);
|
||||
args[1].setString(re);
|
||||
args[2].setString(fl);
|
||||
args[3].setObject(doc.toObject());
|
||||
|
||||
JS::RootedValue rval(cx);
|
||||
if (!JS_CallFunctionName(cx, sandbox, "match", args, &rval)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
RefPtr<DocumentFragment> docFrag;
|
||||
rv = UNWRAP_OBJECT(DocumentFragment, &rval, docFrag);
|
||||
rv = funcs->Match(string, regex, flags, sourceDoc,
|
||||
getter_AddRefs(docFrag));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_STATE(docFrag);
|
||||
|
||||
|
@ -740,23 +700,9 @@ nsresult txEXSLTRegExFunctionCall::evaluate(txIEvalContext* aContext,
|
|||
rv = mParams[3]->evaluateToString(aContext, replace);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JS::RootedString repl(
|
||||
cx, JS_NewUCStringCopyZ(cx, PromiseFlatString(replace).get()));
|
||||
|
||||
JS::AutoValueArray<4> args(cx);
|
||||
args[0].setString(str);
|
||||
args[1].setString(re);
|
||||
args[2].setString(fl);
|
||||
args[3].setString(repl);
|
||||
|
||||
JS::RootedValue rval(cx);
|
||||
if (!JS_CallFunctionName(cx, sandbox, "replace", args, &rval)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsString result;
|
||||
if (!ConvertJSValueToString(cx, rval, result)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsAutoString result;
|
||||
rv = funcs->Replace(string, regex, flags, replace, result);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aContext->recycler()->getStringResult(result, aResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -764,17 +710,9 @@ nsresult txEXSLTRegExFunctionCall::evaluate(txIEvalContext* aContext,
|
|||
return NS_OK;
|
||||
}
|
||||
case txEXSLTType::TEST: {
|
||||
JS::AutoValueArray<3> args(cx);
|
||||
args[0].setString(str);
|
||||
args[1].setString(re);
|
||||
args[2].setString(fl);
|
||||
|
||||
JS::RootedValue rval(cx);
|
||||
if (!JS_CallFunctionName(cx, sandbox, "test", args, &rval)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
bool result = rval.toBoolean();
|
||||
bool result;
|
||||
rv = funcs->Test(string, regex, flags, &result);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aContext->recycler()->getBoolResult(result, aResult);
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
webidl Document;
|
||||
webidl DocumentFragment;
|
||||
|
||||
[scriptable, uuid(21b1cfa4-00ce-4cc1-bfc1-92af1d00e580)]
|
||||
interface txIEXSLTFunctions : nsISupports {
|
||||
DocumentFragment match(in AString str, in AString regex,
|
||||
in AString flags, in Document doc);
|
||||
|
||||
AString replace(in AString str, in AString regex, in AString flags,
|
||||
in AString replace);
|
||||
|
||||
boolean test(in AString str, in AString regex, in AString flags);
|
||||
};
|
||||
|
|
@ -102,6 +102,11 @@ UniquePtr<GLScreenBuffer> GLScreenBuffer::Create(GLContext* gl,
|
|||
#endif
|
||||
} else if (useD3D) {
|
||||
#ifdef XP_WIN
|
||||
// Ensure devices initialization. SharedSurfaceANGLE and
|
||||
// SharedSurfaceD3D11Interop use them. The devices are lazily initialized
|
||||
// with WebRender to reduce memory usage.
|
||||
gfxPlatform::GetPlatform()->EnsureDevicesInitialized();
|
||||
|
||||
// Enable surface sharing only if ANGLE and compositing devices
|
||||
// are both WARP or both not WARP
|
||||
gfx::DeviceManagerDx* dm = gfx::DeviceManagerDx::Get();
|
||||
|
|
|
@ -1615,7 +1615,8 @@ bool SyncObjectD3D11Host::Synchronize(bool aFallible) {
|
|||
SyncObjectD3D11Client::SyncObjectD3D11Client(SyncHandle aSyncHandle,
|
||||
ID3D11Device* aDevice)
|
||||
: mSyncHandle(aSyncHandle), mSyncLock("SyncObjectD3D11") {
|
||||
if (!aDevice) {
|
||||
if (!aDevice && !XRE_IsGPUProcess() &&
|
||||
gfxPlatform::GetPlatform()->DevicesInitialized()) {
|
||||
mDevice = DeviceManagerDx::Get()->GetContentDevice();
|
||||
return;
|
||||
}
|
||||
|
@ -1664,7 +1665,17 @@ void SyncObjectD3D11Client::RegisterTexture(ID3D11Texture2D* aTexture) {
|
|||
}
|
||||
|
||||
bool SyncObjectD3D11Client::IsSyncObjectValid() {
|
||||
RefPtr<ID3D11Device> dev = DeviceManagerDx::Get()->GetContentDevice();
|
||||
RefPtr<ID3D11Device> dev;
|
||||
// There is a case that devices are not initialized yet with WebRender.
|
||||
if (gfxPlatform::GetPlatform()->DevicesInitialized()) {
|
||||
dev = DeviceManagerDx::Get()->GetContentDevice();
|
||||
}
|
||||
|
||||
// Update mDevice if the ContentDevice initialization is detected.
|
||||
if (!mDevice && dev && NS_IsMainThread() && gfxVars::UseWebRender()) {
|
||||
mDevice = dev;
|
||||
}
|
||||
|
||||
if (!dev || (NS_IsMainThread() && dev != mDevice)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -546,6 +546,11 @@ ipc::IShmemAllocator* WebRenderBridgeChild::GetShmemAllocator() {
|
|||
|
||||
RefPtr<KnowsCompositor> WebRenderBridgeChild::GetForMedia() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Ensure devices initialization for video playback. The devices are lazily
|
||||
// initialized with WebRender to reduce memory usage.
|
||||
gfxPlatform::GetPlatform()->EnsureDevicesInitialized();
|
||||
|
||||
return MakeAndAddRef<KnowsCompositorMediaProxy>(
|
||||
GetTextureFactoryIdentifier());
|
||||
}
|
||||
|
|
|
@ -665,6 +665,11 @@ void WebRenderLayerManager::SetRoot(Layer* aLayer) {
|
|||
already_AddRefed<PersistentBufferProvider>
|
||||
WebRenderLayerManager::CreatePersistentBufferProvider(
|
||||
const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat) {
|
||||
|
||||
// Ensure devices initialization for canvas 2d. The devices are lazily
|
||||
// initialized with WebRender to reduce memory usage.
|
||||
gfxPlatform::GetPlatform()->EnsureDevicesInitialized();
|
||||
|
||||
if (gfxPrefs::PersistentBufferProviderSharedEnabled()) {
|
||||
RefPtr<PersistentBufferProvider> provider =
|
||||
PersistentBufferProviderShared::Create(aSize, aFormat,
|
||||
|
|
|
@ -991,6 +991,9 @@ RefPtr<ID3D11Device> DeviceManagerDx::GetCompositorDevice() {
|
|||
}
|
||||
|
||||
RefPtr<ID3D11Device> DeviceManagerDx::GetContentDevice() {
|
||||
MOZ_ASSERT(XRE_IsGPUProcess() ||
|
||||
gfxPlatform::GetPlatform()->DevicesInitialized());
|
||||
|
||||
MutexAutoLock lock(mDeviceLock);
|
||||
return mContentDevice;
|
||||
}
|
||||
|
|
|
@ -913,6 +913,13 @@ void gfxPlatform::Init() {
|
|||
#endif
|
||||
gPlatform->InitAcceleration();
|
||||
gPlatform->InitWebRenderConfig();
|
||||
// When using WebRender, we defer initialization of the D3D11 devices until
|
||||
// the (rare) cases where they're used. Note that the GPU process where WebRender
|
||||
// runs doesn't initialize gfxPlatform and performs explicit initialization of
|
||||
// the bits it needs.
|
||||
if (!gfxVars::UseWebRender()) {
|
||||
gPlatform->EnsureDevicesInitialized();
|
||||
}
|
||||
gPlatform->InitOMTPConfig();
|
||||
|
||||
if (gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
|
||||
|
|
|
@ -752,6 +752,9 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
|
|||
virtual void OnMemoryPressure(
|
||||
mozilla::layers::MemoryPressureReason aWhy) override;
|
||||
|
||||
virtual void EnsureDevicesInitialized() {};
|
||||
virtual bool DevicesInitialized() { return true; };
|
||||
|
||||
protected:
|
||||
gfxPlatform();
|
||||
virtual ~gfxPlatform();
|
||||
|
|
|
@ -424,7 +424,6 @@ void gfxWindowsPlatform::InitAcceleration() {
|
|||
DeviceManagerDx::Init();
|
||||
|
||||
InitializeConfig();
|
||||
InitializeDevices();
|
||||
UpdateANGLEConfig();
|
||||
UpdateRenderMode();
|
||||
|
||||
|
@ -497,7 +496,9 @@ bool gfxWindowsPlatform::HandleDeviceReset() {
|
|||
gfxConfig::Reset(Feature::DIRECT2D);
|
||||
|
||||
InitializeConfig();
|
||||
InitializeDevices();
|
||||
if (mInitializedDevices) {
|
||||
InitializeDevices();
|
||||
}
|
||||
UpdateANGLEConfig();
|
||||
return true;
|
||||
}
|
||||
|
@ -1470,7 +1471,25 @@ void gfxWindowsPlatform::InitializeD3D11Config() {
|
|||
uint32_t(aDevice));
|
||||
}
|
||||
|
||||
// Supports lazy device initialization on Windows, so that WebRender can avoid
|
||||
// initializing GPU state and allocating swap chains for most non-GPU processes.
|
||||
void gfxWindowsPlatform::EnsureDevicesInitialized() {
|
||||
if (!mInitializedDevices) {
|
||||
mInitializedDevices = true;
|
||||
InitializeDevices();
|
||||
UpdateBackendPrefs();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
gfxWindowsPlatform::DevicesInitialized() {
|
||||
|
||||
return mInitializedDevices;
|
||||
}
|
||||
|
||||
void gfxWindowsPlatform::InitializeDevices() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
// If we're the UI process, and the GPU process is enabled, then we don't
|
||||
// initialize any DirectX devices. We do leave them enabled in gfxConfig
|
||||
|
@ -2032,6 +2051,10 @@ void gfxWindowsPlatform::BuildContentDeviceData(ContentDeviceData* aOut) {
|
|||
}
|
||||
|
||||
bool gfxWindowsPlatform::SupportsPluginDirectDXGIDrawing() {
|
||||
// Ensure devices initialization for plugin's DXGISurface. The devices are
|
||||
// lazily initialized with WebRender to reduce memory usage.
|
||||
EnsureDevicesInitialized();
|
||||
|
||||
DeviceManagerDx* dm = DeviceManagerDx::Get();
|
||||
if (!dm->GetContentDevice() || !dm->TextureSharingWorks()) {
|
||||
return false;
|
||||
|
|
|
@ -105,6 +105,9 @@ class gfxWindowsPlatform : public gfxPlatform {
|
|||
return (gfxWindowsPlatform*)gfxPlatform::GetPlatform();
|
||||
}
|
||||
|
||||
virtual void EnsureDevicesInitialized() override;
|
||||
virtual bool DevicesInitialized() override;
|
||||
|
||||
virtual gfxPlatformFontList* CreatePlatformFontList() override;
|
||||
|
||||
virtual already_AddRefed<gfxASurface> CreateOffscreenSurface(
|
||||
|
@ -259,6 +262,7 @@ class gfxWindowsPlatform : public gfxPlatform {
|
|||
DWRITE_MEASURING_MODE mMeasuringMode;
|
||||
|
||||
RefPtr<mozilla::layers::ReadbackManagerD3D11> mD3D11ReadbackManager;
|
||||
bool mInitializedDevices = false;
|
||||
};
|
||||
|
||||
#endif /* GFX_WINDOWS_PLATFORM_H */
|
||||
|
|
|
@ -265,6 +265,24 @@ typedef enum JSGCParamKey {
|
|||
* Pref: None
|
||||
*/
|
||||
JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION = 27,
|
||||
|
||||
/**
|
||||
* If this percentage of the nursery is tenured, then proceed to examine which
|
||||
* groups we should pretenure.
|
||||
*
|
||||
* Default: PretenureThreshold
|
||||
* Pref: None
|
||||
*/
|
||||
JSGC_PRETENURE_THRESHOLD = 28,
|
||||
|
||||
/**
|
||||
* If the above condition is met, then any object group that tenures more than
|
||||
* this number of objects will be pretenured (if it can be).
|
||||
*
|
||||
* Default: PretenureGroupThreshold
|
||||
* Pref: None
|
||||
*/
|
||||
JSGC_PRETENURE_GROUP_THRESHOLD = 29,
|
||||
} JSGCParamKey;
|
||||
|
||||
/*
|
||||
|
|
|
@ -15,7 +15,6 @@ builtin(include, ../../build/autoconf/codeset.m4)dnl
|
|||
builtin(include, ../../build/autoconf/altoptions.m4)dnl
|
||||
builtin(include, ../../build/autoconf/mozprog.m4)dnl
|
||||
builtin(include, ../../build/autoconf/mozheader.m4)dnl
|
||||
builtin(include, ../../build/autoconf/lto.m4)dnl
|
||||
builtin(include, ../../build/autoconf/frameptr.m4)dnl
|
||||
builtin(include, ../../build/autoconf/compiler-opts.m4)dnl
|
||||
builtin(include, ../../build/autoconf/expandlibs.m4)dnl
|
||||
|
|
|
@ -348,6 +348,12 @@ static const bool CompactingEnabled = true;
|
|||
static const uint32_t NurseryFreeThresholdForIdleCollection =
|
||||
Nursery::NurseryChunkUsableSize / 4;
|
||||
|
||||
/* JSGC_PRETENURE_THRESHOLD */
|
||||
static const float PretenureThreashold = 0.6f;
|
||||
|
||||
/* JSGC_PRETENURE_GROUP_THRESHOLD */
|
||||
static const float PretenureGroupThreshold = 3000;
|
||||
|
||||
} // namespace TuningDefaults
|
||||
} // namespace gc
|
||||
} // namespace js
|
||||
|
@ -1260,6 +1266,17 @@ bool GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes) {
|
|||
if (!nursery().init(maxNurseryBytes, lock)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* pretenureThresholdStr = getenv("JSGC_PRETENURE_THRESHOLD");
|
||||
if (pretenureThresholdStr && pretenureThresholdStr[0]) {
|
||||
char* last;
|
||||
long pretenureThreshold = strtol(pretenureThresholdStr, &last, 10);
|
||||
if (last[0] || !tunables.setParameter(JSGC_PRETENURE_THRESHOLD,
|
||||
pretenureThreshold, lock)) {
|
||||
fprintf(stderr, "Invalid value for JSGC_PRETENURE_THRESHOLD: %s\n",
|
||||
pretenureThresholdStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
|
@ -1464,6 +1481,20 @@ bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value,
|
|||
}
|
||||
nurseryFreeThresholdForIdleCollection_ = value;
|
||||
break;
|
||||
case JSGC_PRETENURE_THRESHOLD: {
|
||||
// 100 disables pretenuring
|
||||
if (value == 0 || value > 100) {
|
||||
return false;
|
||||
}
|
||||
pretenureThreshold_ = value / 100.0f;
|
||||
break;
|
||||
}
|
||||
case JSGC_PRETENURE_GROUP_THRESHOLD:
|
||||
if (value <= 0) {
|
||||
return false;
|
||||
}
|
||||
pretenureGroupThreshold_ = value;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unknown GC parameter.");
|
||||
}
|
||||
|
@ -1551,7 +1582,9 @@ GCSchedulingTunables::GCSchedulingTunables()
|
|||
minEmptyChunkCount_(TuningDefaults::MinEmptyChunkCount),
|
||||
maxEmptyChunkCount_(TuningDefaults::MaxEmptyChunkCount),
|
||||
nurseryFreeThresholdForIdleCollection_(
|
||||
TuningDefaults::NurseryFreeThresholdForIdleCollection) {}
|
||||
TuningDefaults::NurseryFreeThresholdForIdleCollection),
|
||||
pretenureThreshold_(TuningDefaults::PretenureThreashold),
|
||||
pretenureGroupThreshold_(TuningDefaults::PretenureGroupThreshold) {}
|
||||
|
||||
void GCRuntime::resetParameter(JSGCParamKey key, AutoLockGC& lock) {
|
||||
switch (key) {
|
||||
|
@ -1633,6 +1666,12 @@ void GCSchedulingTunables::resetParameter(JSGCParamKey key,
|
|||
nurseryFreeThresholdForIdleCollection_ =
|
||||
TuningDefaults::NurseryFreeThresholdForIdleCollection;
|
||||
break;
|
||||
case JSGC_PRETENURE_THRESHOLD:
|
||||
pretenureThreshold_ = TuningDefaults::PretenureThreashold;
|
||||
break;
|
||||
case JSGC_PRETENURE_GROUP_THRESHOLD:
|
||||
pretenureGroupThreshold_ = TuningDefaults::PretenureGroupThreshold;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unknown GC parameter.");
|
||||
}
|
||||
|
@ -1691,6 +1730,10 @@ uint32_t GCRuntime::getParameter(JSGCParamKey key, const AutoLockGC& lock) {
|
|||
return tunables.maxEmptyChunkCount();
|
||||
case JSGC_COMPACTING_ENABLED:
|
||||
return compactingEnabled;
|
||||
case JSGC_PRETENURE_THRESHOLD:
|
||||
return uint32_t(tunables.pretenureThreshold() * 100);
|
||||
case JSGC_PRETENURE_GROUP_THRESHOLD:
|
||||
return tunables.pretenureGroupThreshold();
|
||||
default:
|
||||
MOZ_ASSERT(key == JSGC_NUMBER);
|
||||
return uint32_t(number);
|
||||
|
|
|
@ -175,7 +175,7 @@ struct MovingTracer : JS::CallbackTracer {
|
|||
// been tenured during a minor collection.
|
||||
struct TenureCount {
|
||||
ObjectGroup* group;
|
||||
int count;
|
||||
unsigned count;
|
||||
|
||||
// ObjectGroups are never nursery-allocated, and TenureCounts are only used
|
||||
// in minor GC (not compacting GC), so prevent the analysis from
|
||||
|
|
|
@ -694,7 +694,7 @@ inline void js::Nursery::endProfile(ProfileKey key) {
|
|||
|
||||
bool js::Nursery::needIdleTimeCollection() const {
|
||||
uint32_t threshold =
|
||||
runtime()->gc.tunables.nurseryFreeThresholdForIdleCollection();
|
||||
tunables().nurseryFreeThresholdForIdleCollection();
|
||||
return minorGCRequested() || freeSpace() < threshold;
|
||||
}
|
||||
|
||||
|
@ -768,13 +768,15 @@ void js::Nursery::collect(JS::gcreason::Reason reason) {
|
|||
bool validPromotionRate;
|
||||
const float promotionRate = calcPromotionRate(&validPromotionRate);
|
||||
uint32_t pretenureCount = 0;
|
||||
bool shouldPretenure = (validPromotionRate && promotionRate > 0.6) ||
|
||||
IsFullStoreBufferReason(reason);
|
||||
bool shouldPretenure = tunables().attemptPretenuring() &&
|
||||
((validPromotionRate &&
|
||||
promotionRate > tunables().pretenureThreshold()) ||
|
||||
IsFullStoreBufferReason(reason));
|
||||
|
||||
if (shouldPretenure) {
|
||||
JSContext* cx = rt->mainContextFromOwnThread();
|
||||
for (auto& entry : tenureCounts.entries) {
|
||||
if (entry.count >= 3000) {
|
||||
if (entry.count >= tunables().pretenureGroupThreshold()) {
|
||||
ObjectGroup* group = entry.group;
|
||||
AutoRealm ar(cx, group);
|
||||
AutoSweepObjectGroup sweep(group);
|
||||
|
@ -822,7 +824,7 @@ void js::Nursery::collect(JS::gcreason::Reason reason) {
|
|||
// We ignore gcMaxBytes when allocating for minor collection. However, if we
|
||||
// overflowed, we disable the nursery. The next time we allocate, we'll fail
|
||||
// because gcBytes >= gcMaxBytes.
|
||||
if (rt->gc.usage.gcBytes() >= rt->gc.tunables.gcMaxBytes()) {
|
||||
if (rt->gc.usage.gcBytes() >= tunables().gcMaxBytes()) {
|
||||
disable();
|
||||
}
|
||||
// Disable the nursery if the user changed the configuration setting. The
|
||||
|
@ -1178,8 +1180,7 @@ void js::Nursery::maybeResizeNursery(JS::gcreason::Reason reason) {
|
|||
}
|
||||
#endif
|
||||
|
||||
newMaxNurseryChunks =
|
||||
runtime()->gc.tunables.gcMaxNurseryBytes() >> ChunkShift;
|
||||
newMaxNurseryChunks = tunables().gcMaxNurseryBytes() >> ChunkShift;
|
||||
if (newMaxNurseryChunks != chunkCountLimit_) {
|
||||
chunkCountLimit_ = newMaxNurseryChunks;
|
||||
/* The configured maximum nursery size is changing */
|
||||
|
@ -1260,6 +1261,10 @@ gcstats::Statistics& js::Nursery::stats() const {
|
|||
return runtime()->gc.stats();
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE const js::gc::GCSchedulingTunables& js::Nursery::tunables() const {
|
||||
return runtime()->gc.tunables;
|
||||
}
|
||||
|
||||
void js::Nursery::sweepDictionaryModeObjects() {
|
||||
for (auto obj : dictionaryModeObjects_) {
|
||||
if (!IsForwarded(obj)) {
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace gc {
|
|||
class AutoMaybeStartBackgroundAllocation;
|
||||
class AutoTraceSession;
|
||||
struct Cell;
|
||||
class GCSchedulingTunables;
|
||||
class MinorCollectionTracer;
|
||||
class RelocationOverlay;
|
||||
struct TenureCountCache;
|
||||
|
@ -548,6 +549,8 @@ class Nursery {
|
|||
JSRuntime* runtime() const { return runtime_; }
|
||||
gcstats::Statistics& stats() const;
|
||||
|
||||
const js::gc::GCSchedulingTunables& tunables() const;
|
||||
|
||||
/* Common internal allocator function. */
|
||||
void* allocate(size_t size);
|
||||
|
||||
|
|
|
@ -433,6 +433,24 @@ class GCSchedulingTunables {
|
|||
*/
|
||||
UnprotectedData<uint32_t> nurseryFreeThresholdForIdleCollection_;
|
||||
|
||||
/*
|
||||
* JSGC_PRETENURE_THRESHOLD
|
||||
*
|
||||
* Fraction of objects tenured to trigger pretenuring (between 0 and 1). If
|
||||
* this fraction is met, the GC proceeds to calculate which objects will be
|
||||
* tenured. If this is 1.0f (actually if it is not < 1.0f) then pretenuring
|
||||
* is disabled.
|
||||
*/
|
||||
UnprotectedData<float> pretenureThreshold_;
|
||||
|
||||
/*
|
||||
* JSGC_PRETENURE_GROUP_THRESHOLD
|
||||
*
|
||||
* During a single nursery collection, if this many objects from the same
|
||||
* object group are tenured, then that group will be pretenured.
|
||||
*/
|
||||
UnprotectedData<uint32_t> pretenureGroupThreshold_;
|
||||
|
||||
public:
|
||||
GCSchedulingTunables();
|
||||
|
||||
|
@ -471,6 +489,10 @@ class GCSchedulingTunables {
|
|||
return nurseryFreeThresholdForIdleCollection_;
|
||||
}
|
||||
|
||||
bool attemptPretenuring() const { return pretenureThreshold_ < 1.0f; }
|
||||
float pretenureThreshold() const { return pretenureThreshold_; }
|
||||
uint32_t pretenureGroupThreshold() const { return pretenureGroupThreshold_; }
|
||||
|
||||
MOZ_MUST_USE bool setParameter(JSGCParamKey key, uint32_t value,
|
||||
const AutoLockGC& lock);
|
||||
void resetParameter(JSGCParamKey key, const AutoLockGC& lock);
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// |jit-test| exitstatus: 6; skip-if: !wasmIsSupported()
|
||||
|
||||
const {Module, Instance} = WebAssembly;
|
||||
|
||||
const {innerWasm} = new Instance(new Module(wasmTextToBinary(`(module
|
||||
(func (export "innerWasm") (result i32)
|
||||
(local i32)
|
||||
(loop $top
|
||||
(set_local 0 (i32.add (get_local 0) (i32.const 1)))
|
||||
(br_if $top (i32.lt_u (get_local 0) (i32.const 100000)))
|
||||
)
|
||||
(get_local 0)
|
||||
)
|
||||
)`))).exports;
|
||||
|
||||
function middleJS() {
|
||||
innerWasm();
|
||||
}
|
||||
|
||||
const {outerWasm} = new Instance(new Module(wasmTextToBinary(`(module
|
||||
(func $middleJS (import "" "middleJS"))
|
||||
(func (export "outerWasm") (call $middleJS))
|
||||
)`)), {'':{middleJS}}).exports;
|
||||
|
||||
timeout(1);
|
||||
while (true) {
|
||||
outerWasm();
|
||||
}
|
|
@ -310,50 +310,6 @@ dnl Checks for programs.
|
|||
dnl ========================================================
|
||||
if test "$COMPILE_ENVIRONMENT"; then
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Mac OS X SDK support
|
||||
dnl ========================================================
|
||||
MACOS_SDK_DIR=
|
||||
MOZ_ARG_WITH_STRING(macos-sdk,
|
||||
[ --with-macos-sdk=dir Location of platform SDK to use (Mac OS X only)],
|
||||
MACOS_SDK_DIR=$withval)
|
||||
|
||||
dnl MACOS_SDK_DIR will be set to the SDK location whenever one is in use.
|
||||
AC_SUBST(MACOS_SDK_DIR)
|
||||
|
||||
if test "$MACOS_SDK_DIR"; then
|
||||
dnl Sync this section with the ones in NSPR and NSS.
|
||||
dnl Changes to the cross environment here need to be accounted for in
|
||||
dnl the libIDL checks (below) and xpidl build.
|
||||
|
||||
if test ! -d "$MACOS_SDK_DIR"; then
|
||||
AC_MSG_ERROR([SDK not found. When using --with-macos-sdk, you must
|
||||
specify a valid SDK. SDKs are installed when the optional cross-development
|
||||
tools are selected during the Xcode/Developer Tools installation.])
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS -isysroot ${MACOS_SDK_DIR}"
|
||||
CXXFLAGS="$CXXFLAGS -isysroot ${MACOS_SDK_DIR}"
|
||||
|
||||
dnl CPP/CXXCPP needs to be set for MOZ_CHECK_HEADER.
|
||||
CPP="$CPP -isysroot ${MACOS_SDK_DIR}"
|
||||
CXXCPP="$CXXCPP -isysroot ${MACOS_SDK_DIR}"
|
||||
|
||||
AC_LANG_SAVE
|
||||
AC_MSG_CHECKING([for valid compiler/Mac OS X SDK combination])
|
||||
AC_LANG_CPLUSPLUS
|
||||
AC_TRY_COMPILE([#include <new>
|
||||
int main() { return 0; }],
|
||||
result=yes,
|
||||
result=no)
|
||||
AC_LANG_RESTORE
|
||||
AC_MSG_RESULT($result)
|
||||
|
||||
if test "$result" = "no" ; then
|
||||
AC_MSG_ERROR([The selected compiler and Mac OS X SDK are incompatible.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_PATH_XTRA
|
||||
|
||||
XCFLAGS="$X_CFLAGS"
|
||||
|
@ -556,8 +512,6 @@ case "$host" in
|
|||
;;
|
||||
esac
|
||||
|
||||
MOZ_DOING_LTO(lto_is_enabled)
|
||||
|
||||
dnl ========================================================
|
||||
dnl Add optional and non-optional hardening flags from toolchain.configure
|
||||
dnl ========================================================
|
||||
|
@ -593,11 +547,9 @@ case "$target" in
|
|||
fi
|
||||
LDFLAGS=$_SAVE_LDFLAGS
|
||||
|
||||
if test "x$lto_is_enabled" = "xyes"; then
|
||||
echo "Skipping -dead_strip because lto is enabled."
|
||||
dnl DTrace and -dead_strip don't interact well. See bug 403132.
|
||||
dnl ===================================================================
|
||||
elif test "x$enable_dtrace" = "xyes"; then
|
||||
if test "x$enable_dtrace" = "xyes"; then
|
||||
echo "Skipping -dead_strip because DTrace is enabled. See bug 403132."
|
||||
else
|
||||
dnl check for the presence of the -dead_strip linker flag
|
||||
|
|
|
@ -48,9 +48,11 @@ WasmFrameIter::WasmFrameIter(JitActivation* activation, wasm::Frame* fp)
|
|||
|
||||
// When the stack is captured during a trap (viz., to create the .stack
|
||||
// for an Error object), use the pc/bytecode information captured by the
|
||||
// signal handler in the runtime.
|
||||
// signal handler in the runtime. Take care not to use this trap unwind
|
||||
// state for wasm frames in the middle of a JitActivation, i.e., wasm frames
|
||||
// that called into JIT frames before the trap.
|
||||
|
||||
if (activation->isWasmTrapping()) {
|
||||
if (activation->isWasmTrapping() && fp_ == activation->wasmExitFP()) {
|
||||
const TrapData& trapData = activation->wasmTrapData();
|
||||
void* unwoundPC = trapData.unwoundPC;
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ UNIFIED_SOURCES += [
|
|||
'ChromeScriptLoader.cpp',
|
||||
'mozJSLoaderUtils.cpp',
|
||||
'mozJSSubScriptLoader.cpp',
|
||||
'nsImportModule.cpp',
|
||||
'ScriptCacheActors.cpp',
|
||||
'ScriptPreloader.cpp',
|
||||
'URLPreloader.cpp',
|
||||
|
@ -17,13 +18,17 @@ UNIFIED_SOURCES += [
|
|||
# mozJSComponentLoader.cpp cannot be built in unified mode because it uses
|
||||
# windows.h
|
||||
SOURCES += [
|
||||
'mozJSComponentLoader.cpp'
|
||||
'mozJSComponentLoader.cpp',
|
||||
]
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'PScriptCache.ipdl',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'nsImportModule.h'
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'AutoMemMap.h',
|
||||
'ScriptPreloader.h',
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* -*- 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 http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsImportModule.h"
|
||||
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozJSComponentLoader.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "xpcprivate.h"
|
||||
|
||||
using mozilla::dom::AutoJSAPI;
|
||||
|
||||
namespace mozilla {
|
||||
namespace loader {
|
||||
|
||||
nsresult ImportModule(const char* aURI, const nsIID& aIID, void** aResult) {
|
||||
AutoJSAPI jsapi;
|
||||
MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope()));
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
JS::RootedObject global(cx);
|
||||
JS::RootedObject exports(cx);
|
||||
MOZ_TRY(mozJSComponentLoader::Get()->Import(cx, nsDependentCString(aURI),
|
||||
&global, &exports));
|
||||
|
||||
return nsXPConnect::XPConnect()->WrapJS(cx, exports, aIID, aResult);
|
||||
}
|
||||
|
||||
} // namespace loader
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- 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 http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsImportModule_h
|
||||
#define nsImportModule_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace loader {
|
||||
|
||||
nsresult ImportModule(const char* aURI, const nsIID& aIID, void** aResult);
|
||||
|
||||
} // namespace loader
|
||||
} // namespace mozilla
|
||||
|
||||
class MOZ_STACK_CLASS nsImportModule final : public nsCOMPtr_helper {
|
||||
public:
|
||||
nsImportModule(const char* aURI, nsresult* aErrorPtr)
|
||||
: mURI(aURI), mErrorPtr(aErrorPtr) {}
|
||||
|
||||
virtual nsresult NS_FASTCALL operator()(const nsIID& aIID,
|
||||
void** aResult) const override {
|
||||
nsresult rv = ::mozilla::loader::ImportModule(mURI, aIID, aResult);
|
||||
if (mErrorPtr) {
|
||||
*mErrorPtr = rv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* mURI;
|
||||
nsresult* mErrorPtr;
|
||||
};
|
||||
|
||||
/**
|
||||
* These helpers make it considerably easier for C++ code to import a JS module
|
||||
* and wrap it in an appropriately-defined XPIDL interface for its exports.
|
||||
* Typical usage is something like:
|
||||
*
|
||||
* Foo.jsm:
|
||||
*
|
||||
* var EXPORTED_SYMBOLS = ["foo"];
|
||||
*
|
||||
* function foo(bar) {
|
||||
* return bar.toString();
|
||||
* }
|
||||
*
|
||||
* mozIFoo.idl:
|
||||
*
|
||||
* interface mozIFoo : nsISupports {
|
||||
* AString foo(double meh);
|
||||
* }
|
||||
*
|
||||
* Thing.cpp:
|
||||
*
|
||||
* nsCOMPtr<mozIFoo> foo = do_ImportModule(
|
||||
* "resource://meh/Foo.jsm");
|
||||
*
|
||||
* MOZ_TRY(foo->Foo(42));
|
||||
*/
|
||||
|
||||
inline nsImportModule do_ImportModule(const char* aURI) {
|
||||
return {aURI, nullptr};
|
||||
}
|
||||
|
||||
inline nsImportModule do_ImportModule(const char* aURI, nsresult* aRv) {
|
||||
return {aURI, aRv};
|
||||
}
|
||||
|
||||
#endif // defined nsImportModule_h
|
|
@ -36,8 +36,7 @@ if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']:
|
|||
for f in SOURCES:
|
||||
if f.endswith('neon.c'):
|
||||
SOURCES[f].flags += CONFIG['NEON_FLAGS']
|
||||
elif CONFIG['CPU_ARCH'] == 'aarch64' and CONFIG['OS_ARCH'] != 'WINNT':
|
||||
# Bug 1504017 tracks re-enabling this for Windows.
|
||||
elif CONFIG['CPU_ARCH'] == 'aarch64' and CONFIG['CC_TYPE'] != 'msvc':
|
||||
SOURCES += [
|
||||
'alpha_processing_neon.c',
|
||||
'dec_neon.c',
|
||||
|
|
|
@ -264,7 +264,6 @@
|
|||
; [Extensions]
|
||||
@BINPATH@/components/extensions-toolkit.manifest
|
||||
@BINPATH@/components/extensions-mobile.manifest
|
||||
@BINPATH@/components/extension-process-script.js
|
||||
|
||||
; Features
|
||||
@BINPATH@/features/*
|
||||
|
|
|
@ -30,12 +30,10 @@
|
|||
* @param NSSConfigDir The config dir containing the private key to use
|
||||
* @return 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
int
|
||||
NSSInitCryptoContext(const char *NSSConfigDir)
|
||||
{
|
||||
SECStatus status = NSS_Initialize(NSSConfigDir,
|
||||
"", "", SECMOD_DB, NSS_INIT_READONLY);
|
||||
*/
|
||||
int NSSInitCryptoContext(const char *NSSConfigDir) {
|
||||
SECStatus status =
|
||||
NSS_Initialize(NSSConfigDir, "", "", SECMOD_DB, NSS_INIT_READONLY);
|
||||
if (SECSuccess != status) {
|
||||
fprintf(stderr, "ERROR: Could not initialize NSS\n");
|
||||
return -1;
|
||||
|
@ -50,15 +48,11 @@ NSSInitCryptoContext(const char *NSSConfigDir)
|
|||
* @param ctx A pointer to the signing context to fill
|
||||
* @return 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
int
|
||||
NSSSignBegin(const char *certName,
|
||||
SGNContext **ctx,
|
||||
SECKEYPrivateKey **privKey,
|
||||
CERTCertificate **cert,
|
||||
uint32_t *signatureLength)
|
||||
{
|
||||
secuPWData pwdata = { PW_NONE, 0 };
|
||||
*/
|
||||
int NSSSignBegin(const char *certName, SGNContext **ctx,
|
||||
SECKEYPrivateKey **privKey, CERTCertificate **cert,
|
||||
uint32_t *signatureLength) {
|
||||
secuPWData pwdata = {PW_NONE, 0};
|
||||
if (!certName || !ctx || !privKey || !cert || !signatureLength) {
|
||||
fprintf(stderr, "ERROR: Invalid parameter passed to NSSSignBegin\n");
|
||||
return -1;
|
||||
|
@ -122,13 +116,10 @@ NSSSignBegin(const char *certName,
|
|||
* @return 0 on success
|
||||
* -2 on write error
|
||||
* -3 on signature update error
|
||||
*/
|
||||
int
|
||||
WriteAndUpdateSignatures(FILE *fpDest, void *buffer,
|
||||
uint32_t size, SGNContext **ctxs,
|
||||
uint32_t ctxCount,
|
||||
const char *err)
|
||||
{
|
||||
*/
|
||||
int WriteAndUpdateSignatures(FILE *fpDest, void *buffer, uint32_t size,
|
||||
SGNContext **ctxs, uint32_t ctxCount,
|
||||
const char *err) {
|
||||
uint32_t k;
|
||||
if (!size) {
|
||||
return 0;
|
||||
|
@ -141,7 +132,8 @@ WriteAndUpdateSignatures(FILE *fpDest, void *buffer,
|
|||
|
||||
for (k = 0; k < ctxCount; ++k) {
|
||||
if (SGN_Update(ctxs[k], buffer, size) != SECSuccess) {
|
||||
fprintf(stderr, "ERROR: Could not update signature context for %s\n", err);
|
||||
fprintf(stderr, "ERROR: Could not update signature context for %s\n",
|
||||
err);
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
@ -155,10 +147,9 @@ WriteAndUpdateSignatures(FILE *fpDest, void *buffer,
|
|||
* @param indexBuf A buffer containing the MAR index
|
||||
* @param indexLength The length of the MAR index
|
||||
* @param offsetAmount The amount to adjust each index entry by
|
||||
*/
|
||||
void
|
||||
AdjustIndexContentOffsets(char *indexBuf, uint32_t indexLength, uint32_t offsetAmount)
|
||||
{
|
||||
*/
|
||||
void AdjustIndexContentOffsets(char *indexBuf, uint32_t indexLength,
|
||||
uint32_t offsetAmount) {
|
||||
uint32_t *offsetToContent;
|
||||
char *indexBufLoc = indexBuf;
|
||||
|
||||
|
@ -190,13 +181,10 @@ AdjustIndexContentOffsets(char *indexBuf, uint32_t indexLength, uint32_t offsetA
|
|||
* -1 on read error
|
||||
* -2 on write error
|
||||
* -3 on signature update error
|
||||
*/
|
||||
int
|
||||
ReadWriteAndUpdateSignatures(FILE *fpSrc, FILE *fpDest, void *buffer,
|
||||
uint32_t size, SGNContext **ctxs,
|
||||
uint32_t ctxCount,
|
||||
const char *err)
|
||||
{
|
||||
*/
|
||||
int ReadWriteAndUpdateSignatures(FILE *fpSrc, FILE *fpDest, void *buffer,
|
||||
uint32_t size, SGNContext **ctxs,
|
||||
uint32_t ctxCount, const char *err) {
|
||||
if (!size) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -209,7 +197,6 @@ ReadWriteAndUpdateSignatures(FILE *fpSrc, FILE *fpDest, void *buffer,
|
|||
return WriteAndUpdateSignatures(fpDest, buffer, size, ctxs, ctxCount, err);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads from fpSrc, writes it to fpDest.
|
||||
*
|
||||
|
@ -221,11 +208,9 @@ ReadWriteAndUpdateSignatures(FILE *fpSrc, FILE *fpDest, void *buffer,
|
|||
* @return 0 on success
|
||||
* -1 on read error
|
||||
* -2 on write error
|
||||
*/
|
||||
int
|
||||
ReadAndWrite(FILE *fpSrc, FILE *fpDest, void *buffer,
|
||||
uint32_t size, const char *err)
|
||||
{
|
||||
*/
|
||||
int ReadAndWrite(FILE *fpSrc, FILE *fpDest, void *buffer, uint32_t size,
|
||||
const char *err) {
|
||||
if (!size) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -252,14 +237,12 @@ ReadAndWrite(FILE *fpSrc, FILE *fpDest, void *buffer,
|
|||
* @return 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
int
|
||||
strip_signature_block(const char *src, const char * dest)
|
||||
{
|
||||
uint32_t offsetToIndex, dstOffsetToIndex, indexLength,
|
||||
numSignatures = 0, leftOver;
|
||||
int strip_signature_block(const char *src, const char *dest) {
|
||||
uint32_t offsetToIndex, dstOffsetToIndex, indexLength, numSignatures = 0,
|
||||
leftOver;
|
||||
int32_t stripAmount = 0;
|
||||
int64_t oldPos, sizeOfEntireMAR = 0, realSizeOfSrcMAR, numBytesToCopy,
|
||||
numChunks, i;
|
||||
int64_t oldPos, numChunks, i, realSizeOfSrcMAR, numBytesToCopy,
|
||||
sizeOfEntireMAR = 0;
|
||||
FILE *fpSrc = NULL, *fpDest = NULL;
|
||||
int rv = -1, hasSignatureBlock;
|
||||
char buf[BLOCKSIZE];
|
||||
|
@ -314,8 +297,7 @@ strip_signature_block(const char *src, const char * dest)
|
|||
|
||||
if (hasSignatureBlock) {
|
||||
/* Get the MAR length and adjust its size */
|
||||
if (fread(&sizeOfEntireMAR,
|
||||
sizeof(sizeOfEntireMAR), 1, fpSrc) != 1) {
|
||||
if (fread(&sizeOfEntireMAR, sizeof(sizeOfEntireMAR), 1, fpSrc) != 1) {
|
||||
fprintf(stderr, "ERROR: Could read mar size\n");
|
||||
goto failure;
|
||||
}
|
||||
|
@ -419,14 +401,13 @@ strip_signature_block(const char *src, const char * dest)
|
|||
}
|
||||
|
||||
/* Write out the left over */
|
||||
if (ReadAndWrite(fpSrc, fpDest, buf,
|
||||
leftOver, "left over content block")) {
|
||||
if (ReadAndWrite(fpSrc, fpDest, buf, leftOver, "left over content block")) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Length of the index */
|
||||
if (ReadAndWrite(fpSrc, fpDest, &indexLength,
|
||||
sizeof(indexLength), "index length")) {
|
||||
if (ReadAndWrite(fpSrc, fpDest, &indexLength, sizeof(indexLength),
|
||||
"index length")) {
|
||||
goto failure;
|
||||
}
|
||||
indexLength = ntohl(indexLength);
|
||||
|
@ -442,10 +423,9 @@ strip_signature_block(const char *src, const char * dest)
|
|||
if (hasSignatureBlock) {
|
||||
AdjustIndexContentOffsets(indexBuf, indexLength, -stripAmount);
|
||||
} else {
|
||||
AdjustIndexContentOffsets(indexBuf, indexLength,
|
||||
sizeof(sizeOfEntireMAR) +
|
||||
sizeof(numSignatures) -
|
||||
stripAmount);
|
||||
AdjustIndexContentOffsets(
|
||||
indexBuf, indexLength,
|
||||
sizeof(sizeOfEntireMAR) + sizeof(numSignatures) - stripAmount);
|
||||
}
|
||||
|
||||
if (fwrite(indexBuf, indexLength, 1, fpDest) != 1) {
|
||||
|
@ -485,10 +465,8 @@ failure:
|
|||
* @param dest The path of file to write the signature to
|
||||
* @return 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
int
|
||||
extract_signature(const char *src, uint32_t sigIndex, const char * dest)
|
||||
{
|
||||
*/
|
||||
int extract_signature(const char *src, uint32_t sigIndex, const char *dest) {
|
||||
FILE *fpSrc = NULL, *fpDest = NULL;
|
||||
uint32_t i;
|
||||
uint32_t signatureCount;
|
||||
|
@ -599,21 +577,20 @@ failure:
|
|||
* @param src The path of the source MAR file
|
||||
* @param sigIndex The index of the signature to import
|
||||
* @param base64SigFile A file which contains the signature to import
|
||||
* @param dest The path of the destination MAR file with replaced signature
|
||||
* @param dest The path of the destination MAR file with replaced
|
||||
* signature
|
||||
* @return 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
int
|
||||
import_signature(const char *src, uint32_t sigIndex,
|
||||
const char *base64SigFile, const char *dest)
|
||||
{
|
||||
*/
|
||||
int import_signature(const char *src, uint32_t sigIndex,
|
||||
const char *base64SigFile, const char *dest) {
|
||||
int rv = -1;
|
||||
FILE *fpSrc = NULL;
|
||||
FILE *fpDest = NULL;
|
||||
FILE *fpSigFile = NULL;
|
||||
uint32_t i;
|
||||
uint32_t signatureCount, signatureLen, signatureAlgorithmID,
|
||||
numChunks, leftOver;
|
||||
uint32_t signatureCount, signatureLen, signatureAlgorithmID, numChunks,
|
||||
leftOver;
|
||||
char buf[BLOCKSIZE];
|
||||
uint64_t sizeOfSrcMAR, sizeOfBase64EncodedFile;
|
||||
char *passedInSignatureB64 = NULL;
|
||||
|
@ -638,7 +615,7 @@ import_signature(const char *src, uint32_t sigIndex,
|
|||
goto failure;
|
||||
}
|
||||
|
||||
fpSigFile = fopen(base64SigFile , "rb");
|
||||
fpSigFile = fopen(base64SigFile, "rb");
|
||||
if (!fpSigFile) {
|
||||
fprintf(stderr, "ERROR: could not open sig file: %s\n", base64SigFile);
|
||||
goto failure;
|
||||
|
@ -660,7 +637,7 @@ import_signature(const char *src, uint32_t sigIndex,
|
|||
fprintf(stderr, "ERROR: Could not seek to end of sig file.\n");
|
||||
goto failure;
|
||||
}
|
||||
sizeOfBase64EncodedFile= ftello(fpSigFile);
|
||||
sizeOfBase64EncodedFile = ftello(fpSigFile);
|
||||
if (fseeko(fpSigFile, 0, SEEK_SET)) {
|
||||
fprintf(stderr, "ERROR: Could not seek to start of sig file.\n");
|
||||
goto failure;
|
||||
|
@ -675,21 +652,22 @@ import_signature(const char *src, uint32_t sigIndex,
|
|||
}
|
||||
|
||||
/* Decode the base64 encoded data */
|
||||
passedInSignatureRaw = ATOB_AsciiToData(passedInSignatureB64, &passedInSignatureLenRaw);
|
||||
passedInSignatureRaw =
|
||||
ATOB_AsciiToData(passedInSignatureB64, &passedInSignatureLenRaw);
|
||||
if (!passedInSignatureRaw) {
|
||||
fprintf(stderr, "ERROR: could not obtain base64 decoded data\n");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Read everything up until the signature block offset and write it out */
|
||||
if (ReadAndWrite(fpSrc, fpDest, buf,
|
||||
SIGNATURE_BLOCK_OFFSET, "signature block offset")) {
|
||||
if (ReadAndWrite(fpSrc, fpDest, buf, SIGNATURE_BLOCK_OFFSET,
|
||||
"signature block offset")) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Get the number of signatures */
|
||||
if (ReadAndWrite(fpSrc, fpDest, &signatureCount,
|
||||
sizeof(signatureCount), "signature count")) {
|
||||
if (ReadAndWrite(fpSrc, fpDest, &signatureCount, sizeof(signatureCount),
|
||||
"signature count")) {
|
||||
goto failure;
|
||||
}
|
||||
signatureCount = ntohl(signatureCount);
|
||||
|
@ -708,15 +686,14 @@ import_signature(const char *src, uint32_t sigIndex,
|
|||
base64 decoded signature */
|
||||
for (i = 0; i < signatureCount; i++) {
|
||||
/* Read/Write the signature algorithm ID */
|
||||
if (ReadAndWrite(fpSrc, fpDest,
|
||||
&signatureAlgorithmID,
|
||||
if (ReadAndWrite(fpSrc, fpDest, &signatureAlgorithmID,
|
||||
sizeof(signatureAlgorithmID), "sig algorithm ID")) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Read/Write the signature length */
|
||||
if (ReadAndWrite(fpSrc, fpDest,
|
||||
&signatureLen, sizeof(signatureLen), "sig length")) {
|
||||
if (ReadAndWrite(fpSrc, fpDest, &signatureLen, sizeof(signatureLen),
|
||||
"sig length")) {
|
||||
goto failure;
|
||||
}
|
||||
signatureLen = ntohl(signatureLen);
|
||||
|
@ -738,14 +715,14 @@ import_signature(const char *src, uint32_t sigIndex,
|
|||
goto failure;
|
||||
}
|
||||
|
||||
if (fwrite(passedInSignatureRaw, passedInSignatureLenRaw,
|
||||
1, fpDest) != 1) {
|
||||
if (fwrite(passedInSignatureRaw, passedInSignatureLenRaw, 1, fpDest) !=
|
||||
1) {
|
||||
fprintf(stderr, "ERROR: Could not write signature\n");
|
||||
goto failure;
|
||||
}
|
||||
} else {
|
||||
if (ReadAndWrite(fpSrc, fpDest,
|
||||
extractedMARSignature, signatureLen, "signature")) {
|
||||
if (ReadAndWrite(fpSrc, fpDest, extractedMARSignature, signatureLen,
|
||||
"signature")) {
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
@ -807,7 +784,8 @@ failure:
|
|||
* The passed in MAR file must not already be signed or an error will
|
||||
* be returned.
|
||||
*
|
||||
* @param NSSConfigDir The NSS directory containing the private key for signing
|
||||
* @param NSSConfigDir The NSS directory containing the private key for
|
||||
* signing
|
||||
* @param certNames The nicknames of the certificate to use for signing
|
||||
* @param certCount The number of certificate names contained in certNames.
|
||||
* One signature will be produced for each certificate.
|
||||
|
@ -815,21 +793,15 @@ failure:
|
|||
* @param dest The path of the MAR file to write out that is signed
|
||||
* @return 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
int
|
||||
mar_repackage_and_sign(const char *NSSConfigDir,
|
||||
const char * const *certNames,
|
||||
uint32_t certCount,
|
||||
const char *src,
|
||||
const char *dest)
|
||||
{
|
||||
uint32_t offsetToIndex, dstOffsetToIndex, indexLength,
|
||||
numSignatures = 0, leftOver,
|
||||
signatureAlgorithmID, signatureSectionLength = 0;
|
||||
*/
|
||||
int mar_repackage_and_sign(const char *NSSConfigDir,
|
||||
const char *const *certNames, uint32_t certCount,
|
||||
const char *src, const char *dest) {
|
||||
uint32_t offsetToIndex, dstOffsetToIndex, indexLength, leftOver,
|
||||
signatureAlgorithmID, numSignatures = 0, signatureSectionLength = 0;
|
||||
uint32_t signatureLengths[MAX_SIGNATURES];
|
||||
int64_t oldPos, sizeOfEntireMAR = 0, realSizeOfSrcMAR,
|
||||
signaturePlaceholderOffset, numBytesToCopy,
|
||||
numChunks, i;
|
||||
int64_t oldPos, numChunks, i, realSizeOfSrcMAR, signaturePlaceholderOffset,
|
||||
numBytesToCopy, sizeOfEntireMAR = 0;
|
||||
FILE *fpSrc = NULL, *fpDest = NULL;
|
||||
int rv = -1, hasSignatureBlock;
|
||||
SGNContext *ctxs[MAX_SIGNATURES];
|
||||
|
@ -877,17 +849,16 @@ mar_repackage_and_sign(const char *NSSConfigDir,
|
|||
}
|
||||
|
||||
for (k = 0; k < certCount; k++) {
|
||||
if (NSSSignBegin(certNames[k], &ctxs[k], &privKeys[k],
|
||||
&certs[k], &signatureLengths[k])) {
|
||||
if (NSSSignBegin(certNames[k], &ctxs[k], &privKeys[k], &certs[k],
|
||||
&signatureLengths[k])) {
|
||||
fprintf(stderr, "ERROR: NSSSignBegin failed\n");
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
/* MAR ID */
|
||||
if (ReadWriteAndUpdateSignatures(fpSrc, fpDest,
|
||||
buf, MAR_ID_SIZE,
|
||||
ctxs, certCount, "MAR ID")) {
|
||||
if (ReadWriteAndUpdateSignatures(fpSrc, fpDest, buf, MAR_ID_SIZE, ctxs,
|
||||
certCount, "MAR ID")) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
|
@ -912,8 +883,7 @@ mar_repackage_and_sign(const char *NSSConfigDir,
|
|||
|
||||
if (hasSignatureBlock) {
|
||||
/* Get the MAR length and adjust its size */
|
||||
if (fread(&sizeOfEntireMAR,
|
||||
sizeof(sizeOfEntireMAR), 1, fpSrc) != 1) {
|
||||
if (fread(&sizeOfEntireMAR, sizeof(sizeOfEntireMAR), 1, fpSrc) != 1) {
|
||||
fprintf(stderr, "ERROR: Could read mar size\n");
|
||||
goto failure;
|
||||
}
|
||||
|
@ -948,8 +918,7 @@ mar_repackage_and_sign(const char *NSSConfigDir,
|
|||
/* Calculate the total signature block length */
|
||||
for (k = 0; k < certCount; k++) {
|
||||
signatureSectionLength += sizeof(signatureAlgorithmID) +
|
||||
sizeof(signatureLengths[k]) +
|
||||
signatureLengths[k];
|
||||
sizeof(signatureLengths[k]) + signatureLengths[k];
|
||||
}
|
||||
dstOffsetToIndex = offsetToIndex;
|
||||
if (!hasSignatureBlock) {
|
||||
|
@ -984,9 +953,8 @@ mar_repackage_and_sign(const char *NSSConfigDir,
|
|||
/* Write out the number of signatures */
|
||||
numSignatures = certCount;
|
||||
numSignatures = htonl(numSignatures);
|
||||
if (WriteAndUpdateSignatures(fpDest, &numSignatures,
|
||||
sizeof(numSignatures), ctxs, certCount,
|
||||
"num signatures")) {
|
||||
if (WriteAndUpdateSignatures(fpDest, &numSignatures, sizeof(numSignatures),
|
||||
ctxs, certCount, "num signatures")) {
|
||||
goto failure;
|
||||
}
|
||||
numSignatures = ntohl(numSignatures);
|
||||
|
@ -997,8 +965,8 @@ mar_repackage_and_sign(const char *NSSConfigDir,
|
|||
/* Write out the signature algorithm ID, Only an ID of 2 is supported */
|
||||
signatureAlgorithmID = htonl(2);
|
||||
if (WriteAndUpdateSignatures(fpDest, &signatureAlgorithmID,
|
||||
sizeof(signatureAlgorithmID),
|
||||
ctxs, certCount, "num signatures")) {
|
||||
sizeof(signatureAlgorithmID), ctxs, certCount,
|
||||
"num signatures")) {
|
||||
goto failure;
|
||||
}
|
||||
signatureAlgorithmID = ntohl(signatureAlgorithmID);
|
||||
|
@ -1006,8 +974,8 @@ mar_repackage_and_sign(const char *NSSConfigDir,
|
|||
/* Write out the signature length */
|
||||
signatureLengths[k] = htonl(signatureLengths[k]);
|
||||
if (WriteAndUpdateSignatures(fpDest, &signatureLengths[k],
|
||||
sizeof(signatureLengths[k]),
|
||||
ctxs, certCount, "signature length")) {
|
||||
sizeof(signatureLengths[k]), ctxs, certCount,
|
||||
"signature length")) {
|
||||
goto failure;
|
||||
}
|
||||
signatureLengths[k] = ntohl(signatureLengths[k]);
|
||||
|
@ -1035,17 +1003,15 @@ mar_repackage_and_sign(const char *NSSConfigDir,
|
|||
|
||||
/* Read each file and write it to the MAR file */
|
||||
for (i = 0; i < numChunks; ++i) {
|
||||
if (ReadWriteAndUpdateSignatures(fpSrc, fpDest, buf,
|
||||
BLOCKSIZE, ctxs, certCount,
|
||||
"content block")) {
|
||||
if (ReadWriteAndUpdateSignatures(fpSrc, fpDest, buf, BLOCKSIZE, ctxs,
|
||||
certCount, "content block")) {
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write out the left over */
|
||||
if (ReadWriteAndUpdateSignatures(fpSrc, fpDest, buf,
|
||||
leftOver, ctxs, certCount,
|
||||
"left over content block")) {
|
||||
if (ReadWriteAndUpdateSignatures(fpSrc, fpDest, buf, leftOver, ctxs,
|
||||
certCount, "left over content block")) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
|
@ -1069,13 +1035,12 @@ mar_repackage_and_sign(const char *NSSConfigDir,
|
|||
AdjustIndexContentOffsets(indexBuf, indexLength, signatureSectionLength);
|
||||
} else {
|
||||
AdjustIndexContentOffsets(indexBuf, indexLength,
|
||||
sizeof(sizeOfEntireMAR) +
|
||||
sizeof(numSignatures) +
|
||||
signatureSectionLength);
|
||||
sizeof(sizeOfEntireMAR) + sizeof(numSignatures) +
|
||||
signatureSectionLength);
|
||||
}
|
||||
|
||||
if (WriteAndUpdateSignatures(fpDest, indexBuf,
|
||||
indexLength, ctxs, certCount, "index")) {
|
||||
if (WriteAndUpdateSignatures(fpDest, indexBuf, indexLength, ctxs, certCount,
|
||||
"index")) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
|
@ -1105,14 +1070,15 @@ mar_repackage_and_sign(const char *NSSConfigDir,
|
|||
|
||||
for (k = 0; k < certCount; k++) {
|
||||
/* Skip to the position of the next signature */
|
||||
if (fseeko(fpDest, sizeof(signatureAlgorithmID) +
|
||||
sizeof(signatureLengths[k]), SEEK_CUR)) {
|
||||
if (fseeko(fpDest,
|
||||
sizeof(signatureAlgorithmID) + sizeof(signatureLengths[k]),
|
||||
SEEK_CUR)) {
|
||||
fprintf(stderr, "ERROR: Could not seek to signature offset\n");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Write out the calculated signature.
|
||||
*** THIS IS NOT SIGNED because it is the signature itself. *** */
|
||||
*** THIS IS NOT SIGNED because it is the signature itself. *** */
|
||||
if (fwrite(secItems[k].data, secItems[k].len, 1, fpDest) != 1) {
|
||||
fprintf(stderr, "ERROR: Could not write signature\n");
|
||||
goto failure;
|
||||
|
|
|
@ -19,7 +19,7 @@ extern "C" {
|
|||
* It is also used at various places internally and will affect memory usage.
|
||||
* If you want to increase this value above 9 then you need to adjust parsing
|
||||
* code in tool/mar.c.
|
||||
*/
|
||||
*/
|
||||
#define MAX_SIGNATURES 8
|
||||
#ifdef __cplusplus
|
||||
static_assert(MAX_SIGNATURES <= 9, "too many signatures");
|
||||
|
@ -27,8 +27,7 @@ static_assert(MAX_SIGNATURES <= 9, "too many signatures");
|
|||
MOZ_STATIC_ASSERT(MAX_SIGNATURES <= 9, "too many signatures");
|
||||
#endif
|
||||
|
||||
struct ProductInformationBlock
|
||||
{
|
||||
struct ProductInformationBlock {
|
||||
const char* MARChannelID;
|
||||
const char* productVersion;
|
||||
};
|
||||
|
@ -36,20 +35,18 @@ struct ProductInformationBlock
|
|||
/**
|
||||
* The MAR item data structure.
|
||||
*/
|
||||
typedef struct MarItem_
|
||||
{
|
||||
struct MarItem_* next; /* private field */
|
||||
uint32_t offset; /* offset into archive */
|
||||
uint32_t length; /* length of data in bytes */
|
||||
uint32_t flags; /* contains file mode bits */
|
||||
char name[1]; /* file path */
|
||||
typedef struct MarItem_ {
|
||||
struct MarItem_* next; /* private field */
|
||||
uint32_t offset; /* offset into archive */
|
||||
uint32_t length; /* length of data in bytes */
|
||||
uint32_t flags; /* contains file mode bits */
|
||||
char name[1]; /* file path */
|
||||
} MarItem;
|
||||
|
||||
/**
|
||||
* File offset and length for tracking access of byte indexes
|
||||
*/
|
||||
typedef struct SeenIndex_
|
||||
{
|
||||
typedef struct SeenIndex_ {
|
||||
struct SeenIndex_* next; /* private field */
|
||||
uint32_t offset; /* offset into archive */
|
||||
uint32_t length; /* length of the data in bytes */
|
||||
|
@ -60,8 +57,7 @@ typedef struct SeenIndex_
|
|||
/**
|
||||
* Mozilla ARchive (MAR) file data structure
|
||||
*/
|
||||
struct MarFile_
|
||||
{
|
||||
struct MarFile_ {
|
||||
FILE* fp; /* file pointer to the archive */
|
||||
MarItem* item_table[TABLESIZE]; /* hash table of files in the archive */
|
||||
SeenIndex* index_list; /* file indexes processed */
|
||||
|
@ -85,19 +81,17 @@ typedef int (*MarItemCallback)(MarFile* mar, const MarItem* item, void* data);
|
|||
* be compatible with fopen.
|
||||
* @return NULL if an error occurs.
|
||||
*/
|
||||
MarFile*
|
||||
mar_open(const char* path);
|
||||
MarFile* mar_open(const char* path);
|
||||
|
||||
#ifdef XP_WIN
|
||||
MarFile *mar_wopen(const wchar_t *path);
|
||||
MarFile* mar_wopen(const wchar_t* path);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Close a MAR file that was opened using mar_open.
|
||||
* @param mar The MarFile object to close.
|
||||
*/
|
||||
void
|
||||
mar_close(MarFile* mar);
|
||||
void mar_close(MarFile* mar);
|
||||
|
||||
/**
|
||||
* Find an item in the MAR file by name.
|
||||
|
@ -105,8 +99,7 @@ mar_close(MarFile* mar);
|
|||
* @param item The name of the item to query.
|
||||
* @return A const reference to a MAR item or NULL if not found.
|
||||
*/
|
||||
const MarItem*
|
||||
mar_find_item(MarFile* mar, const char* item);
|
||||
const MarItem* mar_find_item(MarFile* mar, const char* item);
|
||||
|
||||
/**
|
||||
* Enumerate all MAR items via callback function.
|
||||
|
@ -117,8 +110,7 @@ mar_find_item(MarFile* mar, const char* item);
|
|||
* @return 0 if the enumeration ran to completion. Otherwise, any
|
||||
* non-zero return value from the callback is returned.
|
||||
*/
|
||||
int
|
||||
mar_enum_items(MarFile* mar, MarItemCallback callback, void* data);
|
||||
int mar_enum_items(MarFile* mar, MarItemCallback callback, void* data);
|
||||
|
||||
/**
|
||||
* Read from MAR item at given offset up to bufsize bytes.
|
||||
|
@ -130,12 +122,8 @@ mar_enum_items(MarFile* mar, MarItemCallback callback, void* data);
|
|||
* @return The number of bytes written or a negative value if an
|
||||
* error occurs.
|
||||
*/
|
||||
int
|
||||
mar_read(MarFile* mar,
|
||||
const MarItem* item,
|
||||
int offset,
|
||||
uint8_t* buf,
|
||||
int bufsize);
|
||||
int mar_read(MarFile* mar, const MarItem* item, int offset, uint8_t* buf,
|
||||
int bufsize);
|
||||
|
||||
/**
|
||||
* Create a MAR file from a set of files.
|
||||
|
@ -147,11 +135,8 @@ mar_read(MarFile* mar,
|
|||
* @param infoBlock The information to store in the product information block.
|
||||
* @return A non-zero value if an error occurs.
|
||||
*/
|
||||
int
|
||||
mar_create(const char* dest,
|
||||
int numfiles,
|
||||
char** files,
|
||||
struct ProductInformationBlock* infoBlock);
|
||||
int mar_create(const char* dest, int numfiles, char** files,
|
||||
struct ProductInformationBlock* infoBlock);
|
||||
|
||||
/**
|
||||
* Extract a MAR file to the current working directory.
|
||||
|
@ -159,10 +144,9 @@ mar_create(const char* dest,
|
|||
* compatible with fopen.
|
||||
* @return A non-zero value if an error occurs.
|
||||
*/
|
||||
int
|
||||
mar_extract(const char* path);
|
||||
int mar_extract(const char* path);
|
||||
|
||||
#define MAR_MAX_CERT_SIZE (16*1024) // Way larger than necessary
|
||||
#define MAR_MAX_CERT_SIZE (16 * 1024) // Way larger than necessary
|
||||
|
||||
/* Read the entire file (not a MAR file) into a newly-allocated buffer.
|
||||
* This function does not write to stderr. Instead, the caller should
|
||||
|
@ -177,11 +161,9 @@ mar_extract(const char* path);
|
|||
*
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
mar_read_entire_file(const char* filePath,
|
||||
uint32_t maxSize,
|
||||
/*out*/ const uint8_t** data,
|
||||
/*out*/ uint32_t* size);
|
||||
int mar_read_entire_file(const char* filePath, uint32_t maxSize,
|
||||
/*out*/ const uint8_t** data,
|
||||
/*out*/ uint32_t* size);
|
||||
|
||||
/**
|
||||
* Verifies a MAR file by verifying each signature with the corresponding
|
||||
|
@ -203,11 +185,8 @@ mar_read_entire_file(const char* filePath,
|
|||
* a negative number if there was an error
|
||||
* a positive number if the signature does not verify
|
||||
*/
|
||||
int
|
||||
mar_verify_signatures(MarFile* mar,
|
||||
const uint8_t* const* certData,
|
||||
const uint32_t* certDataSizes,
|
||||
uint32_t certCount);
|
||||
int mar_verify_signatures(MarFile* mar, const uint8_t* const* certData,
|
||||
const uint32_t* certDataSizes, uint32_t certCount);
|
||||
|
||||
/**
|
||||
* Reads the product info block from the MAR file's additional block section.
|
||||
|
@ -216,13 +195,12 @@ mar_verify_signatures(MarFile* mar,
|
|||
*
|
||||
* @param infoBlock Out parameter for where to store the result to
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
mar_read_product_info_block(MarFile* mar,
|
||||
struct ProductInformationBlock* infoBlock);
|
||||
*/
|
||||
int mar_read_product_info_block(MarFile* mar,
|
||||
struct ProductInformationBlock* infoBlock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MAR_H__ */
|
||||
#endif /* MAR_H__ */
|
||||
|
|
|
@ -31,10 +31,8 @@ struct ProductInformationBlock;
|
|||
* has_additional_blocks is not equal to 0.
|
||||
* @return 0 on success and non-zero on failure.
|
||||
*/
|
||||
int get_mar_file_info(const char *path,
|
||||
int *hasSignatureBlock,
|
||||
uint32_t *numSignatures,
|
||||
int *hasAdditionalBlocks,
|
||||
int get_mar_file_info(const char *path, int *hasSignatureBlock,
|
||||
uint32_t *numSignatures, int *hasAdditionalBlocks,
|
||||
uint32_t *offsetAdditionalBlocks,
|
||||
uint32_t *numAdditionalBlocks);
|
||||
|
||||
|
@ -45,10 +43,9 @@ int get_mar_file_info(const char *path,
|
|||
*
|
||||
* @param infoBlock Out parameter for where to store the result to
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
read_product_info_block(char *path,
|
||||
struct ProductInformationBlock *infoBlock);
|
||||
*/
|
||||
int read_product_info_block(char *path,
|
||||
struct ProductInformationBlock *infoBlock);
|
||||
|
||||
/**
|
||||
* Refreshes the product information block with the new information.
|
||||
|
@ -58,10 +55,9 @@ read_product_info_block(char *path,
|
|||
* should be refreshed.
|
||||
* @param infoBlock Out parameter for where to store the result to
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
refresh_product_info_block(const char *path,
|
||||
struct ProductInformationBlock *infoBlock);
|
||||
*/
|
||||
int refresh_product_info_block(const char *path,
|
||||
struct ProductInformationBlock *infoBlock);
|
||||
|
||||
/**
|
||||
* Writes out a copy of the MAR at src but with the signature block stripped.
|
||||
|
@ -72,8 +68,7 @@ refresh_product_info_block(const char *path,
|
|||
* @return 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
int
|
||||
strip_signature_block(const char *src, const char * dest);
|
||||
int strip_signature_block(const char *src, const char *dest);
|
||||
|
||||
/**
|
||||
* Extracts a signature from a MAR file, base64 encodes it, and writes it out
|
||||
|
@ -83,9 +78,8 @@ strip_signature_block(const char *src, const char * dest);
|
|||
* @param dest The path of file to write the signature to
|
||||
* @return 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
int
|
||||
extract_signature(const char *src, uint32_t sigIndex, const char * dest);
|
||||
*/
|
||||
int extract_signature(const char *src, uint32_t sigIndex, const char *dest);
|
||||
|
||||
/**
|
||||
* Imports a base64 encoded signature into a MAR file
|
||||
|
@ -93,18 +87,16 @@ extract_signature(const char *src, uint32_t sigIndex, const char * dest);
|
|||
* @param src The path of the source MAR file
|
||||
* @param sigIndex The index of the signature to import
|
||||
* @param base64SigFile A file which contains the signature to import
|
||||
* @param dest The path of the destination MAR file with replaced signature
|
||||
* @param dest The path of the destination MAR file with replaced
|
||||
* signature
|
||||
* @return 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
int
|
||||
import_signature(const char *src,
|
||||
uint32_t sigIndex,
|
||||
const char * base64SigFile,
|
||||
const char *dest);
|
||||
*/
|
||||
int import_signature(const char *src, uint32_t sigIndex,
|
||||
const char *base64SigFile, const char *dest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MAR_CMDLINE_H__ */
|
||||
#endif /* MAR_CMDLINE_H__ */
|
||||
|
|
|
@ -45,12 +45,13 @@ static int mar_push(struct MarItemStack *stack, uint32_t length, uint32_t flags,
|
|||
/* increase size of stack */
|
||||
size_t size_needed = ROUND_UP(stack->size_used + size, BLOCKSIZE);
|
||||
stack->head = realloc(stack->head, size_needed);
|
||||
if (!stack->head)
|
||||
if (!stack->head) {
|
||||
return -1;
|
||||
}
|
||||
stack->size_allocated = size_needed;
|
||||
}
|
||||
|
||||
data = (((char *) stack->head) + stack->size_used);
|
||||
data = (((char *)stack->head) + stack->size_used);
|
||||
|
||||
n_offset = htonl(stack->last_offset);
|
||||
n_length = htonl(length);
|
||||
|
@ -104,16 +105,13 @@ static int mar_concat_file(FILE *fp, const char *path) {
|
|||
* the MAR
|
||||
* @param infoBlock The product info block to store in the file.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
static int
|
||||
mar_concat_product_info_block(FILE *fp,
|
||||
struct MarItemStack *stack,
|
||||
struct ProductInformationBlock *infoBlock)
|
||||
{
|
||||
*/
|
||||
static int mar_concat_product_info_block(
|
||||
FILE *fp, struct MarItemStack *stack,
|
||||
struct ProductInformationBlock *infoBlock) {
|
||||
char buf[PIB_MAX_MAR_CHANNEL_ID_SIZE + PIB_MAX_PRODUCT_VERSION_SIZE];
|
||||
uint32_t additionalBlockID = 1, infoBlockSize, unused;
|
||||
if (!fp || !infoBlock ||
|
||||
!infoBlock->MARChannelID ||
|
||||
if (!fp || !infoBlock || !infoBlock->MARChannelID ||
|
||||
!infoBlock->productVersion) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -132,45 +130,41 @@ mar_concat_product_info_block(FILE *fp,
|
|||
maximum MAR channel name and product version, we allocate the maximum
|
||||
amount to make it easier to modify the MAR file for repurposing MAR files
|
||||
to different MAR channels. + 2 is for the NULL terminators. */
|
||||
infoBlockSize = sizeof(infoBlockSize) +
|
||||
sizeof(additionalBlockID) +
|
||||
PIB_MAX_MAR_CHANNEL_ID_SIZE +
|
||||
PIB_MAX_PRODUCT_VERSION_SIZE + 2;
|
||||
infoBlockSize = sizeof(infoBlockSize) + sizeof(additionalBlockID) +
|
||||
PIB_MAX_MAR_CHANNEL_ID_SIZE + PIB_MAX_PRODUCT_VERSION_SIZE +
|
||||
2;
|
||||
if (stack) {
|
||||
stack->last_offset += infoBlockSize;
|
||||
}
|
||||
|
||||
/* Write out the product info block size */
|
||||
infoBlockSize = htonl(infoBlockSize);
|
||||
if (fwrite(&infoBlockSize,
|
||||
sizeof(infoBlockSize), 1, fp) != 1) {
|
||||
if (fwrite(&infoBlockSize, sizeof(infoBlockSize), 1, fp) != 1) {
|
||||
return -1;
|
||||
}
|
||||
infoBlockSize = ntohl(infoBlockSize);
|
||||
|
||||
/* Write out the product info block ID */
|
||||
additionalBlockID = htonl(additionalBlockID);
|
||||
if (fwrite(&additionalBlockID,
|
||||
sizeof(additionalBlockID), 1, fp) != 1) {
|
||||
if (fwrite(&additionalBlockID, sizeof(additionalBlockID), 1, fp) != 1) {
|
||||
return -1;
|
||||
}
|
||||
additionalBlockID = ntohl(additionalBlockID);
|
||||
|
||||
/* Write out the channel name and NULL terminator */
|
||||
if (fwrite(infoBlock->MARChannelID,
|
||||
strlen(infoBlock->MARChannelID) + 1, 1, fp) != 1) {
|
||||
if (fwrite(infoBlock->MARChannelID, strlen(infoBlock->MARChannelID) + 1, 1,
|
||||
fp) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Write out the product version string and NULL terminator */
|
||||
if (fwrite(infoBlock->productVersion,
|
||||
strlen(infoBlock->productVersion) + 1, 1, fp) != 1) {
|
||||
if (fwrite(infoBlock->productVersion, strlen(infoBlock->productVersion) + 1,
|
||||
1, fp) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Write out the rest of the block that is unused */
|
||||
unused = infoBlockSize - (sizeof(infoBlockSize) +
|
||||
sizeof(additionalBlockID) +
|
||||
unused = infoBlockSize - (sizeof(infoBlockSize) + sizeof(additionalBlockID) +
|
||||
strlen(infoBlock->MARChannelID) +
|
||||
strlen(infoBlock->productVersion) + 2);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
@ -188,23 +182,18 @@ mar_concat_product_info_block(FILE *fp,
|
|||
* should be refreshed.
|
||||
* @param infoBlock Out parameter for where to store the result to
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
refresh_product_info_block(const char *path,
|
||||
struct ProductInformationBlock *infoBlock)
|
||||
{
|
||||
FILE *fp ;
|
||||
*/
|
||||
int refresh_product_info_block(const char *path,
|
||||
struct ProductInformationBlock *infoBlock) {
|
||||
FILE *fp;
|
||||
int rv;
|
||||
uint32_t numSignatures, additionalBlockSize, additionalBlockID,
|
||||
offsetAdditionalBlocks, numAdditionalBlocks, i;
|
||||
offsetAdditionalBlocks, numAdditionalBlocks, i;
|
||||
int additionalBlocks, hasSignatureBlock;
|
||||
int64_t oldPos;
|
||||
|
||||
rv = get_mar_file_info(path,
|
||||
&hasSignatureBlock,
|
||||
&numSignatures,
|
||||
&additionalBlocks,
|
||||
&offsetAdditionalBlocks,
|
||||
rv = get_mar_file_info(path, &hasSignatureBlock, &numSignatures,
|
||||
&additionalBlocks, &offsetAdditionalBlocks,
|
||||
&numAdditionalBlocks);
|
||||
if (rv) {
|
||||
fprintf(stderr, "ERROR: Could not obtain MAR information.\n");
|
||||
|
@ -233,18 +222,14 @@ refresh_product_info_block(const char *path,
|
|||
oldPos = ftello(fp);
|
||||
|
||||
/* Read the additional block size */
|
||||
if (fread(&additionalBlockSize,
|
||||
sizeof(additionalBlockSize),
|
||||
1, fp) != 1) {
|
||||
if (fread(&additionalBlockSize, sizeof(additionalBlockSize), 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
additionalBlockSize = ntohl(additionalBlockSize);
|
||||
|
||||
/* Read the additional block ID */
|
||||
if (fread(&additionalBlockID,
|
||||
sizeof(additionalBlockID),
|
||||
1, fp) != 1) {
|
||||
if (fread(&additionalBlockID, sizeof(additionalBlockID), 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
@ -291,12 +276,11 @@ refresh_product_info_block(const char *path,
|
|||
* @param infoBlock The information to store in the product information block.
|
||||
* @return A non-zero value if an error occurs.
|
||||
*/
|
||||
int mar_create(const char *dest, int
|
||||
num_files, char **files,
|
||||
int mar_create(const char *dest, int num_files, char **files,
|
||||
struct ProductInformationBlock *infoBlock) {
|
||||
struct MarItemStack stack;
|
||||
uint32_t offset_to_index = 0, size_of_index,
|
||||
numSignatures, numAdditionalSections;
|
||||
uint32_t offset_to_index = 0, size_of_index, numSignatures,
|
||||
numAdditionalSections;
|
||||
uint64_t sizeOfEntireMAR = 0;
|
||||
struct stat st;
|
||||
FILE *fp;
|
||||
|
@ -310,15 +294,15 @@ int mar_create(const char *dest, int
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (fwrite(MAR_ID, MAR_ID_SIZE, 1, fp) != 1)
|
||||
if (fwrite(MAR_ID, MAR_ID_SIZE, 1, fp) != 1) {
|
||||
goto failure;
|
||||
if (fwrite(&offset_to_index, sizeof(uint32_t), 1, fp) != 1)
|
||||
}
|
||||
if (fwrite(&offset_to_index, sizeof(uint32_t), 1, fp) != 1) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
stack.last_offset = MAR_ID_SIZE +
|
||||
sizeof(offset_to_index) +
|
||||
sizeof(numSignatures) +
|
||||
sizeof(numAdditionalSections) +
|
||||
stack.last_offset = MAR_ID_SIZE + sizeof(offset_to_index) +
|
||||
sizeof(numSignatures) + sizeof(numAdditionalSections) +
|
||||
sizeof(sizeOfEntireMAR);
|
||||
|
||||
/* We will circle back on this at the end of the MAR creation to fill it */
|
||||
|
@ -335,8 +319,8 @@ int mar_create(const char *dest, int
|
|||
/* Write out the number of additional sections, for now just 1
|
||||
for the product info block */
|
||||
numAdditionalSections = htonl(1);
|
||||
if (fwrite(&numAdditionalSections,
|
||||
sizeof(numAdditionalSections), 1, fp) != 1) {
|
||||
if (fwrite(&numAdditionalSections, sizeof(numAdditionalSections), 1, fp) !=
|
||||
1) {
|
||||
goto failure;
|
||||
}
|
||||
numAdditionalSections = ntohl(numAdditionalSections);
|
||||
|
@ -351,20 +335,24 @@ int mar_create(const char *dest, int
|
|||
goto failure;
|
||||
}
|
||||
|
||||
if (mar_push(&stack, st.st_size, st.st_mode & 0777, files[i]))
|
||||
if (mar_push(&stack, st.st_size, st.st_mode & 0777, files[i])) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* concatenate input file to archive */
|
||||
if (mar_concat_file(fp, files[i]))
|
||||
if (mar_concat_file(fp, files[i])) {
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
/* write out the index (prefixed with length of index) */
|
||||
size_of_index = htonl(stack.size_used);
|
||||
if (fwrite(&size_of_index, sizeof(size_of_index), 1, fp) != 1)
|
||||
if (fwrite(&size_of_index, sizeof(size_of_index), 1, fp) != 1) {
|
||||
goto failure;
|
||||
if (fwrite(stack.head, stack.size_used, 1, fp) != 1)
|
||||
}
|
||||
if (fwrite(stack.head, stack.size_used, 1, fp) != 1) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* To protect against invalid MAR files, we assumes that the MAR file
|
||||
size is less than or equal to MAX_SIZE_OF_MAR_FILE. */
|
||||
|
@ -374,26 +362,30 @@ int mar_create(const char *dest, int
|
|||
|
||||
/* write out offset to index file in network byte order */
|
||||
offset_to_index = htonl(stack.last_offset);
|
||||
if (fseek(fp, MAR_ID_SIZE, SEEK_SET))
|
||||
if (fseek(fp, MAR_ID_SIZE, SEEK_SET)) {
|
||||
goto failure;
|
||||
if (fwrite(&offset_to_index, sizeof(offset_to_index), 1, fp) != 1)
|
||||
}
|
||||
if (fwrite(&offset_to_index, sizeof(offset_to_index), 1, fp) != 1) {
|
||||
goto failure;
|
||||
}
|
||||
offset_to_index = ntohl(stack.last_offset);
|
||||
|
||||
sizeOfEntireMAR = ((uint64_t)stack.last_offset) +
|
||||
stack.size_used +
|
||||
sizeof(size_of_index);
|
||||
sizeOfEntireMAR =
|
||||
((uint64_t)stack.last_offset) + stack.size_used + sizeof(size_of_index);
|
||||
sizeOfEntireMAR = HOST_TO_NETWORK64(sizeOfEntireMAR);
|
||||
if (fwrite(&sizeOfEntireMAR, sizeof(sizeOfEntireMAR), 1, fp) != 1)
|
||||
if (fwrite(&sizeOfEntireMAR, sizeof(sizeOfEntireMAR), 1, fp) != 1) {
|
||||
goto failure;
|
||||
}
|
||||
sizeOfEntireMAR = NETWORK_TO_HOST64(sizeOfEntireMAR);
|
||||
|
||||
rv = 0;
|
||||
failure:
|
||||
if (stack.head)
|
||||
if (stack.head) {
|
||||
free(stack.head);
|
||||
}
|
||||
fclose(fp);
|
||||
if (rv)
|
||||
if (rv) {
|
||||
remove(dest);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -15,14 +15,13 @@
|
|||
#ifdef XP_WIN
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
#define fdopen _fdopen
|
||||
#endif
|
||||
|
||||
/* Ensure that the directory containing this file exists */
|
||||
static int mar_ensure_parent_dir(const char *path)
|
||||
{
|
||||
static int mar_ensure_parent_dir(const char *path) {
|
||||
char *slash = strrchr(path, '/');
|
||||
if (slash)
|
||||
{
|
||||
if (slash) {
|
||||
*slash = '\0';
|
||||
mar_ensure_parent_dir(path);
|
||||
#ifdef XP_WIN
|
||||
|
@ -40,11 +39,13 @@ static int mar_test_callback(MarFile *mar, const MarItem *item, void *unused) {
|
|||
uint8_t buf[BLOCKSIZE];
|
||||
int fd, len, offset = 0;
|
||||
|
||||
if (mar_ensure_parent_dir(item->name))
|
||||
if (mar_ensure_parent_dir(item->name)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
fd = _open(item->name, _O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY, item->flags);
|
||||
fd = _open(item->name, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY,
|
||||
item->flags);
|
||||
#else
|
||||
fd = creat(item->name, item->flags);
|
||||
#endif
|
||||
|
@ -55,12 +56,14 @@ static int mar_test_callback(MarFile *mar, const MarItem *item, void *unused) {
|
|||
}
|
||||
|
||||
fp = fdopen(fd, "wb");
|
||||
if (!fp)
|
||||
if (!fp) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((len = mar_read(mar, item, offset, buf, sizeof(buf))) > 0) {
|
||||
if (fwrite(buf, len, 1, fp) != 1)
|
||||
if (fwrite(buf, len, 1, fp) != 1) {
|
||||
break;
|
||||
}
|
||||
offset += len;
|
||||
}
|
||||
|
||||
|
@ -73,8 +76,9 @@ int mar_extract(const char *path) {
|
|||
int rv;
|
||||
|
||||
mar = mar_open(path);
|
||||
if (!mar)
|
||||
if (!mar) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = mar_enum_items(mar, mar_test_callback, NULL);
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ MOZ_STATIC_ASSERT(MAX_SIZE_OF_MAR_FILE < ((int64_t)LONG_MAX),
|
|||
|
||||
/* We store at most the size up to the signature block + 4
|
||||
bytes per BLOCKSIZE bytes */
|
||||
MOZ_STATIC_ASSERT(sizeof(BLOCKSIZE) < \
|
||||
(SIGNATURE_BLOCK_OFFSET + sizeof(uint32_t)),
|
||||
MOZ_STATIC_ASSERT(sizeof(BLOCKSIZE) <
|
||||
(SIGNATURE_BLOCK_OFFSET + sizeof(uint32_t)),
|
||||
"BLOCKSIZE is too big");
|
||||
|
||||
/* The maximum size of any signature supported by current and future
|
||||
|
@ -44,7 +44,7 @@ MOZ_STATIC_ASSERT(sizeof(BLOCKSIZE) < \
|
|||
The product information block has an ID of 1. */
|
||||
#define PRODUCT_INFO_BLOCK_ID 1
|
||||
|
||||
#define MAR_ITEM_SIZE(namelen) (3*sizeof(uint32_t) + (namelen) + 1)
|
||||
#define MAR_ITEM_SIZE(namelen) (3 * sizeof(uint32_t) + (namelen) + 1)
|
||||
|
||||
/* Product Information Block (PIB) constants */
|
||||
#define PIB_MAX_MAR_CHANNEL_ID_SIZE 63
|
||||
|
@ -65,15 +65,13 @@ MOZ_STATIC_ASSERT(sizeof(BLOCKSIZE) < \
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#define HOST_TO_NETWORK64(x) ( \
|
||||
((((uint64_t) x) & 0xFF) << 56) | \
|
||||
((((uint64_t) x) >> 8) & 0xFF) << 48) | \
|
||||
(((((uint64_t) x) >> 16) & 0xFF) << 40) | \
|
||||
(((((uint64_t) x) >> 24) & 0xFF) << 32) | \
|
||||
(((((uint64_t) x) >> 32) & 0xFF) << 24) | \
|
||||
(((((uint64_t) x) >> 40) & 0xFF) << 16) | \
|
||||
(((((uint64_t) x) >> 48) & 0xFF) << 8) | \
|
||||
(((uint64_t) x) >> 56)
|
||||
#define HOST_TO_NETWORK64(x) \
|
||||
(((((uint64_t)x) & 0xFF) << 56) | ((((uint64_t)x) >> 8) & 0xFF) << 48) | \
|
||||
(((((uint64_t)x) >> 16) & 0xFF) << 40) | \
|
||||
(((((uint64_t)x) >> 24) & 0xFF) << 32) | \
|
||||
(((((uint64_t)x) >> 32) & 0xFF) << 24) | \
|
||||
(((((uint64_t)x) >> 40) & 0xFF) << 16) | \
|
||||
(((((uint64_t)x) >> 48) & 0xFF) << 8) | (((uint64_t)x) >> 56)
|
||||
#define NETWORK_TO_HOST64 HOST_TO_NETWORK64
|
||||
|
||||
#endif /* MAR_PRIVATE_H__ */
|
||||
#endif /* MAR_PRIVATE_H__ */
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
#include "city.h"
|
||||
#include "mar_private.h"
|
||||
#include "mar.h"
|
||||
#ifdef XP_WIN
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
/* This block must be at most 104 bytes.
|
||||
MAR channel name < 64 bytes, and product version < 32 bytes + 3 NULL
|
||||
|
@ -19,26 +22,19 @@
|
|||
sizeof(additionalBlockSize) and sizeof(additionalBlockID) */
|
||||
#define MAXADDITIONALBLOCKSIZE 96
|
||||
|
||||
static uint32_t
|
||||
mar_hash_name(const char* name)
|
||||
{
|
||||
static uint32_t mar_hash_name(const char* name) {
|
||||
return CityHash64(name, strlen(name)) % TABLESIZE;
|
||||
}
|
||||
|
||||
static int
|
||||
mar_insert_item(MarFile* mar,
|
||||
const char* name,
|
||||
int namelen,
|
||||
uint32_t offset,
|
||||
uint32_t length,
|
||||
uint32_t flags)
|
||||
{
|
||||
static int mar_insert_item(MarFile* mar, const char* name, int namelen,
|
||||
uint32_t offset, uint32_t length, uint32_t flags) {
|
||||
MarItem *item, *root;
|
||||
uint32_t hash;
|
||||
|
||||
item = (MarItem *) malloc(sizeof(MarItem) + namelen);
|
||||
if (!item)
|
||||
item = (MarItem*)malloc(sizeof(MarItem) + namelen);
|
||||
if (!item) {
|
||||
return -1;
|
||||
}
|
||||
item->next = NULL;
|
||||
item->offset = offset;
|
||||
item->length = length;
|
||||
|
@ -52,16 +48,13 @@ mar_insert_item(MarFile* mar,
|
|||
mar->item_table[hash] = item;
|
||||
} else {
|
||||
/* append item */
|
||||
while (root->next)
|
||||
root = root->next;
|
||||
while (root->next) root = root->next;
|
||||
root->next = item;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mar_consume_index(MarFile* mar, char** buf, const char* buf_end)
|
||||
{
|
||||
static int mar_consume_index(MarFile* mar, char** buf, const char* buf_end) {
|
||||
/*
|
||||
* Each item has the following structure:
|
||||
* uint32_t offset (network byte order)
|
||||
|
@ -73,11 +66,12 @@ mar_consume_index(MarFile* mar, char** buf, const char* buf_end)
|
|||
uint32_t offset;
|
||||
uint32_t length;
|
||||
uint32_t flags;
|
||||
const char *name;
|
||||
const char* name;
|
||||
int namelen;
|
||||
|
||||
if ((buf_end - *buf) < (int)(3*sizeof(uint32_t) + 2))
|
||||
if ((buf_end - *buf) < (int)(3 * sizeof(uint32_t) + 2)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(&offset, *buf, sizeof(offset));
|
||||
*buf += sizeof(offset);
|
||||
|
@ -96,8 +90,9 @@ mar_consume_index(MarFile* mar, char** buf, const char* buf_end)
|
|||
/* find namelen; must take care not to read beyond buf_end */
|
||||
while (**buf) {
|
||||
/* buf_end points one byte past the end of buf's allocation */
|
||||
if (*buf == (buf_end - 1))
|
||||
if (*buf == (buf_end - 1)) {
|
||||
return -1;
|
||||
}
|
||||
++(*buf);
|
||||
}
|
||||
namelen = (*buf - name);
|
||||
|
@ -106,39 +101,44 @@ mar_consume_index(MarFile* mar, char** buf, const char* buf_end)
|
|||
return -1;
|
||||
}
|
||||
/* consume null byte */
|
||||
if (*buf == buf_end)
|
||||
if (*buf == buf_end) {
|
||||
return -1;
|
||||
}
|
||||
++(*buf);
|
||||
|
||||
return mar_insert_item(mar, name, namelen, offset, length, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
mar_read_index(MarFile* mar)
|
||||
{
|
||||
static int mar_read_index(MarFile* mar) {
|
||||
char id[MAR_ID_SIZE], *buf, *bufptr, *bufend;
|
||||
uint32_t offset_to_index, size_of_index;
|
||||
|
||||
/* verify MAR ID */
|
||||
fseek(mar->fp, 0, SEEK_SET);
|
||||
if (fread(id, MAR_ID_SIZE, 1, mar->fp) != 1)
|
||||
if (fread(id, MAR_ID_SIZE, 1, mar->fp) != 1) {
|
||||
return -1;
|
||||
if (memcmp(id, MAR_ID, MAR_ID_SIZE) != 0)
|
||||
}
|
||||
if (memcmp(id, MAR_ID, MAR_ID_SIZE) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread(&offset_to_index, sizeof(uint32_t), 1, mar->fp) != 1)
|
||||
if (fread(&offset_to_index, sizeof(uint32_t), 1, mar->fp) != 1) {
|
||||
return -1;
|
||||
}
|
||||
offset_to_index = ntohl(offset_to_index);
|
||||
|
||||
if (fseek(mar->fp, offset_to_index, SEEK_SET))
|
||||
if (fseek(mar->fp, offset_to_index, SEEK_SET)) {
|
||||
return -1;
|
||||
if (fread(&size_of_index, sizeof(uint32_t), 1, mar->fp) != 1)
|
||||
}
|
||||
if (fread(&size_of_index, sizeof(uint32_t), 1, mar->fp) != 1) {
|
||||
return -1;
|
||||
}
|
||||
size_of_index = ntohl(size_of_index);
|
||||
|
||||
buf = (char *) malloc(size_of_index);
|
||||
if (!buf)
|
||||
buf = (char*)malloc(size_of_index);
|
||||
if (!buf) {
|
||||
return -1;
|
||||
}
|
||||
if (fread(buf, size_of_index, 1, mar->fp) != 1) {
|
||||
free(buf);
|
||||
return -1;
|
||||
|
@ -146,7 +146,8 @@ mar_read_index(MarFile* mar)
|
|||
|
||||
bufptr = buf;
|
||||
bufend = buf + size_of_index;
|
||||
while (bufptr < bufend && mar_consume_index(mar, &bufptr, bufend) == 0);
|
||||
while (bufptr < bufend && mar_consume_index(mar, &bufptr, bufend) == 0)
|
||||
;
|
||||
|
||||
free(buf);
|
||||
return (bufptr == bufend) ? 0 : -1;
|
||||
|
@ -160,9 +161,7 @@ mar_read_index(MarFile* mar)
|
|||
* @return int 1 on success, 0 if offset has been previously processed
|
||||
* -1 if unable to allocate space for the SeenIndexes
|
||||
*/
|
||||
static int
|
||||
mar_insert_offset(MarFile* mar, uint32_t offset, uint32_t length)
|
||||
{
|
||||
static int mar_insert_offset(MarFile* mar, uint32_t offset, uint32_t length) {
|
||||
/* Ignore files with no length */
|
||||
if (length == 0) {
|
||||
return 1;
|
||||
|
@ -213,9 +212,7 @@ mar_insert_offset(MarFile* mar, uint32_t offset, uint32_t length)
|
|||
* Internal shared code for mar_open and mar_wopen.
|
||||
* On failure, will fclose(fp).
|
||||
*/
|
||||
static MarFile*
|
||||
mar_fpopen(FILE* fp)
|
||||
{
|
||||
static MarFile* mar_fpopen(FILE* fp) {
|
||||
MarFile* mar;
|
||||
|
||||
mar = (MarFile*)malloc(sizeof(*mar));
|
||||
|
@ -232,10 +229,8 @@ mar_fpopen(FILE* fp)
|
|||
return mar;
|
||||
}
|
||||
|
||||
MarFile*
|
||||
mar_open(const char* path)
|
||||
{
|
||||
FILE *fp;
|
||||
MarFile* mar_open(const char* path) {
|
||||
FILE* fp;
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
|
@ -248,10 +243,8 @@ mar_open(const char* path)
|
|||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
MarFile*
|
||||
mar_wopen(const wchar_t* path)
|
||||
{
|
||||
FILE *fp;
|
||||
MarFile* mar_wopen(const wchar_t* path) {
|
||||
FILE* fp;
|
||||
|
||||
_wfopen_s(&fp, path, L"rb");
|
||||
if (!fp) {
|
||||
|
@ -264,9 +257,7 @@ mar_wopen(const wchar_t* path)
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
mar_close(MarFile* mar)
|
||||
{
|
||||
void mar_close(MarFile* mar) {
|
||||
MarItem* item;
|
||||
SeenIndex* index;
|
||||
int i;
|
||||
|
@ -309,14 +300,10 @@ mar_close(MarFile* mar)
|
|||
* hasAdditionalBlocks is not equal to 0.
|
||||
* @return 0 on success and non-zero on failure.
|
||||
*/
|
||||
int
|
||||
get_mar_file_info_fp(FILE* fp,
|
||||
int* hasSignatureBlock,
|
||||
uint32_t* numSignatures,
|
||||
int* hasAdditionalBlocks,
|
||||
uint32_t* offsetAdditionalBlocks,
|
||||
uint32_t* numAdditionalBlocks)
|
||||
{
|
||||
int get_mar_file_info_fp(FILE* fp, int* hasSignatureBlock,
|
||||
uint32_t* numSignatures, int* hasAdditionalBlocks,
|
||||
uint32_t* offsetAdditionalBlocks,
|
||||
uint32_t* numAdditionalBlocks) {
|
||||
uint32_t offsetToIndex, offsetToContent, signatureCount, signatureLen, i;
|
||||
|
||||
/* One of hasSignatureBlock or hasAdditionalBlocks must be non NULL */
|
||||
|
@ -324,7 +311,6 @@ get_mar_file_info_fp(FILE* fp,
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Skip to the start of the offset index */
|
||||
if (fseek(fp, MAR_ID_SIZE, SEEK_SET)) {
|
||||
return -1;
|
||||
|
@ -337,7 +323,7 @@ get_mar_file_info_fp(FILE* fp,
|
|||
offsetToIndex = ntohl(offsetToIndex);
|
||||
|
||||
if (numSignatures) {
|
||||
/* Skip past the MAR file size field */
|
||||
/* Skip past the MAR file size field */
|
||||
if (fseek(fp, sizeof(uint64_t), SEEK_CUR)) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -381,7 +367,7 @@ get_mar_file_info_fp(FILE* fp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Skip to the start of the signature block */
|
||||
/* Skip to the start of the signature block */
|
||||
if (fseeko(fp, SIGNATURE_BLOCK_OFFSET, SEEK_SET)) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -446,15 +432,15 @@ get_mar_file_info_fp(FILE* fp,
|
|||
*
|
||||
* @param infoBlock Out parameter for where to store the result to
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
read_product_info_block(char* path, struct ProductInformationBlock* infoBlock)
|
||||
{
|
||||
*/
|
||||
int read_product_info_block(char* path,
|
||||
struct ProductInformationBlock* infoBlock) {
|
||||
int rv;
|
||||
MarFile mar;
|
||||
mar.fp = fopen(path, "rb");
|
||||
if (!mar.fp) {
|
||||
fprintf(stderr, "ERROR: could not open file in read_product_info_block()\n");
|
||||
fprintf(stderr,
|
||||
"ERROR: could not open file in read_product_info_block()\n");
|
||||
perror(path);
|
||||
return -1;
|
||||
}
|
||||
|
@ -470,20 +456,17 @@ read_product_info_block(char* path, struct ProductInformationBlock* infoBlock)
|
|||
*
|
||||
* @param infoBlock Out parameter for where to store the result to
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
mar_read_product_info_block(MarFile* mar,
|
||||
struct ProductInformationBlock* infoBlock)
|
||||
{
|
||||
uint32_t offsetAdditionalBlocks, numAdditionalBlocks,
|
||||
additionalBlockSize, additionalBlockID;
|
||||
*/
|
||||
int mar_read_product_info_block(MarFile* mar,
|
||||
struct ProductInformationBlock* infoBlock) {
|
||||
uint32_t offsetAdditionalBlocks, numAdditionalBlocks, additionalBlockSize,
|
||||
additionalBlockID;
|
||||
int hasAdditionalBlocks;
|
||||
|
||||
/* The buffer size is 97 bytes because the MAR channel name < 64 bytes, and
|
||||
product version < 32 bytes + 3 NULL terminator bytes. */
|
||||
char buf[MAXADDITIONALBLOCKSIZE + 1] = { '\0' };
|
||||
if (get_mar_file_info_fp(mar->fp, NULL, NULL,
|
||||
&hasAdditionalBlocks,
|
||||
char buf[MAXADDITIONALBLOCKSIZE + 1] = {'\0'};
|
||||
if (get_mar_file_info_fp(mar->fp, NULL, NULL, &hasAdditionalBlocks,
|
||||
&offsetAdditionalBlocks,
|
||||
&numAdditionalBlocks) != 0) {
|
||||
return -1;
|
||||
|
@ -493,9 +476,8 @@ mar_read_product_info_block(MarFile* mar,
|
|||
in a MAR file so check if any exist and process the first found */
|
||||
if (numAdditionalBlocks > 0) {
|
||||
/* Read the additional block size */
|
||||
if (fread(&additionalBlockSize,
|
||||
sizeof(additionalBlockSize),
|
||||
1, mar->fp) != 1) {
|
||||
if (fread(&additionalBlockSize, sizeof(additionalBlockSize), 1, mar->fp) !=
|
||||
1) {
|
||||
return -1;
|
||||
}
|
||||
additionalBlockSize = ntohl(additionalBlockSize) -
|
||||
|
@ -508,15 +490,13 @@ mar_read_product_info_block(MarFile* mar,
|
|||
}
|
||||
|
||||
/* Read the additional block ID */
|
||||
if (fread(&additionalBlockID,
|
||||
sizeof(additionalBlockID),
|
||||
1, mar->fp) != 1) {
|
||||
if (fread(&additionalBlockID, sizeof(additionalBlockID), 1, mar->fp) != 1) {
|
||||
return -1;
|
||||
}
|
||||
additionalBlockID = ntohl(additionalBlockID);
|
||||
|
||||
if (PRODUCT_INFO_BLOCK_ID == additionalBlockID) {
|
||||
const char *location;
|
||||
const char* location;
|
||||
int len;
|
||||
|
||||
if (fread(buf, additionalBlockSize, 1, mar->fp) != 1) {
|
||||
|
@ -543,10 +523,8 @@ mar_read_product_info_block(MarFile* mar,
|
|||
infoBlock->productVersion = NULL;
|
||||
return -1;
|
||||
}
|
||||
infoBlock->MARChannelID =
|
||||
strdup(infoBlock->MARChannelID);
|
||||
infoBlock->productVersion =
|
||||
strdup(infoBlock->productVersion);
|
||||
infoBlock->MARChannelID = strdup(infoBlock->MARChannelID);
|
||||
infoBlock->productVersion = strdup(infoBlock->productVersion);
|
||||
return 0;
|
||||
} else {
|
||||
/* This is not the additional block you're looking for. Move along. */
|
||||
|
@ -560,9 +538,7 @@ mar_read_product_info_block(MarFile* mar,
|
|||
return -1;
|
||||
}
|
||||
|
||||
const MarItem*
|
||||
mar_find_item(MarFile* mar, const char* name)
|
||||
{
|
||||
const MarItem* mar_find_item(MarFile* mar, const char* name) {
|
||||
uint32_t hash;
|
||||
const MarItem* item;
|
||||
|
||||
|
@ -590,9 +566,7 @@ mar_find_item(MarFile* mar, const char* name)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
mar_enum_items(MarFile* mar, MarItemCallback callback, void* closure)
|
||||
{
|
||||
int mar_enum_items(MarFile* mar, MarItemCallback callback, void* closure) {
|
||||
MarItem* item;
|
||||
int i, rv;
|
||||
|
||||
|
@ -624,26 +598,25 @@ mar_enum_items(MarFile* mar, MarItemCallback callback, void* closure)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mar_read(MarFile* mar,
|
||||
const MarItem* item,
|
||||
int offset,
|
||||
uint8_t* buf,
|
||||
int bufsize)
|
||||
{
|
||||
int mar_read(MarFile* mar, const MarItem* item, int offset, uint8_t* buf,
|
||||
int bufsize) {
|
||||
int nr;
|
||||
|
||||
if (offset == (int) item->length)
|
||||
if (offset == (int)item->length) {
|
||||
return 0;
|
||||
if (offset > (int) item->length)
|
||||
}
|
||||
if (offset > (int)item->length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
nr = item->length - offset;
|
||||
if (nr > bufsize)
|
||||
if (nr > bufsize) {
|
||||
nr = bufsize;
|
||||
}
|
||||
|
||||
if (fseek(mar->fp, item->offset + offset, SEEK_SET))
|
||||
if (fseek(mar->fp, item->offset + offset, SEEK_SET)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fread(buf, 1, nr, mar->fp);
|
||||
}
|
||||
|
@ -666,25 +639,21 @@ mar_read(MarFile* mar,
|
|||
* has_additional_blocks is not equal to 0.
|
||||
* @return 0 on success and non-zero on failure.
|
||||
*/
|
||||
int
|
||||
get_mar_file_info(const char* path,
|
||||
int* hasSignatureBlock,
|
||||
uint32_t* numSignatures,
|
||||
int* hasAdditionalBlocks,
|
||||
uint32_t* offsetAdditionalBlocks,
|
||||
uint32_t* numAdditionalBlocks)
|
||||
{
|
||||
int get_mar_file_info(const char* path, int* hasSignatureBlock,
|
||||
uint32_t* numSignatures, int* hasAdditionalBlocks,
|
||||
uint32_t* offsetAdditionalBlocks,
|
||||
uint32_t* numAdditionalBlocks) {
|
||||
int rv;
|
||||
FILE *fp = fopen(path, "rb");
|
||||
FILE* fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "ERROR: could not open file in get_mar_file_info()\n");
|
||||
perror(path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = get_mar_file_info_fp(fp, hasSignatureBlock,
|
||||
numSignatures, hasAdditionalBlocks,
|
||||
offsetAdditionalBlocks, numAdditionalBlocks);
|
||||
rv = get_mar_file_info_fp(fp, hasSignatureBlock, numSignatures,
|
||||
hasAdditionalBlocks, offsetAdditionalBlocks,
|
||||
numAdditionalBlocks);
|
||||
|
||||
fclose(fp);
|
||||
return rv;
|
||||
|
|
|
@ -26,10 +26,8 @@ int NSSInitCryptoContext(const char *NSSConfigDir);
|
|||
#endif
|
||||
|
||||
int mar_repackage_and_sign(const char *NSSConfigDir,
|
||||
const char * const *certNames,
|
||||
uint32_t certCount,
|
||||
const char *src,
|
||||
const char * dest);
|
||||
const char *const *certNames, uint32_t certCount,
|
||||
const char *src, const char *dest);
|
||||
|
||||
static void print_version() {
|
||||
printf("Version: %s\n", MOZ_APP_VERSION);
|
||||
|
@ -39,43 +37,55 @@ static void print_version() {
|
|||
static void print_usage() {
|
||||
printf("usage:\n");
|
||||
printf("Create a MAR file:\n");
|
||||
printf(" mar [-H MARChannelID] [-V ProductVersion] [-C workingDir] "
|
||||
"-c archive.mar [files...]\n");
|
||||
printf(
|
||||
" mar [-H MARChannelID] [-V ProductVersion] [-C workingDir] "
|
||||
"-c archive.mar [files...]\n");
|
||||
|
||||
printf("Extract a MAR file:\n");
|
||||
printf(" mar [-C workingDir] -x archive.mar\n");
|
||||
#ifndef NO_SIGN_VERIFY
|
||||
printf("Sign a MAR file:\n");
|
||||
printf(" mar [-C workingDir] -d NSSConfigDir -n certname -s "
|
||||
"archive.mar out_signed_archive.mar\n");
|
||||
printf(
|
||||
" mar [-C workingDir] -d NSSConfigDir -n certname -s "
|
||||
"archive.mar out_signed_archive.mar\n");
|
||||
|
||||
printf("Strip a MAR signature:\n");
|
||||
printf(" mar [-C workingDir] -r "
|
||||
"signed_input_archive.mar output_archive.mar\n");
|
||||
printf(
|
||||
" mar [-C workingDir] -r "
|
||||
"signed_input_archive.mar output_archive.mar\n");
|
||||
|
||||
printf("Extract a MAR signature:\n");
|
||||
printf(" mar [-C workingDir] -n(i) -X "
|
||||
"signed_input_archive.mar base_64_encoded_signature_file\n");
|
||||
printf(
|
||||
" mar [-C workingDir] -n(i) -X "
|
||||
"signed_input_archive.mar base_64_encoded_signature_file\n");
|
||||
|
||||
printf("Import a MAR signature:\n");
|
||||
printf(" mar [-C workingDir] -n(i) -I "
|
||||
"signed_input_archive.mar base_64_encoded_signature_file "
|
||||
"changed_signed_output.mar\n");
|
||||
printf(
|
||||
" mar [-C workingDir] -n(i) -I "
|
||||
"signed_input_archive.mar base_64_encoded_signature_file "
|
||||
"changed_signed_output.mar\n");
|
||||
printf("(i) is the index of the certificate to extract\n");
|
||||
#if defined(XP_MACOSX) || (defined(XP_WIN) && !defined(MAR_NSS))
|
||||
printf("Verify a MAR file:\n");
|
||||
printf(" mar [-C workingDir] -D DERFilePath -v signed_archive.mar\n");
|
||||
printf("At most %d signature certificate DER files are specified by "
|
||||
"-D0 DERFilePath1 -D1 DERFilePath2, ...\n", MAX_SIGNATURES);
|
||||
printf(
|
||||
"At most %d signature certificate DER files are specified by "
|
||||
"-D0 DERFilePath1 -D1 DERFilePath2, ...\n",
|
||||
MAX_SIGNATURES);
|
||||
#else
|
||||
printf("Verify a MAR file:\n");
|
||||
printf(" mar [-C workingDir] -d NSSConfigDir -n certname "
|
||||
"-v signed_archive.mar\n");
|
||||
printf("At most %d signature certificate names are specified by "
|
||||
"-n0 certName -n1 certName2, ...\n", MAX_SIGNATURES);
|
||||
printf(
|
||||
" mar [-C workingDir] -d NSSConfigDir -n certname "
|
||||
"-v signed_archive.mar\n");
|
||||
printf(
|
||||
"At most %d signature certificate names are specified by "
|
||||
"-n0 certName -n1 certName2, ...\n",
|
||||
MAX_SIGNATURES);
|
||||
#endif
|
||||
printf("At most %d verification certificate names are specified by "
|
||||
"-n0 certName -n1 certName2, ...\n", MAX_SIGNATURES);
|
||||
printf(
|
||||
"At most %d verification certificate names are specified by "
|
||||
"-n0 certName -n1 certName2, ...\n",
|
||||
MAX_SIGNATURES);
|
||||
#endif
|
||||
printf("Print information on a MAR file:\n");
|
||||
printf(" mar -t archive.mar\n");
|
||||
|
@ -84,17 +94,16 @@ static void print_usage() {
|
|||
printf(" mar -T archive.mar\n");
|
||||
|
||||
printf("Refresh the product information block of a MAR file:\n");
|
||||
printf(" mar [-H MARChannelID] [-V ProductVersion] [-C workingDir] "
|
||||
"-i unsigned_archive_to_refresh.mar\n");
|
||||
printf(
|
||||
" mar [-H MARChannelID] [-V ProductVersion] [-C workingDir] "
|
||||
"-i unsigned_archive_to_refresh.mar\n");
|
||||
|
||||
printf("Print executable version:\n");
|
||||
printf(" mar --version\n");
|
||||
printf("This program does not handle unicode file paths properly\n");
|
||||
}
|
||||
|
||||
static int mar_test_callback(MarFile *mar,
|
||||
const MarItem *item,
|
||||
void *unused) {
|
||||
static int mar_test_callback(MarFile *mar, const MarItem *item, void *unused) {
|
||||
printf("%u\t0%o\t%s\n", item->length, item->flags, item->name);
|
||||
return 0;
|
||||
}
|
||||
|
@ -103,8 +112,9 @@ static int mar_test(const char *path) {
|
|||
MarFile *mar;
|
||||
|
||||
mar = mar_open(path);
|
||||
if (!mar)
|
||||
if (!mar) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("SIZE\tMODE\tNAME\n");
|
||||
mar_enum_items(mar, mar_test_callback, NULL);
|
||||
|
@ -125,22 +135,22 @@ int main(int argc, char **argv) {
|
|||
|
||||
#if !defined(NO_SIGN_VERIFY)
|
||||
uint32_t fileSizes[MAX_SIGNATURES];
|
||||
const uint8_t* certBuffers[MAX_SIGNATURES];
|
||||
const uint8_t *certBuffers[MAX_SIGNATURES];
|
||||
#if ((!defined(MAR_NSS) && defined(XP_WIN)) || defined(XP_MACOSX)) || \
|
||||
((defined(XP_WIN) || defined(XP_MACOSX)) && !defined(MAR_NSS))
|
||||
char* DERFilePaths[MAX_SIGNATURES];
|
||||
char *DERFilePaths[MAX_SIGNATURES];
|
||||
#endif
|
||||
#if (!defined(XP_WIN) && !defined(XP_MACOSX)) || defined(MAR_NSS)
|
||||
CERTCertificate* certs[MAX_SIGNATURES];
|
||||
CERTCertificate *certs[MAX_SIGNATURES];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
memset((void*)certNames, 0, sizeof(certNames));
|
||||
memset((void *)certNames, 0, sizeof(certNames));
|
||||
#if defined(XP_WIN) && !defined(MAR_NSS) && !defined(NO_SIGN_VERIFY)
|
||||
memset((void*)certBuffers, 0, sizeof(certBuffers));
|
||||
memset((void *)certBuffers, 0, sizeof(certBuffers));
|
||||
#endif
|
||||
#if !defined(NO_SIGN_VERIFY) && ((!defined(MAR_NSS) && defined(XP_WIN)) || \
|
||||
defined(XP_MACOSX))
|
||||
#if !defined(NO_SIGN_VERIFY) && \
|
||||
((!defined(MAR_NSS) && defined(XP_WIN)) || defined(XP_MACOSX))
|
||||
memset(DERFilePaths, 0, sizeof(DERFilePaths));
|
||||
memset(fileSizes, 0, sizeof(fileSizes));
|
||||
#endif
|
||||
|
@ -156,14 +166,13 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
while (argc > 0) {
|
||||
if (argv[1][0] == '-' && (argv[1][1] == 'c' ||
|
||||
argv[1][1] == 't' || argv[1][1] == 'x' ||
|
||||
argv[1][1] == 'v' || argv[1][1] == 's' ||
|
||||
argv[1][1] == 'i' || argv[1][1] == 'T' ||
|
||||
argv[1][1] == 'r' || argv[1][1] == 'X' ||
|
||||
argv[1][1] == 'I')) {
|
||||
if (argv[1][0] == '-' &&
|
||||
(argv[1][1] == 'c' || argv[1][1] == 't' || argv[1][1] == 'x' ||
|
||||
argv[1][1] == 'v' || argv[1][1] == 's' || argv[1][1] == 'i' ||
|
||||
argv[1][1] == 'T' || argv[1][1] == 'r' || argv[1][1] == 'X' ||
|
||||
argv[1][1] == 'I')) {
|
||||
break;
|
||||
/* -C workingdirectory */
|
||||
/* -C workingdirectory */
|
||||
}
|
||||
if (argv[1][0] == '-' && argv[1][1] == 'C') {
|
||||
if (chdir(argv[2]) != 0) {
|
||||
|
@ -172,13 +181,12 @@ int main(int argc, char **argv) {
|
|||
argv += 2;
|
||||
argc -= 2;
|
||||
}
|
||||
#if !defined(NO_SIGN_VERIFY) && ((!defined(MAR_NSS) && defined(XP_WIN)) || \
|
||||
defined(XP_MACOSX))
|
||||
#if !defined(NO_SIGN_VERIFY) && \
|
||||
((!defined(MAR_NSS) && defined(XP_WIN)) || defined(XP_MACOSX))
|
||||
/* -D DERFilePath, also matches -D[index] DERFilePath
|
||||
We allow an index for verifying to be symmetric
|
||||
with the import and export command line arguments. */
|
||||
else if (argv[1][0] == '-' &&
|
||||
argv[1][1] == 'D' &&
|
||||
else if (argv[1][0] == '-' && argv[1][1] == 'D' &&
|
||||
(argv[1][2] == (char)('0' + certCount) || argv[1][2] == '\0')) {
|
||||
if (certCount >= MAX_SIGNATURES) {
|
||||
print_usage();
|
||||
|
@ -194,15 +202,12 @@ int main(int argc, char **argv) {
|
|||
NSSConfigDir = argv[2];
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
/* -n certName, also matches -n[index] certName
|
||||
We allow an index for verifying to be symmetric
|
||||
with the import and export command line arguments. */
|
||||
} else if (argv[1][0] == '-' &&
|
||||
argv[1][1] == 'n' &&
|
||||
(argv[1][2] == (char)('0' + certCount) ||
|
||||
argv[1][2] == '\0' ||
|
||||
!strcmp(argv[2], "-X") ||
|
||||
!strcmp(argv[2], "-I"))) {
|
||||
/* -n certName, also matches -n[index] certName
|
||||
We allow an index for verifying to be symmetric
|
||||
with the import and export command line arguments. */
|
||||
} else if (argv[1][0] == '-' && argv[1][1] == 'n' &&
|
||||
(argv[1][2] == (char)('0' + certCount) || argv[1][2] == '\0' ||
|
||||
!strcmp(argv[2], "-X") || !strcmp(argv[2], "-I"))) {
|
||||
if (certCount >= MAX_SIGNATURES) {
|
||||
print_usage();
|
||||
return -1;
|
||||
|
@ -218,18 +223,15 @@ int main(int argc, char **argv) {
|
|||
argv += 2;
|
||||
argc -= 2;
|
||||
}
|
||||
/* MAR channel ID */
|
||||
} else if (argv[1][0] == '-' && argv[1][1] == 'H') {
|
||||
} else if (argv[1][0] == '-' && argv[1][1] == 'H') { // MAR channel ID
|
||||
MARChannelID = argv[2];
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
/* Product Version */
|
||||
} else if (argv[1][0] == '-' && argv[1][1] == 'V') {
|
||||
} else if (argv[1][0] == '-' && argv[1][1] == 'V') { // Product Version
|
||||
productVersion = argv[2];
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
|
@ -241,187 +243,181 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
switch (argv[1][1]) {
|
||||
case 'c': {
|
||||
struct ProductInformationBlock infoBlock;
|
||||
infoBlock.MARChannelID = MARChannelID;
|
||||
infoBlock.productVersion = productVersion;
|
||||
return mar_create(argv[2], argc - 3, argv + 3, &infoBlock);
|
||||
}
|
||||
case 'i': {
|
||||
struct ProductInformationBlock infoBlock;
|
||||
infoBlock.MARChannelID = MARChannelID;
|
||||
infoBlock.productVersion = productVersion;
|
||||
return refresh_product_info_block(argv[2], &infoBlock);
|
||||
}
|
||||
case 'T': {
|
||||
struct ProductInformationBlock infoBlock;
|
||||
uint32_t numSignatures, numAdditionalBlocks;
|
||||
int hasSignatureBlock, hasAdditionalBlock;
|
||||
if (!get_mar_file_info(argv[2],
|
||||
&hasSignatureBlock,
|
||||
&numSignatures,
|
||||
&hasAdditionalBlock,
|
||||
NULL, &numAdditionalBlocks)) {
|
||||
if (hasSignatureBlock) {
|
||||
printf("Signature block found with %d signature%s\n",
|
||||
numSignatures,
|
||||
numSignatures != 1 ? "s" : "");
|
||||
}
|
||||
if (hasAdditionalBlock) {
|
||||
printf("%d additional block%s found:\n",
|
||||
numAdditionalBlocks,
|
||||
numAdditionalBlocks != 1 ? "s" : "");
|
||||
}
|
||||
case 'c': {
|
||||
struct ProductInformationBlock infoBlock;
|
||||
infoBlock.MARChannelID = MARChannelID;
|
||||
infoBlock.productVersion = productVersion;
|
||||
return mar_create(argv[2], argc - 3, argv + 3, &infoBlock);
|
||||
}
|
||||
case 'i': {
|
||||
struct ProductInformationBlock infoBlock;
|
||||
infoBlock.MARChannelID = MARChannelID;
|
||||
infoBlock.productVersion = productVersion;
|
||||
return refresh_product_info_block(argv[2], &infoBlock);
|
||||
}
|
||||
case 'T': {
|
||||
struct ProductInformationBlock infoBlock;
|
||||
uint32_t numSignatures, numAdditionalBlocks;
|
||||
int hasSignatureBlock, hasAdditionalBlock;
|
||||
if (!get_mar_file_info(argv[2], &hasSignatureBlock, &numSignatures,
|
||||
&hasAdditionalBlock, NULL, &numAdditionalBlocks)) {
|
||||
if (hasSignatureBlock) {
|
||||
printf("Signature block found with %d signature%s\n", numSignatures,
|
||||
numSignatures != 1 ? "s" : "");
|
||||
}
|
||||
if (hasAdditionalBlock) {
|
||||
printf("%d additional block%s found:\n", numAdditionalBlocks,
|
||||
numAdditionalBlocks != 1 ? "s" : "");
|
||||
}
|
||||
|
||||
rv = read_product_info_block(argv[2], &infoBlock);
|
||||
if (!rv) {
|
||||
printf(" - Product Information Block:\n");
|
||||
printf(" - MAR channel name: %s\n"
|
||||
" - Product version: %s\n",
|
||||
infoBlock.MARChannelID,
|
||||
infoBlock.productVersion);
|
||||
free((void *)infoBlock.MARChannelID);
|
||||
free((void *)infoBlock.productVersion);
|
||||
rv = read_product_info_block(argv[2], &infoBlock);
|
||||
if (!rv) {
|
||||
printf(" - Product Information Block:\n");
|
||||
printf(
|
||||
" - MAR channel name: %s\n"
|
||||
" - Product version: %s\n",
|
||||
infoBlock.MARChannelID, infoBlock.productVersion);
|
||||
free((void *)infoBlock.MARChannelID);
|
||||
free((void *)infoBlock.productVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
/* The fall through from 'T' to 't' is intentional */
|
||||
}
|
||||
case 't':
|
||||
return mar_test(argv[2]);
|
||||
printf("\n");
|
||||
/* The fall through from 'T' to 't' is intentional */
|
||||
}
|
||||
case 't':
|
||||
return mar_test(argv[2]);
|
||||
|
||||
/* Extract a MAR file */
|
||||
case 'x':
|
||||
return mar_extract(argv[2]);
|
||||
case 'x': // Extract a MAR file
|
||||
return mar_extract(argv[2]);
|
||||
|
||||
#ifndef NO_SIGN_VERIFY
|
||||
/* Extract a MAR signature */
|
||||
case 'X':
|
||||
if (sigIndex == -1) {
|
||||
fprintf(stderr, "ERROR: Signature index was not passed.\n");
|
||||
return -1;
|
||||
}
|
||||
if (sigIndex >= MAX_SIGNATURES || sigIndex < -1) {
|
||||
fprintf(stderr, "ERROR: Signature index is out of range: %d.\n",
|
||||
sigIndex);
|
||||
return -1;
|
||||
}
|
||||
return extract_signature(argv[2], sigIndex, argv[3]);
|
||||
case 'X': // Extract a MAR signature
|
||||
if (sigIndex == -1) {
|
||||
fprintf(stderr, "ERROR: Signature index was not passed.\n");
|
||||
return -1;
|
||||
}
|
||||
if (sigIndex >= MAX_SIGNATURES || sigIndex < -1) {
|
||||
fprintf(stderr, "ERROR: Signature index is out of range: %d.\n",
|
||||
sigIndex);
|
||||
return -1;
|
||||
}
|
||||
return extract_signature(argv[2], sigIndex, argv[3]);
|
||||
|
||||
/* Import a MAR signature */
|
||||
case 'I':
|
||||
if (sigIndex == -1) {
|
||||
fprintf(stderr, "ERROR: signature index was not passed.\n");
|
||||
return -1;
|
||||
}
|
||||
if (sigIndex >= MAX_SIGNATURES || sigIndex < -1) {
|
||||
fprintf(stderr, "ERROR: Signature index is out of range: %d.\n",
|
||||
sigIndex);
|
||||
return -1;
|
||||
}
|
||||
if (argc < 5) {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
return import_signature(argv[2], sigIndex, argv[3], argv[4]);
|
||||
case 'I': // Import a MAR signature
|
||||
if (sigIndex == -1) {
|
||||
fprintf(stderr, "ERROR: signature index was not passed.\n");
|
||||
return -1;
|
||||
}
|
||||
if (sigIndex >= MAX_SIGNATURES || sigIndex < -1) {
|
||||
fprintf(stderr, "ERROR: Signature index is out of range: %d.\n",
|
||||
sigIndex);
|
||||
return -1;
|
||||
}
|
||||
if (argc < 5) {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
return import_signature(argv[2], sigIndex, argv[3], argv[4]);
|
||||
|
||||
case 'v':
|
||||
if (certCount == 0) {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
case 'v':
|
||||
if (certCount == 0) {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if (!defined(XP_WIN) && !defined(XP_MACOSX)) || defined(MAR_NSS)
|
||||
if (!NSSConfigDir || certCount == 0) {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
if (!NSSConfigDir || certCount == 0) {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NSSInitCryptoContext(NSSConfigDir)) {
|
||||
fprintf(stderr, "ERROR: Could not initialize crypto library.\n");
|
||||
return -1;
|
||||
}
|
||||
if (NSSInitCryptoContext(NSSConfigDir)) {
|
||||
fprintf(stderr, "ERROR: Could not initialize crypto library.\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = 0;
|
||||
for (k = 0; k < certCount; ++k) {
|
||||
rv = 0;
|
||||
for (k = 0; k < certCount; ++k) {
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && !defined(MAR_NSS)
|
||||
rv = mar_read_entire_file(DERFilePaths[k], MAR_MAX_CERT_SIZE,
|
||||
&certBuffers[k], &fileSizes[k]);
|
||||
rv = mar_read_entire_file(DERFilePaths[k], MAR_MAX_CERT_SIZE,
|
||||
&certBuffers[k], &fileSizes[k]);
|
||||
|
||||
if (rv) {
|
||||
fprintf(stderr, "ERROR: could not read file %s", DERFilePaths[k]);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
/* It is somewhat circuitous to look up a CERTCertificate and then pass
|
||||
* in its DER encoding just so we can later re-create that
|
||||
* CERTCertificate to extract the public key out of it. However, by
|
||||
* doing things this way, we maximize the reuse of the
|
||||
* mar_verify_signatures function and also we keep the control flow as
|
||||
* similar as possible between programs and operating systems, at least
|
||||
* for the functions that are critically important to security.
|
||||
*/
|
||||
certs[k] = PK11_FindCertFromNickname(certNames[k], NULL);
|
||||
if (certs[k]) {
|
||||
certBuffers[k] = certs[k]->derCert.data;
|
||||
fileSizes[k] = certs[k]->derCert.len;
|
||||
} else {
|
||||
rv = -1;
|
||||
fprintf(stderr, "ERROR: could not find cert from nickname %s",
|
||||
certNames[k]);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!rv) {
|
||||
MarFile *mar = mar_open(argv[2]);
|
||||
if (mar) {
|
||||
rv = mar_verify_signatures(mar, certBuffers, fileSizes, certCount);
|
||||
mar_close(mar);
|
||||
} else {
|
||||
fprintf(stderr, "ERROR: Could not open MAR file.\n");
|
||||
rv = -1;
|
||||
}
|
||||
}
|
||||
for (k = 0; k < certCount; ++k) {
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && !defined(MAR_NSS)
|
||||
free((void *)certBuffers[k]);
|
||||
#else
|
||||
/* certBuffers[k] is owned by certs[k] so don't free it */
|
||||
CERT_DestroyCertificate(certs[k]);
|
||||
#endif
|
||||
}
|
||||
if (rv) {
|
||||
fprintf(stderr, "ERROR: could not read file %s", DERFilePaths[k]);
|
||||
break;
|
||||
/* Determine if the source MAR file has the new fields for signing */
|
||||
int hasSignatureBlock;
|
||||
if (get_mar_file_info(argv[2], &hasSignatureBlock, NULL, NULL, NULL,
|
||||
NULL)) {
|
||||
fprintf(stderr, "ERROR: could not determine if MAR is old or new.\n");
|
||||
} else if (!hasSignatureBlock) {
|
||||
fprintf(stderr,
|
||||
"ERROR: The MAR file is in the old format so has"
|
||||
" no signature to verify.\n");
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* It is somewhat circuitous to look up a CERTCertificate and then pass
|
||||
* in its DER encoding just so we can later re-create that
|
||||
* CERTCertificate to extract the public key out of it. However, by doing
|
||||
* things this way, we maximize the reuse of the mar_verify_signatures
|
||||
* function and also we keep the control flow as similar as possible
|
||||
* between programs and operating systems, at least for the functions
|
||||
* that are critically important to security.
|
||||
*/
|
||||
certs[k] = PK11_FindCertFromNickname(certNames[k], NULL);
|
||||
if (certs[k]) {
|
||||
certBuffers[k] = certs[k]->derCert.data;
|
||||
fileSizes[k] = certs[k]->derCert.len;
|
||||
} else {
|
||||
rv = -1;
|
||||
fprintf(stderr, "ERROR: could not find cert from nickname %s", certNames[k]);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!rv) {
|
||||
MarFile *mar = mar_open(argv[2]);
|
||||
if (mar) {
|
||||
rv = mar_verify_signatures(mar, certBuffers, fileSizes, certCount);
|
||||
mar_close(mar);
|
||||
} else {
|
||||
fprintf(stderr, "ERROR: Could not open MAR file.\n");
|
||||
rv = -1;
|
||||
}
|
||||
}
|
||||
for (k = 0; k < certCount; ++k) {
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && !defined(MAR_NSS)
|
||||
free((void*)certBuffers[k]);
|
||||
#else
|
||||
/* certBuffers[k] is owned by certs[k] so don't free it */
|
||||
CERT_DestroyCertificate(certs[k]);
|
||||
#endif
|
||||
}
|
||||
if (rv) {
|
||||
/* Determine if the source MAR file has the new fields for signing */
|
||||
int hasSignatureBlock;
|
||||
if (get_mar_file_info(argv[2], &hasSignatureBlock,
|
||||
NULL, NULL, NULL, NULL)) {
|
||||
fprintf(stderr, "ERROR: could not determine if MAR is old or new.\n");
|
||||
} else if (!hasSignatureBlock) {
|
||||
fprintf(stderr, "ERROR: The MAR file is in the old format so has"
|
||||
" no signature to verify.\n");
|
||||
}
|
||||
}
|
||||
#if (!defined(XP_WIN) && !defined(XP_MACOSX)) || defined(MAR_NSS)
|
||||
(void) NSS_Shutdown();
|
||||
(void)NSS_Shutdown();
|
||||
#endif
|
||||
return rv ? -1 : 0;
|
||||
return rv ? -1 : 0;
|
||||
|
||||
case 's':
|
||||
if (!NSSConfigDir || certCount == 0 || argc < 4) {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
return mar_repackage_and_sign(NSSConfigDir, certNames, certCount,
|
||||
argv[2], argv[3]);
|
||||
case 's':
|
||||
if (!NSSConfigDir || certCount == 0 || argc < 4) {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
return mar_repackage_and_sign(NSSConfigDir, certNames, certCount, argv[2],
|
||||
argv[3]);
|
||||
|
||||
case 'r':
|
||||
return strip_signature_block(argv[2], argv[3]);
|
||||
case 'r':
|
||||
return strip_signature_block(argv[2], argv[3]);
|
||||
#endif /* endif NO_SIGN_VERIFY disabled */
|
||||
|
||||
default:
|
||||
print_usage();
|
||||
return -1;
|
||||
default:
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,65 +11,60 @@
|
|||
// We declare the necessary parts of the Security Transforms API here since
|
||||
// we're building with the 10.6 SDK, which doesn't know about Security
|
||||
// Transforms.
|
||||
#ifdef __cplusplus
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
const CFStringRef kSecTransformInputAttributeName = CFSTR("INPUT");
|
||||
typedef CFTypeRef SecTransformRef;
|
||||
typedef struct OpaqueSecKeyRef* SecKeyRef;
|
||||
const CFStringRef kSecTransformInputAttributeName = CFSTR("INPUT");
|
||||
typedef CFTypeRef SecTransformRef;
|
||||
typedef struct OpaqueSecKeyRef* SecKeyRef;
|
||||
|
||||
typedef SecTransformRef (*SecTransformCreateReadTransformWithReadStreamFunc)
|
||||
(CFReadStreamRef inputStream);
|
||||
SecTransformCreateReadTransformWithReadStreamFunc
|
||||
typedef SecTransformRef (*SecTransformCreateReadTransformWithReadStreamFunc)(
|
||||
CFReadStreamRef inputStream);
|
||||
SecTransformCreateReadTransformWithReadStreamFunc
|
||||
SecTransformCreateReadTransformWithReadStreamPtr = NULL;
|
||||
typedef CFTypeRef (*SecTransformExecuteFunc)(SecTransformRef transform,
|
||||
CFErrorRef* error);
|
||||
SecTransformExecuteFunc SecTransformExecutePtr = NULL;
|
||||
typedef SecTransformRef (*SecVerifyTransformCreateFunc)(SecKeyRef key,
|
||||
CFDataRef signature,
|
||||
CFErrorRef* error);
|
||||
SecVerifyTransformCreateFunc SecVerifyTransformCreatePtr = NULL;
|
||||
typedef Boolean (*SecTransformSetAttributeFunc)(SecTransformRef transform,
|
||||
CFStringRef key,
|
||||
CFTypeRef value,
|
||||
CFErrorRef* error);
|
||||
SecTransformSetAttributeFunc SecTransformSetAttributePtr = NULL;
|
||||
#ifdef __cplusplus
|
||||
typedef CFTypeRef (*SecTransformExecuteFunc)(SecTransformRef transform,
|
||||
CFErrorRef* error);
|
||||
SecTransformExecuteFunc SecTransformExecutePtr = NULL;
|
||||
typedef SecTransformRef (*SecVerifyTransformCreateFunc)(SecKeyRef key,
|
||||
CFDataRef signature,
|
||||
CFErrorRef* error);
|
||||
SecVerifyTransformCreateFunc SecVerifyTransformCreatePtr = NULL;
|
||||
typedef Boolean (*SecTransformSetAttributeFunc)(SecTransformRef transform,
|
||||
CFStringRef key,
|
||||
CFTypeRef value,
|
||||
CFErrorRef* error);
|
||||
SecTransformSetAttributeFunc SecTransformSetAttributePtr = NULL;
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
CryptoX_Result
|
||||
CryptoMac_InitCryptoProvider()
|
||||
{
|
||||
CryptoX_Result CryptoMac_InitCryptoProvider() {
|
||||
if (!SecTransformCreateReadTransformWithReadStreamPtr) {
|
||||
SecTransformCreateReadTransformWithReadStreamPtr =
|
||||
(SecTransformCreateReadTransformWithReadStreamFunc)
|
||||
dlsym(RTLD_DEFAULT, "SecTransformCreateReadTransformWithReadStream");
|
||||
(SecTransformCreateReadTransformWithReadStreamFunc)dlsym(
|
||||
RTLD_DEFAULT, "SecTransformCreateReadTransformWithReadStream");
|
||||
}
|
||||
if (!SecTransformExecutePtr) {
|
||||
SecTransformExecutePtr = (SecTransformExecuteFunc)
|
||||
dlsym(RTLD_DEFAULT, "SecTransformExecute");
|
||||
SecTransformExecutePtr =
|
||||
(SecTransformExecuteFunc)dlsym(RTLD_DEFAULT, "SecTransformExecute");
|
||||
}
|
||||
if (!SecVerifyTransformCreatePtr) {
|
||||
SecVerifyTransformCreatePtr = (SecVerifyTransformCreateFunc)
|
||||
dlsym(RTLD_DEFAULT, "SecVerifyTransformCreate");
|
||||
SecVerifyTransformCreatePtr = (SecVerifyTransformCreateFunc)dlsym(
|
||||
RTLD_DEFAULT, "SecVerifyTransformCreate");
|
||||
}
|
||||
if (!SecTransformSetAttributePtr) {
|
||||
SecTransformSetAttributePtr = (SecTransformSetAttributeFunc)
|
||||
dlsym(RTLD_DEFAULT, "SecTransformSetAttribute");
|
||||
SecTransformSetAttributePtr = (SecTransformSetAttributeFunc)dlsym(
|
||||
RTLD_DEFAULT, "SecTransformSetAttribute");
|
||||
}
|
||||
if (!SecTransformCreateReadTransformWithReadStreamPtr ||
|
||||
!SecTransformExecutePtr ||
|
||||
!SecVerifyTransformCreatePtr ||
|
||||
!SecTransformExecutePtr || !SecVerifyTransformCreatePtr ||
|
||||
!SecTransformSetAttributePtr) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
return CryptoX_Success;
|
||||
}
|
||||
|
||||
CryptoX_Result
|
||||
CryptoMac_VerifyBegin(CryptoX_SignatureHandle* aInputData)
|
||||
{
|
||||
CryptoX_Result CryptoMac_VerifyBegin(CryptoX_SignatureHandle* aInputData) {
|
||||
if (!aInputData) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
@ -83,10 +78,8 @@ CryptoMac_VerifyBegin(CryptoX_SignatureHandle* aInputData)
|
|||
return CryptoX_Success;
|
||||
}
|
||||
|
||||
CryptoX_Result
|
||||
CryptoMac_VerifyUpdate(CryptoX_SignatureHandle* aInputData, void* aBuf,
|
||||
unsigned int aLen)
|
||||
{
|
||||
CryptoX_Result CryptoMac_VerifyUpdate(CryptoX_SignatureHandle* aInputData,
|
||||
void* aBuf, unsigned int aLen) {
|
||||
if (aLen == 0) {
|
||||
return CryptoX_Success;
|
||||
}
|
||||
|
@ -100,31 +93,26 @@ CryptoMac_VerifyUpdate(CryptoX_SignatureHandle* aInputData, void* aBuf,
|
|||
return CryptoX_Success;
|
||||
}
|
||||
|
||||
CryptoX_Result
|
||||
CryptoMac_LoadPublicKey(const unsigned char* aCertData,
|
||||
unsigned int aDataSize,
|
||||
CryptoX_PublicKey* aPublicKey)
|
||||
{
|
||||
CryptoX_Result CryptoMac_LoadPublicKey(const unsigned char* aCertData,
|
||||
unsigned int aDataSize,
|
||||
CryptoX_PublicKey* aPublicKey) {
|
||||
if (!aCertData || aDataSize == 0 || !aPublicKey) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
*aPublicKey = NULL;
|
||||
CFDataRef certData = CFDataCreate(kCFAllocatorDefault,
|
||||
aCertData,
|
||||
aDataSize);
|
||||
CFDataRef certData = CFDataCreate(kCFAllocatorDefault, aCertData, aDataSize);
|
||||
if (!certData) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault,
|
||||
certData);
|
||||
SecCertificateRef cert =
|
||||
SecCertificateCreateWithData(kCFAllocatorDefault, certData);
|
||||
CFRelease(certData);
|
||||
if (!cert) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
OSStatus status = SecCertificateCopyPublicKey(cert,
|
||||
(SecKeyRef*)aPublicKey);
|
||||
OSStatus status = SecCertificateCopyPublicKey(cert, (SecKeyRef*)aPublicKey);
|
||||
CFRelease(cert);
|
||||
if (status != 0) {
|
||||
return CryptoX_Error;
|
||||
|
@ -133,28 +121,24 @@ CryptoMac_LoadPublicKey(const unsigned char* aCertData,
|
|||
return CryptoX_Success;
|
||||
}
|
||||
|
||||
CryptoX_Result
|
||||
CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData,
|
||||
CryptoX_PublicKey* aPublicKey,
|
||||
const unsigned char* aSignature,
|
||||
unsigned int aSignatureLen)
|
||||
{
|
||||
CryptoX_Result CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData,
|
||||
CryptoX_PublicKey* aPublicKey,
|
||||
const unsigned char* aSignature,
|
||||
unsigned int aSignatureLen) {
|
||||
if (!aInputData || !*aInputData || !aPublicKey || !*aPublicKey ||
|
||||
!aSignature || aSignatureLen == 0) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
CFDataRef signatureData = CFDataCreate(kCFAllocatorDefault,
|
||||
aSignature, aSignatureLen);
|
||||
CFDataRef signatureData =
|
||||
CFDataCreate(kCFAllocatorDefault, aSignature, aSignatureLen);
|
||||
if (!signatureData) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
CFErrorRef error;
|
||||
SecTransformRef verifier =
|
||||
SecVerifyTransformCreatePtr((SecKeyRef)*aPublicKey,
|
||||
signatureData,
|
||||
&error);
|
||||
SecTransformRef verifier = SecVerifyTransformCreatePtr((SecKeyRef)*aPublicKey,
|
||||
signatureData, &error);
|
||||
if (!verifier || error) {
|
||||
if (error) {
|
||||
CFRelease(error);
|
||||
|
@ -163,9 +147,7 @@ CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData,
|
|||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
SecTransformSetAttributePtr(verifier,
|
||||
kSecDigestTypeAttribute,
|
||||
kSecDigestSHA2,
|
||||
SecTransformSetAttributePtr(verifier, kSecDigestTypeAttribute, kSecDigestSHA2,
|
||||
&error);
|
||||
if (error) {
|
||||
CFRelease(error);
|
||||
|
@ -175,10 +157,9 @@ CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData,
|
|||
}
|
||||
|
||||
int digestLength = 384;
|
||||
CFNumberRef dLen = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &digestLength);
|
||||
SecTransformSetAttributePtr(verifier,
|
||||
kSecDigestLengthAttribute,
|
||||
dLen,
|
||||
CFNumberRef dLen =
|
||||
CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &digestLength);
|
||||
SecTransformSetAttributePtr(verifier, kSecDigestLengthAttribute, dLen,
|
||||
&error);
|
||||
CFRelease(dLen);
|
||||
if (error) {
|
||||
|
@ -188,10 +169,8 @@ CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData,
|
|||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
SecTransformSetAttributePtr(verifier,
|
||||
kSecTransformInputAttributeName,
|
||||
(CFDataRef)*aInputData,
|
||||
&error);
|
||||
SecTransformSetAttributePtr(verifier, kSecTransformInputAttributeName,
|
||||
(CFDataRef)*aInputData, &error);
|
||||
if (error) {
|
||||
CFRelease(error);
|
||||
CFRelease(signatureData);
|
||||
|
@ -219,9 +198,7 @@ CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData,
|
|||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
CryptoMac_FreeSignatureHandle(CryptoX_SignatureHandle* aInputData)
|
||||
{
|
||||
void CryptoMac_FreeSignatureHandle(CryptoX_SignatureHandle* aInputData) {
|
||||
if (!aInputData || !*aInputData) {
|
||||
return;
|
||||
}
|
||||
|
@ -232,9 +209,7 @@ CryptoMac_FreeSignatureHandle(CryptoX_SignatureHandle* aInputData)
|
|||
CFRelease(inputData);
|
||||
}
|
||||
|
||||
void
|
||||
CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey)
|
||||
{
|
||||
void CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey) {
|
||||
if (!aPublicKey || !*aPublicKey) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -21,13 +21,12 @@
|
|||
* @param certDataSize The size of certData.
|
||||
* @param publicKey Out parameter for the public key to use.
|
||||
* @return CryptoX_Success on success, CryptoX_Error on error.
|
||||
*/
|
||||
CryptoX_Result
|
||||
NSS_LoadPublicKey(const unsigned char *certData, unsigned int certDataSize,
|
||||
SECKEYPublicKey **publicKey)
|
||||
{
|
||||
CERTCertificate * cert;
|
||||
SECItem certDataItem = { siBuffer, (unsigned char*) certData, certDataSize };
|
||||
*/
|
||||
CryptoX_Result NSS_LoadPublicKey(const unsigned char *certData,
|
||||
unsigned int certDataSize,
|
||||
SECKEYPublicKey **publicKey) {
|
||||
CERTCertificate *cert;
|
||||
SECItem certDataItem = {siBuffer, (unsigned char *)certData, certDataSize};
|
||||
|
||||
if (!certData || !publicKey) {
|
||||
return CryptoX_Error;
|
||||
|
@ -48,10 +47,8 @@ NSS_LoadPublicKey(const unsigned char *certData, unsigned int certDataSize,
|
|||
return CryptoX_Success;
|
||||
}
|
||||
|
||||
CryptoX_Result
|
||||
NSS_VerifyBegin(VFYContext **ctx,
|
||||
SECKEYPublicKey * const *publicKey)
|
||||
{
|
||||
CryptoX_Result NSS_VerifyBegin(VFYContext **ctx,
|
||||
SECKEYPublicKey *const *publicKey) {
|
||||
SECStatus status;
|
||||
if (!ctx || !publicKey || !*publicKey) {
|
||||
return CryptoX_Error;
|
||||
|
@ -82,12 +79,10 @@ NSS_VerifyBegin(VFYContext **ctx,
|
|||
* @param signature The signature to match.
|
||||
* @param signatureLen The length of the signature.
|
||||
* @return CryptoX_Success on success, CryptoX_Error on error.
|
||||
*/
|
||||
CryptoX_Result
|
||||
NSS_VerifySignature(VFYContext * const *ctx,
|
||||
const unsigned char *signature,
|
||||
unsigned int signatureLen)
|
||||
{
|
||||
*/
|
||||
CryptoX_Result NSS_VerifySignature(VFYContext *const *ctx,
|
||||
const unsigned char *signature,
|
||||
unsigned int signatureLen) {
|
||||
SECItem signedItem;
|
||||
SECStatus status;
|
||||
if (!ctx || !signature || !*ctx) {
|
||||
|
@ -95,7 +90,7 @@ NSS_VerifySignature(VFYContext * const *ctx,
|
|||
}
|
||||
|
||||
signedItem.len = signatureLen;
|
||||
signedItem.data = (unsigned char*)signature;
|
||||
signedItem.data = (unsigned char *)signature;
|
||||
status = VFY_EndWithSignature(*ctx, &signedItem);
|
||||
return SECSuccess == status ? CryptoX_Success : CryptoX_Error;
|
||||
}
|
||||
|
@ -109,19 +104,16 @@ NSS_VerifySignature(VFYContext * const *ctx,
|
|||
* @param signature The signature to check.
|
||||
* @param signatureLen The length of the signature.
|
||||
* @return CryptoX_Success on success, CryptoX_Error on error.
|
||||
*/
|
||||
CryptoX_Result
|
||||
CryptoAPI_VerifySignature(HCRYPTHASH *hash,
|
||||
HCRYPTKEY *pubKey,
|
||||
const BYTE *signature,
|
||||
DWORD signatureLen)
|
||||
{
|
||||
*/
|
||||
CryptoX_Result CryptoAPI_VerifySignature(HCRYPTHASH *hash, HCRYPTKEY *pubKey,
|
||||
const BYTE *signature,
|
||||
DWORD signatureLen) {
|
||||
DWORD i;
|
||||
BOOL result;
|
||||
/* Windows APIs expect the bytes in the signature to be in little-endian
|
||||
* order, but we write the signature in big-endian order. Other APIs like
|
||||
* NSS and OpenSSL expect big-endian order.
|
||||
*/
|
||||
/* Windows APIs expect the bytes in the signature to be in little-endian
|
||||
* order, but we write the signature in big-endian order. Other APIs like
|
||||
* NSS and OpenSSL expect big-endian order.
|
||||
*/
|
||||
BYTE *signatureReversed;
|
||||
if (!hash || !pubKey || !signature || signatureLen < 1) {
|
||||
return CryptoX_Error;
|
||||
|
@ -135,8 +127,8 @@ CryptoAPI_VerifySignature(HCRYPTHASH *hash,
|
|||
for (i = 0; i < signatureLen; i++) {
|
||||
signatureReversed[i] = signature[signatureLen - 1 - i];
|
||||
}
|
||||
result = CryptVerifySignature(*hash, signatureReversed,
|
||||
signatureLen, *pubKey, NULL, 0);
|
||||
result = CryptVerifySignature(*hash, signatureReversed, signatureLen, *pubKey,
|
||||
NULL, 0);
|
||||
free(signatureReversed);
|
||||
return result ? CryptoX_Success : CryptoX_Error;
|
||||
}
|
||||
|
@ -149,13 +141,10 @@ CryptoAPI_VerifySignature(HCRYPTHASH *hash,
|
|||
* @param sizeOfCertData The size of the certData buffer
|
||||
* @param certStore Pointer to the handle of the certificate store to use
|
||||
* @param CryptoX_Success on success
|
||||
*/
|
||||
CryptoX_Result
|
||||
CryptoAPI_LoadPublicKey(HCRYPTPROV provider,
|
||||
BYTE *certData,
|
||||
DWORD sizeOfCertData,
|
||||
HCRYPTKEY *publicKey)
|
||||
{
|
||||
*/
|
||||
CryptoX_Result CryptoAPI_LoadPublicKey(HCRYPTPROV provider, BYTE *certData,
|
||||
DWORD sizeOfCertData,
|
||||
HCRYPTKEY *publicKey) {
|
||||
CRYPT_DATA_BLOB blob;
|
||||
CERT_CONTEXT *context;
|
||||
if (!provider || !certData || !publicKey) {
|
||||
|
@ -166,16 +155,14 @@ CryptoAPI_LoadPublicKey(HCRYPTPROV provider,
|
|||
blob.pbData = certData;
|
||||
if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
||||
CERT_QUERY_CONTENT_FLAG_CERT,
|
||||
CERT_QUERY_FORMAT_FLAG_BINARY,
|
||||
0, NULL, NULL, NULL,
|
||||
CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL,
|
||||
NULL, NULL, (const void **)&context)) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
if (!CryptImportPublicKeyInfo(provider,
|
||||
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
|
||||
&context->pCertInfo->SubjectPublicKeyInfo,
|
||||
publicKey)) {
|
||||
if (!CryptImportPublicKeyInfo(
|
||||
provider, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
|
||||
&context->pCertInfo->SubjectPublicKeyInfo, publicKey)) {
|
||||
CertFreeCertificateContext(context);
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
@ -185,38 +172,24 @@ CryptoAPI_LoadPublicKey(HCRYPTPROV provider,
|
|||
}
|
||||
|
||||
/* Try to acquire context in this way:
|
||||
* 1. Enhanced provider without creating a new key set
|
||||
* 2. Enhanced provider with creating a new key set
|
||||
* 3. Default provider without creating a new key set
|
||||
* 4. Default provider without creating a new key set
|
||||
* #2 and #4 should not be needed because of the CRYPT_VERIFYCONTEXT,
|
||||
* but we add it just in case.
|
||||
*
|
||||
* @param provider Out parameter containing the provider handle.
|
||||
* @return CryptoX_Success on success, CryptoX_Error on error.
|
||||
* 1. Enhanced provider without creating a new key set
|
||||
* 2. Enhanced provider with creating a new key set
|
||||
* 3. Default provider without creating a new key set
|
||||
* 4. Default provider without creating a new key set
|
||||
* #2 and #4 should not be needed because of the CRYPT_VERIFYCONTEXT,
|
||||
* but we add it just in case.
|
||||
*
|
||||
* @param provider Out parameter containing the provider handle.
|
||||
* @return CryptoX_Success on success, CryptoX_Error on error.
|
||||
*/
|
||||
CryptoX_Result
|
||||
CryptoAPI_InitCryptoContext(HCRYPTPROV *provider)
|
||||
{
|
||||
if (!CryptAcquireContext(provider,
|
||||
NULL,
|
||||
MS_ENH_RSA_AES_PROV,
|
||||
PROV_RSA_AES,
|
||||
CryptoX_Result CryptoAPI_InitCryptoContext(HCRYPTPROV *provider) {
|
||||
if (!CryptAcquireContext(provider, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES,
|
||||
CRYPT_VERIFYCONTEXT)) {
|
||||
if (!CryptAcquireContext(provider,
|
||||
NULL,
|
||||
MS_ENH_RSA_AES_PROV,
|
||||
PROV_RSA_AES,
|
||||
if (!CryptAcquireContext(provider, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES,
|
||||
CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT)) {
|
||||
if (!CryptAcquireContext(provider,
|
||||
NULL,
|
||||
NULL,
|
||||
PROV_RSA_AES,
|
||||
if (!CryptAcquireContext(provider, NULL, NULL, PROV_RSA_AES,
|
||||
CRYPT_VERIFYCONTEXT)) {
|
||||
if (!CryptAcquireContext(provider,
|
||||
NULL,
|
||||
NULL,
|
||||
PROV_RSA_AES,
|
||||
if (!CryptAcquireContext(provider, NULL, NULL, PROV_RSA_AES,
|
||||
CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT)) {
|
||||
*provider = CryptoX_InvalidHandleValue;
|
||||
return CryptoX_Error;
|
||||
|
@ -228,37 +201,32 @@ CryptoAPI_InitCryptoContext(HCRYPTPROV *provider)
|
|||
}
|
||||
|
||||
/**
|
||||
* Begins a signature verification hash context
|
||||
*
|
||||
* @param provider The crypt provider to use
|
||||
* @param hash Out parameter for a handle to the hash context
|
||||
* @return CryptoX_Success on success, CryptoX_Error on error.
|
||||
*/
|
||||
CryptoX_Result
|
||||
CryptoAPI_VerifyBegin(HCRYPTPROV provider, HCRYPTHASH* hash)
|
||||
{
|
||||
* Begins a signature verification hash context
|
||||
*
|
||||
* @param provider The crypt provider to use
|
||||
* @param hash Out parameter for a handle to the hash context
|
||||
* @return CryptoX_Success on success, CryptoX_Error on error.
|
||||
*/
|
||||
CryptoX_Result CryptoAPI_VerifyBegin(HCRYPTPROV provider, HCRYPTHASH *hash) {
|
||||
BOOL result;
|
||||
if (!provider || !hash) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
*hash = (HCRYPTHASH)NULL;
|
||||
result = CryptCreateHash(provider, CALG_SHA_384,
|
||||
0, 0, hash);
|
||||
result = CryptCreateHash(provider, CALG_SHA_384, 0, 0, hash);
|
||||
return result ? CryptoX_Success : CryptoX_Error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a signature verification hash context
|
||||
*
|
||||
* @param hash The hash context to udpate
|
||||
* @param buf The buffer to update the hash context with
|
||||
* @param len The size of the passed in buffer
|
||||
* @return CryptoX_Success on success, CryptoX_Error on error.
|
||||
*/
|
||||
CryptoX_Result
|
||||
CryptoAPI_VerifyUpdate(HCRYPTHASH* hash, BYTE *buf, DWORD len)
|
||||
{
|
||||
* Updates a signature verification hash context
|
||||
*
|
||||
* @param hash The hash context to udpate
|
||||
* @param buf The buffer to update the hash context with
|
||||
* @param len The size of the passed in buffer
|
||||
* @return CryptoX_Success on success, CryptoX_Error on error.
|
||||
*/
|
||||
CryptoX_Result CryptoAPI_VerifyUpdate(HCRYPTHASH *hash, BYTE *buf, DWORD len) {
|
||||
BOOL result;
|
||||
if (!hash || !buf) {
|
||||
return CryptoX_Error;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "cryptohi.h"
|
||||
|
||||
#define CryptoX_InvalidHandleValue NULL
|
||||
#define CryptoX_ProviderHandle void*
|
||||
#define CryptoX_ProviderHandle void *
|
||||
#define CryptoX_SignatureHandle VFYContext *
|
||||
#define CryptoX_PublicKey SECKEYPublicKey *
|
||||
#define CryptoX_Certificate CERTCertificate *
|
||||
|
@ -28,42 +28,39 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
CryptoX_Result NSS_LoadPublicKey(const unsigned char* certData,
|
||||
CryptoX_Result NSS_LoadPublicKey(const unsigned char *certData,
|
||||
unsigned int certDataSize,
|
||||
SECKEYPublicKey** publicKey);
|
||||
SECKEYPublicKey **publicKey);
|
||||
CryptoX_Result NSS_VerifyBegin(VFYContext **ctx,
|
||||
SECKEYPublicKey * const *publicKey);
|
||||
CryptoX_Result NSS_VerifySignature(VFYContext * const *ctx ,
|
||||
SECKEYPublicKey *const *publicKey);
|
||||
CryptoX_Result NSS_VerifySignature(VFYContext *const *ctx,
|
||||
const unsigned char *signature,
|
||||
unsigned int signatureLen);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#define CryptoX_InitCryptoProvider(CryptoHandle) \
|
||||
CryptoX_Success
|
||||
#define CryptoX_InitCryptoProvider(CryptoHandle) CryptoX_Success
|
||||
#define CryptoX_VerifyBegin(CryptoHandle, SignatureHandle, PublicKey) \
|
||||
NSS_VerifyBegin(SignatureHandle, PublicKey)
|
||||
#define CryptoX_FreeSignatureHandle(SignatureHandle) \
|
||||
VFY_DestroyContext(*SignatureHandle, PR_TRUE)
|
||||
#define CryptoX_VerifyUpdate(SignatureHandle, buf, len) \
|
||||
VFY_Update(*SignatureHandle, (const unsigned char*)(buf), len)
|
||||
VFY_Update(*SignatureHandle, (const unsigned char *)(buf), len)
|
||||
#define CryptoX_LoadPublicKey(CryptoHandle, certData, dataSize, publicKey) \
|
||||
NSS_LoadPublicKey(certData, dataSize, publicKey)
|
||||
#define CryptoX_VerifySignature(hash, publicKey, signedData, len) \
|
||||
NSS_VerifySignature(hash, (const unsigned char *)(signedData), len)
|
||||
#define CryptoX_FreePublicKey(key) \
|
||||
SECKEY_DestroyPublicKey(*key)
|
||||
#define CryptoX_FreeCertificate(cert) \
|
||||
CERT_DestroyCertificate(*cert)
|
||||
#define CryptoX_FreePublicKey(key) SECKEY_DestroyPublicKey(*key)
|
||||
#define CryptoX_FreeCertificate(cert) CERT_DestroyCertificate(*cert)
|
||||
|
||||
#elif XP_MACOSX
|
||||
|
||||
#define CryptoX_InvalidHandleValue NULL
|
||||
#define CryptoX_ProviderHandle void*
|
||||
#define CryptoX_SignatureHandle void*
|
||||
#define CryptoX_PublicKey void*
|
||||
#define CryptoX_Certificate void*
|
||||
#define CryptoX_ProviderHandle void *
|
||||
#define CryptoX_SignatureHandle void *
|
||||
#define CryptoX_PublicKey void *
|
||||
#define CryptoX_Certificate void *
|
||||
|
||||
// Forward-declare Objective-C functions implemented in MacVerifyCrypto.mm.
|
||||
#ifdef __cplusplus
|
||||
|
@ -83,7 +80,7 @@ CryptoX_Result CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData,
|
|||
void CryptoMac_FreeSignatureHandle(CryptoX_SignatureHandle* aInputData);
|
||||
void CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#define CryptoX_InitCryptoProvider(aProviderHandle) \
|
||||
|
@ -93,15 +90,14 @@ void CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey);
|
|||
#define CryptoX_VerifyUpdate(aInputData, aBuf, aLen) \
|
||||
CryptoMac_VerifyUpdate(aInputData, aBuf, aLen)
|
||||
#define CryptoX_LoadPublicKey(aProviderHandle, aCertData, aDataSize, \
|
||||
aPublicKey) \
|
||||
aPublicKey) \
|
||||
CryptoMac_LoadPublicKey(aCertData, aDataSize, aPublicKey)
|
||||
#define CryptoX_VerifySignature(aInputData, aPublicKey, aSignature, \
|
||||
aSignatureLen) \
|
||||
aSignatureLen) \
|
||||
CryptoMac_VerifySignature(aInputData, aPublicKey, aSignature, aSignatureLen)
|
||||
#define CryptoX_FreeSignatureHandle(aInputData) \
|
||||
CryptoMac_FreeSignatureHandle(aInputData)
|
||||
#define CryptoX_FreePublicKey(aPublicKey) \
|
||||
CryptoMac_FreePublicKey(aPublicKey)
|
||||
#define CryptoX_FreePublicKey(aPublicKey) CryptoMac_FreePublicKey(aPublicKey)
|
||||
#define CryptoX_FreeCertificate(aCertificate)
|
||||
|
||||
#elif defined(XP_WIN)
|
||||
|
@ -110,15 +106,12 @@ void CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey);
|
|||
#include <wincrypt.h>
|
||||
|
||||
CryptoX_Result CryptoAPI_InitCryptoContext(HCRYPTPROV *provider);
|
||||
CryptoX_Result CryptoAPI_LoadPublicKey(HCRYPTPROV hProv,
|
||||
BYTE *certData,
|
||||
CryptoX_Result CryptoAPI_LoadPublicKey(HCRYPTPROV hProv, BYTE *certData,
|
||||
DWORD sizeOfCertData,
|
||||
HCRYPTKEY *publicKey);
|
||||
CryptoX_Result CryptoAPI_VerifyBegin(HCRYPTPROV provider, HCRYPTHASH* hash);
|
||||
CryptoX_Result CryptoAPI_VerifyUpdate(HCRYPTHASH* hash,
|
||||
BYTE *buf, DWORD len);
|
||||
CryptoX_Result CryptoAPI_VerifySignature(HCRYPTHASH *hash,
|
||||
HCRYPTKEY *pubKey,
|
||||
CryptoX_Result CryptoAPI_VerifyBegin(HCRYPTPROV provider, HCRYPTHASH *hash);
|
||||
CryptoX_Result CryptoAPI_VerifyUpdate(HCRYPTHASH *hash, BYTE *buf, DWORD len);
|
||||
CryptoX_Result CryptoAPI_VerifySignature(HCRYPTHASH *hash, HCRYPTKEY *pubKey,
|
||||
const BYTE *signature,
|
||||
DWORD signatureLen);
|
||||
|
||||
|
@ -135,11 +128,10 @@ CryptoX_Result CryptoAPI_VerifySignature(HCRYPTHASH *hash,
|
|||
#define CryptoX_VerifyUpdate(SignatureHandle, buf, len) \
|
||||
CryptoAPI_VerifyUpdate(SignatureHandle, (BYTE *)(buf), len)
|
||||
#define CryptoX_LoadPublicKey(CryptoHandle, certData, dataSize, publicKey) \
|
||||
CryptoAPI_LoadPublicKey(CryptoHandle, (BYTE*)(certData), dataSize, publicKey)
|
||||
CryptoAPI_LoadPublicKey(CryptoHandle, (BYTE *)(certData), dataSize, publicKey)
|
||||
#define CryptoX_VerifySignature(hash, publicKey, signedData, len) \
|
||||
CryptoAPI_VerifySignature(hash, publicKey, signedData, len)
|
||||
#define CryptoX_FreePublicKey(key) \
|
||||
CryptDestroyKey(*(key))
|
||||
#define CryptoX_FreePublicKey(key) CryptDestroyKey(*(key))
|
||||
#define CryptoX_FreeCertificate(cert) \
|
||||
CertCloseStore(*(cert), CERT_CLOSE_STORE_FORCE_FLAG);
|
||||
|
||||
|
@ -152,12 +144,11 @@ CryptoX_Result CryptoAPI_VerifySignature(HCRYPTHASH *hash,
|
|||
*/
|
||||
|
||||
#define CryptoX_InvalidHandleValue NULL
|
||||
#define CryptoX_ProviderHandle void*
|
||||
#define CryptoX_SignatureHandle void*
|
||||
#define CryptoX_PublicKey void*
|
||||
#define CryptoX_Certificate void*
|
||||
#define CryptoX_InitCryptoProvider(CryptoHandle) \
|
||||
CryptoX_Error
|
||||
#define CryptoX_ProviderHandle void *
|
||||
#define CryptoX_SignatureHandle void *
|
||||
#define CryptoX_PublicKey void *
|
||||
#define CryptoX_Certificate void *
|
||||
#define CryptoX_InitCryptoProvider(CryptoHandle) CryptoX_Error
|
||||
#define CryptoX_VerifyBegin(CryptoHandle, SignatureHandle, PublicKey) \
|
||||
CryptoX_Error
|
||||
#define CryptoX_FreeSignatureHandle(SignatureHandle)
|
||||
|
|
|
@ -17,13 +17,11 @@
|
|||
#include "mar.h"
|
||||
#include "cryptox.h"
|
||||
|
||||
int
|
||||
mar_read_entire_file(const char * filePath, uint32_t maxSize,
|
||||
/*out*/ const uint8_t * *data,
|
||||
/*out*/ uint32_t *size)
|
||||
{
|
||||
int mar_read_entire_file(const char *filePath, uint32_t maxSize,
|
||||
/*out*/ const uint8_t **data,
|
||||
/*out*/ uint32_t *size) {
|
||||
int result;
|
||||
FILE * f;
|
||||
FILE *f;
|
||||
|
||||
if (!filePath || !data || !size) {
|
||||
return -1;
|
||||
|
@ -38,9 +36,9 @@ mar_read_entire_file(const char * filePath, uint32_t maxSize,
|
|||
if (!fseeko(f, 0, SEEK_END)) {
|
||||
int64_t fileSize = ftello(f);
|
||||
if (fileSize > 0 && fileSize <= maxSize && !fseeko(f, 0, SEEK_SET)) {
|
||||
unsigned char * fileData;
|
||||
unsigned char *fileData;
|
||||
|
||||
*size = (unsigned int) fileSize;
|
||||
*size = (unsigned int)fileSize;
|
||||
fileData = malloc(*size);
|
||||
if (fileData) {
|
||||
if (fread(fileData, *size, 1, f) == 1) {
|
||||
|
@ -62,12 +60,10 @@ int mar_extract_and_verify_signatures_fp(FILE *fp,
|
|||
CryptoX_ProviderHandle provider,
|
||||
CryptoX_PublicKey *keys,
|
||||
uint32_t keyCount);
|
||||
int mar_verify_signatures_for_fp(FILE *fp,
|
||||
CryptoX_ProviderHandle provider,
|
||||
int mar_verify_signatures_for_fp(FILE *fp, CryptoX_ProviderHandle provider,
|
||||
CryptoX_PublicKey *keys,
|
||||
const uint8_t * const *extractedSignatures,
|
||||
uint32_t keyCount,
|
||||
uint32_t *numVerified);
|
||||
const uint8_t *const *extractedSignatures,
|
||||
uint32_t keyCount, uint32_t *numVerified);
|
||||
|
||||
/**
|
||||
* Reads the specified number of bytes from the file pointer and
|
||||
|
@ -83,15 +79,10 @@ int mar_verify_signatures_for_fp(FILE *fp,
|
|||
* @return 0 on success
|
||||
* -1 on read error
|
||||
* -2 on verify update error
|
||||
*/
|
||||
int
|
||||
ReadAndUpdateVerifyContext(FILE *fp,
|
||||
void *buffer,
|
||||
uint32_t size,
|
||||
CryptoX_SignatureHandle *ctxs,
|
||||
uint32_t count,
|
||||
const char *err)
|
||||
{
|
||||
*/
|
||||
int ReadAndUpdateVerifyContext(FILE *fp, void *buffer, uint32_t size,
|
||||
CryptoX_SignatureHandle *ctxs, uint32_t count,
|
||||
const char *err) {
|
||||
uint32_t k;
|
||||
if (!fp || !buffer || !ctxs || count == 0 || !err) {
|
||||
fprintf(stderr, "ERROR: Invalid parameter specified.\n");
|
||||
|
@ -130,12 +121,9 @@ ReadAndUpdateVerifyContext(FILE *fp,
|
|||
* the data stored
|
||||
* @param certCount The number of elements in certData and certDataSizes
|
||||
* @return 0 on success
|
||||
*/
|
||||
int
|
||||
mar_verify_signatures(MarFile *mar,
|
||||
const uint8_t * const *certData,
|
||||
const uint32_t *certDataSizes,
|
||||
uint32_t certCount) {
|
||||
*/
|
||||
int mar_verify_signatures(MarFile *mar, const uint8_t *const *certData,
|
||||
const uint32_t *certDataSizes, uint32_t certCount) {
|
||||
int rv = -1;
|
||||
CryptoX_ProviderHandle provider = CryptoX_InvalidHandleValue;
|
||||
CryptoX_PublicKey keys[MAX_SIGNATURES];
|
||||
|
@ -159,8 +147,8 @@ mar_verify_signatures(MarFile *mar,
|
|||
}
|
||||
|
||||
for (k = 0; k < certCount; ++k) {
|
||||
if (CryptoX_Failed(CryptoX_LoadPublicKey(provider, certData[k], certDataSizes[k],
|
||||
&keys[k]))) {
|
||||
if (CryptoX_Failed(CryptoX_LoadPublicKey(provider, certData[k],
|
||||
certDataSizes[k], &keys[k]))) {
|
||||
fprintf(stderr, "ERROR: Could not load public key.\n");
|
||||
goto failure;
|
||||
}
|
||||
|
@ -188,12 +176,11 @@ failure:
|
|||
* @param keys The public keys to use to verify the MAR
|
||||
* @param keyCount The number of keys pointed to by keys
|
||||
* @return 0 on success
|
||||
*/
|
||||
int
|
||||
mar_extract_and_verify_signatures_fp(FILE *fp,
|
||||
CryptoX_ProviderHandle provider,
|
||||
CryptoX_PublicKey *keys,
|
||||
uint32_t keyCount) {
|
||||
*/
|
||||
int mar_extract_and_verify_signatures_fp(FILE *fp,
|
||||
CryptoX_ProviderHandle provider,
|
||||
CryptoX_PublicKey *keys,
|
||||
uint32_t keyCount) {
|
||||
uint32_t signatureCount, signatureLen, numVerified = 0;
|
||||
uint32_t signatureAlgorithmIDs[MAX_SIGNATURES];
|
||||
uint8_t *extractedSignatures[MAX_SIGNATURES];
|
||||
|
@ -286,12 +273,9 @@ mar_extract_and_verify_signatures_fp(FILE *fp,
|
|||
if (ftello(fp) == -1) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
if (mar_verify_signatures_for_fp(fp,
|
||||
provider,
|
||||
keys,
|
||||
(const uint8_t * const *)extractedSignatures,
|
||||
signatureCount,
|
||||
&numVerified) == CryptoX_Error) {
|
||||
if (mar_verify_signatures_for_fp(
|
||||
fp, provider, keys, (const uint8_t *const *)extractedSignatures,
|
||||
signatureCount, &numVerified) == CryptoX_Error) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
for (i = 0; i < signatureCount; ++i) {
|
||||
|
@ -332,15 +316,12 @@ mar_extract_and_verify_signatures_fp(FILE *fp,
|
|||
* This information can be useful for printing
|
||||
* error messages.
|
||||
* @return 0 on success, *numVerified == signatureCount.
|
||||
*/
|
||||
int
|
||||
mar_verify_signatures_for_fp(FILE *fp,
|
||||
CryptoX_ProviderHandle provider,
|
||||
CryptoX_PublicKey *keys,
|
||||
const uint8_t * const *extractedSignatures,
|
||||
uint32_t signatureCount,
|
||||
uint32_t *numVerified)
|
||||
{
|
||||
*/
|
||||
int mar_verify_signatures_for_fp(FILE *fp, CryptoX_ProviderHandle provider,
|
||||
CryptoX_PublicKey *keys,
|
||||
const uint8_t *const *extractedSignatures,
|
||||
uint32_t signatureCount,
|
||||
uint32_t *numVerified) {
|
||||
CryptoX_SignatureHandle signatureHandles[MAX_SIGNATURES];
|
||||
char buf[BLOCKSIZE];
|
||||
uint32_t signatureLengths[MAX_SIGNATURES];
|
||||
|
@ -367,8 +348,8 @@ mar_verify_signatures_for_fp(FILE *fp,
|
|||
}
|
||||
|
||||
for (i = 0; i < signatureCount; i++) {
|
||||
if (CryptoX_Failed(CryptoX_VerifyBegin(provider,
|
||||
&signatureHandles[i], &keys[i]))) {
|
||||
if (CryptoX_Failed(
|
||||
CryptoX_VerifyBegin(provider, &signatureHandles[i], &keys[i]))) {
|
||||
fprintf(stderr, "ERROR: Could not initialize signature handle.\n");
|
||||
goto failure;
|
||||
}
|
||||
|
@ -384,33 +365,24 @@ mar_verify_signatures_for_fp(FILE *fp,
|
|||
Bytes 4-7: index offset
|
||||
Bytes 8-15: size of entire MAR
|
||||
*/
|
||||
if (CryptoX_Failed(ReadAndUpdateVerifyContext(fp, buf,
|
||||
SIGNATURE_BLOCK_OFFSET +
|
||||
sizeof(uint32_t),
|
||||
signatureHandles,
|
||||
signatureCount,
|
||||
"signature block"))) {
|
||||
if (CryptoX_Failed(ReadAndUpdateVerifyContext(
|
||||
fp, buf, SIGNATURE_BLOCK_OFFSET + sizeof(uint32_t), signatureHandles,
|
||||
signatureCount, "signature block"))) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Read the signature block */
|
||||
for (i = 0; i < signatureCount; i++) {
|
||||
/* Get the signature algorithm ID */
|
||||
if (CryptoX_Failed(ReadAndUpdateVerifyContext(fp,
|
||||
&buf,
|
||||
sizeof(uint32_t),
|
||||
signatureHandles,
|
||||
signatureCount,
|
||||
"signature algorithm ID"))) {
|
||||
if (CryptoX_Failed(ReadAndUpdateVerifyContext(
|
||||
fp, &buf, sizeof(uint32_t), signatureHandles, signatureCount,
|
||||
"signature algorithm ID"))) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (CryptoX_Failed(ReadAndUpdateVerifyContext(fp,
|
||||
&signatureLengths[i],
|
||||
sizeof(uint32_t),
|
||||
signatureHandles,
|
||||
signatureCount,
|
||||
"signature length"))) {
|
||||
if (CryptoX_Failed(ReadAndUpdateVerifyContext(
|
||||
fp, &signatureLengths[i], sizeof(uint32_t), signatureHandles,
|
||||
signatureCount, "signature length"))) {
|
||||
goto failure;
|
||||
}
|
||||
signatureLengths[i] = ntohl(signatureLengths[i]);
|
||||
|
@ -428,17 +400,18 @@ mar_verify_signatures_for_fp(FILE *fp,
|
|||
|
||||
/* Read the rest of the file after the signature block */
|
||||
while (!feof(fp)) {
|
||||
int numRead = fread(buf, 1, BLOCKSIZE , fp);
|
||||
int numRead = fread(buf, 1, BLOCKSIZE, fp);
|
||||
if (ferror(fp)) {
|
||||
fprintf(stderr, "ERROR: Error reading data block.\n");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
for (i = 0; i < signatureCount; i++) {
|
||||
if (CryptoX_Failed(CryptoX_VerifyUpdate(&signatureHandles[i],
|
||||
buf, numRead))) {
|
||||
fprintf(stderr, "ERROR: Error updating verify context with"
|
||||
" data block.\n");
|
||||
if (CryptoX_Failed(
|
||||
CryptoX_VerifyUpdate(&signatureHandles[i], buf, numRead))) {
|
||||
fprintf(stderr,
|
||||
"ERROR: Error updating verify context with"
|
||||
" data block.\n");
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
@ -446,8 +419,7 @@ mar_verify_signatures_for_fp(FILE *fp,
|
|||
|
||||
/* Verify the signatures */
|
||||
for (i = 0; i < signatureCount; i++) {
|
||||
if (CryptoX_Failed(CryptoX_VerifySignature(&signatureHandles[i],
|
||||
&keys[i],
|
||||
if (CryptoX_Failed(CryptoX_VerifySignature(&signatureHandles[i], &keys[i],
|
||||
extractedSignatures[i],
|
||||
signatureLengths[i]))) {
|
||||
fprintf(stderr, "ERROR: Error verifying signature.\n");
|
||||
|
|
|
@ -344,66 +344,6 @@ dnl Checks for programs.
|
|||
dnl ========================================================
|
||||
if test "$COMPILE_ENVIRONMENT"; then
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Mac OS X SDK support
|
||||
dnl ========================================================
|
||||
MACOS_SDK_DIR=
|
||||
MOZ_ARG_WITH_STRING(macos-sdk,
|
||||
[ --with-macos-sdk=dir Location of platform SDK to use (Mac OS X only)],
|
||||
MACOS_SDK_DIR=$withval)
|
||||
|
||||
MACOS_PRIVATE_FRAMEWORKS_DIR_DEFAULTED=
|
||||
MOZ_ARG_WITH_STRING(macos-private-frameworks,
|
||||
[ --with-macos-private-frameworks=dir Location of private frameworks to use (Mac OS X only)],
|
||||
MACOS_PRIVATE_FRAMEWORKS_DIR=$withval,
|
||||
MACOS_PRIVATE_FRAMEWORKS_DIR=/System/Library/PrivateFrameworks
|
||||
MACOS_PRIVATE_FRAMEWORKS_DEFAULTED=1)
|
||||
|
||||
if test -z "${MACOS_PRIVATE_FRAMEWORKS_DEFAULTED}"; then
|
||||
if test -z "$CROSS_COMPILE"; then
|
||||
AC_MSG_WARN([You should only be using --with-macos-private-frameworks when cross-compiling.])
|
||||
fi
|
||||
if test ! -d "$MACOS_PRIVATE_FRAMEWORKS_DIR"; then
|
||||
AC_MSG_ERROR([PrivateFrameworks directory not found.])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl MACOS_SDK_DIR will be set to the SDK location whenever one is in use.
|
||||
AC_SUBST(MACOS_SDK_DIR)
|
||||
AC_SUBST(MACOS_PRIVATE_FRAMEWORKS_DIR)
|
||||
|
||||
if test "$MACOS_SDK_DIR"; then
|
||||
dnl Sync this section with the ones in NSPR and NSS.
|
||||
dnl Changes to the cross environment here need to be accounted for in
|
||||
dnl the libIDL checks (below) and xpidl build.
|
||||
|
||||
if test ! -d "$MACOS_SDK_DIR"; then
|
||||
AC_MSG_ERROR([SDK not found. When using --with-macos-sdk, you must
|
||||
specify a valid SDK. SDKs are installed when the optional cross-development
|
||||
tools are selected during the Xcode/Developer Tools installation.])
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS -isysroot ${MACOS_SDK_DIR}"
|
||||
CXXFLAGS="$CXXFLAGS -isysroot ${MACOS_SDK_DIR}"
|
||||
|
||||
dnl CPP/CXXCPP needs to be set for MOZ_CHECK_HEADER.
|
||||
CPP="$CPP -isysroot ${MACOS_SDK_DIR}"
|
||||
CXXCPP="$CXXCPP -isysroot ${MACOS_SDK_DIR}"
|
||||
|
||||
AC_LANG_SAVE
|
||||
AC_MSG_CHECKING([for valid compiler/Mac OS X SDK combination])
|
||||
AC_LANG_CPLUSPLUS
|
||||
AC_TRY_COMPILE([#include <new>],[],
|
||||
result=yes,
|
||||
result=no)
|
||||
AC_LANG_RESTORE
|
||||
AC_MSG_RESULT($result)
|
||||
|
||||
if test "$result" = "no" ; then
|
||||
AC_MSG_ERROR([The selected compiler and Mac OS X SDK are incompatible.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_PATH_XTRA
|
||||
|
||||
XCFLAGS="$X_CFLAGS"
|
||||
|
@ -689,8 +629,6 @@ case "$host" in
|
|||
;;
|
||||
esac
|
||||
|
||||
MOZ_DOING_LTO(lto_is_enabled)
|
||||
|
||||
dnl ========================================================
|
||||
dnl System overrides of the defaults for target
|
||||
dnl ========================================================
|
||||
|
@ -723,11 +661,9 @@ case "$target" in
|
|||
MOZ_DEBUG_LDFLAGS="$MOZ_DEBUG_LDFLAGS -framework ExceptionHandling";
|
||||
fi
|
||||
|
||||
if test "x$lto_is_enabled" = "xyes"; then
|
||||
echo "Skipping -dead_strip because lto is enabled."
|
||||
dnl DTrace and -dead_strip don't interact well. See bug 403132.
|
||||
dnl ===================================================================
|
||||
elif test "x$enable_dtrace" = "xyes"; then
|
||||
if test "x$enable_dtrace" = "xyes"; then
|
||||
echo "Skipping -dead_strip because DTrace is enabled. See bug 403132."
|
||||
else
|
||||
dnl check for the presence of the -dead_strip linker flag
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
#ifdef XP_WIN
|
||||
#include <io.h>
|
||||
#include <winsock2.h>
|
||||
#define open _open
|
||||
#define close _close
|
||||
#define read _read
|
||||
#define lseek _lseek
|
||||
#define write _write
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
|
|
|
@ -36,7 +36,7 @@ if [ "$TARGET" == "x86_64-apple-darwin" ]; then
|
|||
export PATH="$PWD/cctools/bin:$PATH"
|
||||
cat >cross-linker <<EOF
|
||||
exec $PWD/clang/bin/clang -v \
|
||||
-fuse-ld=$PWD/cctools/bin/x86_64-apple-darwin11-ld \
|
||||
-fuse-ld=$PWD/cctools/bin/x86_64-darwin11-ld \
|
||||
-mmacosx-version-min=10.11 \
|
||||
-target $TARGET \
|
||||
-B $PWD/cctools/bin \
|
||||
|
|
|
@ -23,7 +23,7 @@ CLANG_DIR=$WORKSPACE/build/src/clang
|
|||
CCTOOLS_DIR=$WORKSPACE/build/src/cctools
|
||||
MACOSX_SDK_DIR=$WORKSPACE/build/src/MacOSX10.11.sdk
|
||||
|
||||
TARGET_TRIPLE=x86_64-apple-darwin11
|
||||
TARGET_TRIPLE=x86_64-darwin11
|
||||
|
||||
# Create our directories
|
||||
mkdir -p $CROSSTOOLS_BUILD_DIR
|
||||
|
|
|
@ -42,13 +42,15 @@ export CC=$CLANG_DIR/bin/clang
|
|||
export CXX=$CLANG_DIR/bin/clang++
|
||||
export LDFLAGS="-lpthread -Wl,-rpath-link,$CLANG_DIR/lib"
|
||||
./autogen.sh
|
||||
./configure --prefix=$CROSSTOOLS_BUILD_DIR --target=x86_64-apple-darwin11 --with-llvm-config=$CLANG_DIR/bin/llvm-config
|
||||
./configure --prefix=$CROSSTOOLS_BUILD_DIR --target=x86_64-darwin11 --with-llvm-config=$CLANG_DIR/bin/llvm-config
|
||||
|
||||
# Build cctools
|
||||
make -j `nproc --all` install
|
||||
strip $CROSSTOOLS_BUILD_DIR/bin/*
|
||||
# cctools-port doesn't include dsymutil but clang will need to find it.
|
||||
cp $CLANG_DIR/bin/dsymutil $CROSSTOOLS_BUILD_DIR/bin/x86_64-apple-darwin11-dsymutil
|
||||
cp $CLANG_DIR/bin/dsymutil $CROSSTOOLS_BUILD_DIR/bin/x86_64-darwin11-dsymutil
|
||||
# various build scripts based on cmake want to find `lipo` without a prefix
|
||||
cp $CROSSTOOLS_BUILD_DIR/bin/x86_64-darwin11-lipo $CROSSTOOLS_BUILD_DIR/bin/lipo
|
||||
|
||||
# Put a tarball in the artifacts dir
|
||||
mkdir -p $UPLOAD_DIR
|
||||
|
|
|
@ -16,9 +16,7 @@ export LD_LIBRARY_PATH=$HOME_DIR/src/clang/lib
|
|||
# these variables are used in build-clang.py
|
||||
export CROSS_CCTOOLS_PATH=$HOME_DIR/src/cctools
|
||||
export CROSS_SYSROOT=$HOME_DIR/src/MacOSX10.11.sdk
|
||||
# cmake doesn't allow us to specify a path to lipo on the command line.
|
||||
export PATH=$PATH:$CROSS_CCTOOLS_PATH/bin
|
||||
ln -sf $CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin11-lipo $CROSS_CCTOOLS_PATH/bin/lipo
|
||||
|
||||
# gets a bit too verbose here
|
||||
set +x
|
||||
|
|
|
@ -15,9 +15,7 @@ export LD_LIBRARY_PATH=$HOME_DIR/src/clang/lib
|
|||
# these variables are used in build-clang.py
|
||||
export CROSS_CCTOOLS_PATH=$HOME_DIR/src/cctools
|
||||
export CROSS_SYSROOT=$HOME_DIR/src/MacOSX10.11.sdk
|
||||
# cmake doesn't allow us to specify a path to lipo on the command line.
|
||||
export PATH=$PATH:$CROSS_CCTOOLS_PATH/bin
|
||||
ln -sf $CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin11-lipo $CROSS_CCTOOLS_PATH/bin/lipo
|
||||
|
||||
# gets a bit too verbose here
|
||||
set +x
|
||||
|
|
|
@ -15,9 +15,7 @@ export LD_LIBRARY_PATH=$HOME_DIR/src/clang/lib
|
|||
# these variables are used in build-clang.py
|
||||
export CROSS_CCTOOLS_PATH=$HOME_DIR/src/cctools
|
||||
export CROSS_SYSROOT=$HOME_DIR/src/MacOSX10.11.sdk
|
||||
# cmake doesn't allow us to specify a path to lipo on the command line.
|
||||
export PATH=$PATH:$CROSS_CCTOOLS_PATH/bin
|
||||
ln -sf $CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin11-lipo $CROSS_CCTOOLS_PATH/bin/lipo
|
||||
|
||||
# gets a bit too verbose here
|
||||
set +x
|
||||
|
|
|
@ -14,7 +14,7 @@ export LD_LIBRARY_PATH=$WORKSPACE/build/src/clang/lib
|
|||
export CC=$WORKSPACE/build/src/clang/bin/clang
|
||||
export CXX=$WORKSPACE/build/src/clang/bin/clang++
|
||||
export AR=$WORKSPACE/build/src/clang/bin/clang
|
||||
export CFLAGS="-target x86_64-apple-darwin11 -mlinker-version=137 -B ${CROSS_CCTOOLS_PATH}/bin -isysroot ${CROSS_SYSROOT} -I${CROSS_SYSROOT}/usr/include -iframework ${CROSS_SYSROOT}/System/Library/Frameworks"
|
||||
export CFLAGS="-target x86_64-darwin11 -mlinker-version=137 -B ${CROSS_CCTOOLS_PATH}/bin -isysroot ${CROSS_SYSROOT} -I${CROSS_SYSROOT}/usr/include -iframework ${CROSS_SYSROOT}/System/Library/Frameworks"
|
||||
export CXXFLAGS="-stdlib=libc++ ${CFLAGS}"
|
||||
export LDFLAGS="${CXXFLAGS} -Wl,-syslibroot,${CROSS_SYSROOT} -Wl,-dead_strip"
|
||||
|
||||
|
@ -34,7 +34,7 @@ cd $WORKSPACE/build/src
|
|||
|
||||
# The ninja templates used to bootstrap gn have hard-coded references to
|
||||
# 'libtool', make sure we find the right one.
|
||||
ln -s $CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin11-libtool $CROSS_CCTOOLS_PATH/bin/libtool
|
||||
ln -s $CROSS_CCTOOLS_PATH/bin/x86_64-darwin11-libtool $CROSS_CCTOOLS_PATH/bin/libtool
|
||||
export PATH=$CROSS_CCTOOLS_PATH/bin:$PATH
|
||||
|
||||
. taskcluster/scripts/misc/build-gn-common.sh
|
||||
|
|
|
@ -7,15 +7,12 @@ const Registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
|||
const UUID = "0f459ab4-b4ba-4741-ac89-ee47dea07adb";
|
||||
const ABOUT_PATH_PATH = "content/test.html";
|
||||
|
||||
XPCOMUtils.defineLazyGetter(
|
||||
this, "processScript",
|
||||
() => Cc["@mozilla.org/webextensions/extension-process-script;1"]
|
||||
.getService().wrappedJSObject);
|
||||
const {WebExtensionPolicy} = Cu.getGlobalForObject(Services);
|
||||
|
||||
const TPSProcessScript = {
|
||||
init() {
|
||||
let extensionChild = processScript.getExtensionChild(WEBEXTENSION_ID);
|
||||
let aboutPageURI = extensionChild.baseURI.resolve(ABOUT_PATH_PATH);
|
||||
let extensionPolicy = WebExtensionPolicy.getByID(WEBEXTENSION_ID);
|
||||
let aboutPageURI = extensionPolicy.getURL(ABOUT_PATH_PATH);
|
||||
|
||||
class TabSwitchAboutModule {
|
||||
constructor() {
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
[grid-alignment-style-changes-005.html]
|
||||
[.before 2]
|
||||
expected: FAIL
|
||||
|
||||
[.before 3]
|
||||
expected: FAIL
|
||||
|
||||
[.before 1]
|
||||
expected: FAIL
|
||||
|
||||
[.after 4]
|
||||
expected: FAIL
|
||||
|
||||
[.after 5]
|
||||
expected: FAIL
|
||||
|
||||
[.after 6]
|
||||
expected: FAIL
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
[grid-alignment-style-changes-006.html]
|
||||
[.before 2]
|
||||
expected: FAIL
|
||||
|
||||
[.before 3]
|
||||
expected: FAIL
|
||||
|
||||
[.before 1]
|
||||
expected: FAIL
|
||||
|
||||
[.after 4]
|
||||
expected: FAIL
|
||||
|
||||
[.after 5]
|
||||
expected: FAIL
|
||||
|
||||
[.after 6]
|
||||
expected: FAIL
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
[grid-alignment-style-changes-007.html]
|
||||
[.before 2]
|
||||
expected: FAIL
|
||||
|
||||
[.before 3]
|
||||
expected: FAIL
|
||||
|
||||
[.before 1]
|
||||
expected: FAIL
|
||||
|
||||
[.after 4]
|
||||
expected: FAIL
|
||||
|
||||
[.after 5]
|
||||
expected: FAIL
|
||||
|
||||
[.after 6]
|
||||
expected: FAIL
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
[grid-alignment-style-changes-008.html]
|
||||
[.before 2]
|
||||
expected: FAIL
|
||||
|
||||
[.before 3]
|
||||
expected: FAIL
|
||||
|
||||
[.before 1]
|
||||
expected: FAIL
|
||||
|
||||
[.after 4]
|
||||
expected: FAIL
|
||||
|
||||
[.after 5]
|
||||
expected: FAIL
|
||||
|
||||
[.after 6]
|
||||
expected: FAIL
|
||||
|
|
@ -17,30 +17,9 @@
|
|||
[canvas[tabindex\] should be focusable.]
|
||||
expected: FAIL
|
||||
|
||||
[clipPath[tabindex\] should not be focusable.]
|
||||
[mesh[tabindex\] should be focusable.]
|
||||
expected: FAIL
|
||||
|
||||
[defs[tabindex\] should not be focusable.]
|
||||
expected: FAIL
|
||||
|
||||
[hatch[tabindex\] should not be focusable.]
|
||||
expected: FAIL
|
||||
|
||||
[linearGradient[tabindex\] should not be focusable.]
|
||||
expected: FAIL
|
||||
|
||||
[marker[tabindex\] should not be focusable.]
|
||||
expected: FAIL
|
||||
|
||||
[mask[tabindex\] should not be focusable.]
|
||||
expected: FAIL
|
||||
|
||||
[meshgradient[tabindex\] should not be focusable.]
|
||||
expected: FAIL
|
||||
|
||||
[pattern[tabindex\] should not be focusable.]
|
||||
expected: FAIL
|
||||
|
||||
[radialGradient[tabindex\] should not be focusable.]
|
||||
[unknown[tabindex\] should be focusable.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
background: grey;
|
||||
align-items: baseline;
|
||||
font-family: Ahem;
|
||||
line-height: 1;
|
||||
}
|
||||
#item1 {
|
||||
font-size: 20px;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
background: grey;
|
||||
align-items: baseline;
|
||||
font-family: Ahem;
|
||||
line-height: 1;
|
||||
}
|
||||
#item1 {
|
||||
font-size: 20px;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
justify-items: baseline;
|
||||
font-family: Ahem;
|
||||
text-orientation: sideways;
|
||||
line-height: 1;
|
||||
}
|
||||
#container > div { writing-mode: vertical-lr; }
|
||||
#item1 {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
background: grey;
|
||||
justify-items: baseline;
|
||||
font-family: Ahem;
|
||||
line-height: 1;
|
||||
}
|
||||
#container > div { writing-mode: vertical-lr; }
|
||||
#item1 {
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче