1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Firefox
16 : *
17 : * The Initial Developer of the Original Code is
18 : * the Mozilla Foundation <http://www.mozilla.org/>.
19 : * Portions created by the Initial Developer are Copyright (C) 2010
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Philipp Kewisch <mozilla@kewis.ch>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "mozilla/Util.h"
40 :
41 : #include "ManifestParser.h"
42 :
43 : #include <string.h>
44 :
45 : #include "prio.h"
46 : #include "prprf.h"
47 : #if defined(XP_WIN)
48 : #include <windows.h>
49 : #elif defined(MOZ_WIDGET_COCOA)
50 : #include <CoreServices/CoreServices.h>
51 : #elif defined(MOZ_WIDGET_GTK2)
52 : #include <gtk/gtk.h>
53 : #endif
54 :
55 : #ifdef MOZ_WIDGET_ANDROID
56 : #include "AndroidBridge.h"
57 : #endif
58 :
59 : #include "mozilla/Services.h"
60 :
61 : #include "nsCRT.h"
62 : #include "nsConsoleMessage.h"
63 : #include "nsTextFormatter.h"
64 : #include "nsVersionComparator.h"
65 : #include "nsXPCOMCIDInternal.h"
66 :
67 : #include "nsIConsoleService.h"
68 : #include "nsIScriptError.h"
69 : #include "nsIXULAppInfo.h"
70 : #include "nsIXULRuntime.h"
71 :
72 : using namespace mozilla;
73 :
74 : struct ManifestDirective
75 : {
76 : const char* directive;
77 : int argc;
78 :
79 : // Some directives should only be delivered for NS_COMPONENT_LOCATION
80 : // manifests.
81 : bool componentonly;
82 :
83 : bool ischrome;
84 :
85 : bool allowbootstrap;
86 :
87 : // The platform/contentaccessible flags only apply to content directives.
88 : bool contentflags;
89 :
90 : // Function to handle this directive. This isn't a union because C++ still
91 : // hasn't learned how to initialize unions in a sane way.
92 : void (nsComponentManagerImpl::*mgrfunc)
93 : (nsComponentManagerImpl::ManifestProcessingContext& cx,
94 : int lineno, char *const * argv);
95 : void (nsChromeRegistry::*regfunc)
96 : (nsChromeRegistry::ManifestProcessingContext& cx,
97 : int lineno, char *const *argv,
98 : bool platform, bool contentaccessible);
99 :
100 : bool isContract;
101 : };
102 : static const ManifestDirective kParsingTable[] = {
103 : { "manifest", 1, false, true, true, false,
104 : &nsComponentManagerImpl::ManifestManifest, NULL },
105 : { "binary-component", 1, true, false, false, false,
106 : &nsComponentManagerImpl::ManifestBinaryComponent, NULL },
107 : { "interfaces", 1, true, false, false, false,
108 : &nsComponentManagerImpl::ManifestXPT, NULL },
109 : { "component", 2, true, false, false, false,
110 : &nsComponentManagerImpl::ManifestComponent, NULL },
111 : { "contract", 2, true, false, false, false,
112 : &nsComponentManagerImpl::ManifestContract, NULL, true},
113 : { "category", 3, true, false, false, false,
114 : &nsComponentManagerImpl::ManifestCategory, NULL },
115 : { "content", 2, true, true, true, true,
116 : NULL, &nsChromeRegistry::ManifestContent },
117 : { "locale", 3, true, true, true, false,
118 : NULL, &nsChromeRegistry::ManifestLocale },
119 : { "skin", 3, false, true, true, false,
120 : NULL, &nsChromeRegistry::ManifestSkin },
121 : { "overlay", 2, true, true, false, false,
122 : NULL, &nsChromeRegistry::ManifestOverlay },
123 : { "style", 2, false, true, false, false,
124 : NULL, &nsChromeRegistry::ManifestStyle },
125 : { "override", 2, true, true, true, false,
126 : NULL, &nsChromeRegistry::ManifestOverride },
127 : { "resource", 2, true, true, false, false,
128 : NULL, &nsChromeRegistry::ManifestResource }
129 : };
130 :
131 : static const char kWhitespace[] = "\t ";
132 :
133 53306398 : static bool IsNewline(char c)
134 : {
135 53306398 : return c == '\n' || c == '\r';
136 : }
137 :
138 : namespace {
139 : struct AutoPR_smprintf_free
140 : {
141 1408 : AutoPR_smprintf_free(char* buf)
142 1408 : : mBuf(buf)
143 : {
144 1408 : }
145 :
146 1408 : ~AutoPR_smprintf_free()
147 : {
148 1408 : if (mBuf)
149 1408 : PR_smprintf_free(mBuf);
150 1408 : }
151 :
152 2815 : operator char*() const {
153 2815 : return mBuf;
154 : }
155 :
156 : char* mBuf;
157 : };
158 :
159 : } // anonymous namespace
160 :
161 1 : void LogMessage(const char* aMsg, ...)
162 : {
163 : nsCOMPtr<nsIConsoleService> console =
164 2 : do_GetService(NS_CONSOLESERVICE_CONTRACTID);
165 1 : if (!console)
166 : return;
167 :
168 : va_list args;
169 1 : va_start(args, aMsg);
170 2 : AutoPR_smprintf_free formatted(PR_vsmprintf(aMsg, args));
171 1 : va_end(args);
172 :
173 : nsCOMPtr<nsIConsoleMessage> error =
174 3 : new nsConsoleMessage(NS_ConvertUTF8toUTF16(formatted).get());
175 1 : console->LogMessage(error);
176 : }
177 :
178 1407 : void LogMessageWithContext(FileLocation &aFile,
179 : PRUint32 aLineNumber, const char* aMsg, ...)
180 : {
181 : va_list args;
182 1407 : va_start(args, aMsg);
183 2814 : AutoPR_smprintf_free formatted(PR_vsmprintf(aMsg, args));
184 1407 : va_end(args);
185 1407 : if (!formatted)
186 : return;
187 :
188 2814 : nsCString file;
189 1407 : aFile.GetURIString(file);
190 :
191 : nsCOMPtr<nsIScriptError> error =
192 2814 : do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
193 1407 : if (!error) {
194 : // This can happen early in component registration. Fall back to a
195 : // generic console message.
196 : LogMessage("Warning: in '%s', line %i: %s", file.get(),
197 0 : aLineNumber, (char*) formatted);
198 : return;
199 : }
200 :
201 : nsCOMPtr<nsIConsoleService> console =
202 2814 : do_GetService(NS_CONSOLESERVICE_CONTRACTID);
203 1407 : if (!console)
204 : return;
205 :
206 4221 : nsresult rv = error->Init(NS_ConvertUTF8toUTF16(formatted).get(),
207 1407 : NS_ConvertUTF8toUTF16(file).get(), NULL,
208 : aLineNumber, 0, nsIScriptError::warningFlag,
209 2814 : "chrome registration");
210 1407 : if (NS_FAILED(rv))
211 : return;
212 :
213 2814 : console->LogMessage(error);
214 : }
215 :
216 : /**
217 : * Check for a modifier flag of the following forms:
218 : * "flag" (same as "true")
219 : * "flag=yes|true|1"
220 : * "flag="no|false|0"
221 : * @param aFlag The flag to compare.
222 : * @param aData The tokenized data to check; this is lowercased
223 : * before being passed in.
224 : * @param aResult If the flag is found, the value is assigned here.
225 : * @return Whether the flag was handled.
226 : */
227 : static bool
228 11410 : CheckFlag(const nsSubstring& aFlag, const nsSubstring& aData, bool& aResult)
229 : {
230 11410 : if (!StringBeginsWith(aData, aFlag))
231 4908 : return false;
232 :
233 6502 : if (aFlag.Length() == aData.Length()) {
234 : // the data is simply "flag", which is the same as "flag=yes"
235 1626 : aResult = true;
236 1626 : return true;
237 : }
238 :
239 4876 : if (aData.CharAt(aFlag.Length()) != '=') {
240 : // the data is "flag2=", which is not anything we care about
241 0 : return false;
242 : }
243 :
244 4876 : if (aData.Length() == aFlag.Length() + 1) {
245 0 : aResult = false;
246 0 : return true;
247 : }
248 :
249 4876 : switch (aData.CharAt(aFlag.Length() + 1)) {
250 : case '1':
251 : case 't': //true
252 : case 'y': //yes
253 4874 : aResult = true;
254 4874 : return true;
255 :
256 : case '0':
257 : case 'f': //false
258 : case 'n': //no
259 2 : aResult = false;
260 2 : return true;
261 : }
262 :
263 0 : return false;
264 : }
265 :
266 : enum TriState {
267 : eUnspecified,
268 : eBad,
269 : eOK
270 : };
271 :
272 : /**
273 : * Check for a modifier flag of the following form:
274 : * "flag=string"
275 : * "flag!=string"
276 : * @param aFlag The flag to compare.
277 : * @param aData The tokenized data to check; this is lowercased
278 : * before being passed in.
279 : * @param aValue The value that is expected.
280 : * @param aResult If this is "ok" when passed in, this is left alone.
281 : * Otherwise if the flag is found it is set to eBad or eOK.
282 : * @return Whether the flag was handled.
283 : */
284 : static bool
285 79709 : CheckStringFlag(const nsSubstring& aFlag, const nsSubstring& aData,
286 : const nsSubstring& aValue, TriState& aResult)
287 : {
288 79709 : if (aData.Length() < aFlag.Length() + 1)
289 11382 : return false;
290 :
291 68327 : if (!StringBeginsWith(aData, aFlag))
292 21206 : return false;
293 :
294 47121 : bool comparison = true;
295 47121 : if (aData[aFlag.Length()] != '=') {
296 13022 : if (aData[aFlag.Length()] == '!' &&
297 3258 : aData.Length() >= aFlag.Length() + 2 &&
298 3258 : aData[aFlag.Length() + 1] == '=')
299 3256 : comparison = false;
300 : else
301 3250 : return false;
302 : }
303 :
304 43871 : if (aResult != eOK) {
305 87742 : nsDependentSubstring testdata = Substring(aData, aFlag.Length() + (comparison ? 1 : 2));
306 43871 : if (testdata.Equals(aValue))
307 9 : aResult = comparison ? eOK : eBad;
308 : else
309 43862 : aResult = comparison ? eBad : eOK;
310 : }
311 :
312 43871 : return true;
313 : }
314 :
315 : /**
316 : * Check for a modifier flag of the following form:
317 : * "flag=version"
318 : * "flag<=version"
319 : * "flag<version"
320 : * "flag>=version"
321 : * "flag>version"
322 : * @param aFlag The flag to compare.
323 : * @param aData The tokenized data to check; this is lowercased
324 : * before being passed in.
325 : * @param aValue The value that is expected. If this is empty then no
326 : * comparison will match.
327 : * @param aResult If this is eOK when passed in, this is left alone.
328 : * Otherwise if the flag is found it is set to eBad or eOK.
329 : * @return Whether the flag was handled.
330 : */
331 :
332 : #define COMPARE_EQ 1 << 0
333 : #define COMPARE_LT 1 << 1
334 : #define COMPARE_GT 1 << 2
335 :
336 : static bool
337 22816 : CheckVersionFlag(const nsString& aFlag, const nsString& aData,
338 : const nsString& aValue, TriState& aResult)
339 : {
340 22816 : if (aData.Length() < aFlag.Length() + 2)
341 4890 : return false;
342 :
343 17926 : if (!StringBeginsWith(aData, aFlag))
344 14662 : return false;
345 :
346 3264 : if (aValue.Length() == 0) {
347 8 : if (aResult != eOK)
348 8 : aResult = eBad;
349 8 : return true;
350 : }
351 :
352 : PRUint32 comparison;
353 6512 : nsAutoString testdata;
354 :
355 3256 : switch (aData[aFlag.Length()]) {
356 : case '=':
357 2 : comparison = COMPARE_EQ;
358 2 : testdata = Substring(aData, aFlag.Length() + 1);
359 2 : break;
360 :
361 : case '<':
362 3251 : if (aData[aFlag.Length() + 1] == '=') {
363 1 : comparison = COMPARE_EQ | COMPARE_LT;
364 1 : testdata = Substring(aData, aFlag.Length() + 2);
365 : }
366 : else {
367 3250 : comparison = COMPARE_LT;
368 3250 : testdata = Substring(aData, aFlag.Length() + 1);
369 : }
370 3251 : break;
371 :
372 : case '>':
373 3 : if (aData[aFlag.Length() + 1] == '=') {
374 1 : comparison = COMPARE_EQ | COMPARE_GT;
375 1 : testdata = Substring(aData, aFlag.Length() + 2);
376 : }
377 : else {
378 2 : comparison = COMPARE_GT;
379 2 : testdata = Substring(aData, aFlag.Length() + 1);
380 : }
381 3 : break;
382 :
383 : default:
384 0 : return false;
385 : }
386 :
387 3256 : if (testdata.Length() == 0)
388 0 : return false;
389 :
390 3256 : if (aResult != eOK) {
391 3256 : PRInt32 c = NS_CompareVersions(NS_ConvertUTF16toUTF8(aValue).get(),
392 6512 : NS_ConvertUTF16toUTF8(testdata).get());
393 3256 : if ((c == 0 && comparison & COMPARE_EQ) ||
394 : (c < 0 && comparison & COMPARE_LT) ||
395 : (c > 0 && comparison & COMPARE_GT))
396 3253 : aResult = eOK;
397 : else
398 3 : aResult = eBad;
399 : }
400 :
401 3256 : return true;
402 : }
403 :
404 : // In-place conversion of ascii characters to lower case
405 : static void
406 53647 : ToLowerCase(char* token)
407 : {
408 2128765 : for (; *token; ++token)
409 2075118 : *token = NS_ToLower(*token);
410 53647 : }
411 :
412 : namespace {
413 :
414 : struct CachedDirective
415 137637 : {
416 : int lineno;
417 : char* argv[4];
418 : };
419 :
420 : } // anonymous namespace
421 :
422 :
423 : void
424 99082 : ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOnly)
425 : {
426 198164 : nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, file, aChromeOnly);
427 198164 : nsChromeRegistry::ManifestProcessingContext chromecx(type, file);
428 : nsresult rv;
429 :
430 198164 : NS_NAMED_LITERAL_STRING(kPlatform, "platform");
431 198164 : NS_NAMED_LITERAL_STRING(kContentAccessible, "contentaccessible");
432 198164 : NS_NAMED_LITERAL_STRING(kApplication, "application");
433 198164 : NS_NAMED_LITERAL_STRING(kAppVersion, "appversion");
434 198164 : NS_NAMED_LITERAL_STRING(kGeckoVersion, "platformversion");
435 198164 : NS_NAMED_LITERAL_STRING(kOs, "os");
436 198164 : NS_NAMED_LITERAL_STRING(kOsVersion, "osversion");
437 198164 : NS_NAMED_LITERAL_STRING(kABI, "abi");
438 : #if defined(MOZ_WIDGET_ANDROID)
439 : NS_NAMED_LITERAL_STRING(kTablet, "tablet");
440 : #endif
441 :
442 : // Obsolete
443 198164 : NS_NAMED_LITERAL_STRING(kXPCNativeWrappers, "xpcnativewrappers");
444 :
445 198164 : nsAutoString appID;
446 198164 : nsAutoString appVersion;
447 198164 : nsAutoString geckoVersion;
448 198164 : nsAutoString osTarget;
449 198164 : nsAutoString abi;
450 :
451 198164 : nsCOMPtr<nsIXULAppInfo> xapp (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
452 99082 : if (xapp) {
453 24302 : nsCAutoString s;
454 12151 : rv = xapp->GetID(s);
455 12151 : if (NS_SUCCEEDED(rv))
456 12151 : CopyUTF8toUTF16(s, appID);
457 :
458 12151 : rv = xapp->GetVersion(s);
459 12151 : if (NS_SUCCEEDED(rv))
460 12151 : CopyUTF8toUTF16(s, appVersion);
461 :
462 12151 : rv = xapp->GetPlatformVersion(s);
463 12151 : if (NS_SUCCEEDED(rv))
464 12151 : CopyUTF8toUTF16(s, geckoVersion);
465 :
466 24302 : nsCOMPtr<nsIXULRuntime> xruntime (do_QueryInterface(xapp));
467 12151 : if (xruntime) {
468 12151 : rv = xruntime->GetOS(s);
469 12151 : if (NS_SUCCEEDED(rv)) {
470 12151 : ToLowerCase(s);
471 12151 : CopyUTF8toUTF16(s, osTarget);
472 : }
473 :
474 12151 : rv = xruntime->GetXPCOMABI(s);
475 12151 : if (NS_SUCCEEDED(rv) && osTarget.Length()) {
476 12151 : ToLowerCase(s);
477 12151 : CopyUTF8toUTF16(s, abi);
478 12151 : abi.Insert(PRUnichar('_'), 0);
479 12151 : abi.Insert(osTarget, 0);
480 : }
481 : }
482 : }
483 :
484 198164 : nsAutoString osVersion;
485 : #if defined(XP_WIN)
486 : OSVERSIONINFO info = { sizeof(OSVERSIONINFO) };
487 : if (GetVersionEx(&info)) {
488 : nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
489 : info.dwMajorVersion,
490 : info.dwMinorVersion);
491 : }
492 : #elif defined(MOZ_WIDGET_COCOA)
493 : SInt32 majorVersion, minorVersion;
494 : if ((Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) &&
495 : (Gestalt(gestaltSystemVersionMinor, &minorVersion) == noErr)) {
496 : nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
497 : majorVersion,
498 : minorVersion);
499 : }
500 : #elif defined(MOZ_WIDGET_GTK2)
501 99082 : nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
502 : gtk_major_version,
503 99082 : gtk_minor_version);
504 : #elif defined(MOZ_WIDGET_ANDROID)
505 : bool isTablet = false;
506 : if (mozilla::AndroidBridge::Bridge()) {
507 : mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION", "RELEASE", osVersion);
508 : isTablet = mozilla::AndroidBridge::Bridge()->IsTablet();
509 : }
510 : #endif
511 :
512 : // Because contracts must be registered after CIDs, we save and process them
513 : // at the end.
514 198164 : nsTArray<CachedDirective> contracts;
515 :
516 : char *token;
517 99082 : char *newline = buf;
518 99082 : PRUint32 line = 0;
519 :
520 : // outer loop tokenizes by newline
521 1060688 : while (*newline) {
522 1760866 : while (*newline && IsNewline(*newline)) {
523 22806 : ++newline;
524 22806 : ++line;
525 : }
526 869030 : if (!*newline)
527 6506 : break;
528 :
529 862524 : token = newline;
530 53290089 : while (*newline && !IsNewline(*newline))
531 51565041 : ++newline;
532 :
533 862524 : if (*newline) {
534 856027 : *newline = '\0';
535 856027 : ++newline;
536 : }
537 862524 : ++line;
538 :
539 862524 : if (*token == '#') // ignore lines that begin with # as comments
540 13042 : continue;
541 :
542 849482 : char *whitespace = token;
543 849482 : token = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
544 849482 : if (!token) continue;
545 :
546 849482 : const ManifestDirective* directive = NULL;
547 7190302 : for (const ManifestDirective* d = kParsingTable;
548 3595151 : d < ArrayEnd(kParsingTable);
549 : ++d) {
550 3595151 : if (!strcmp(d->directive, token)) {
551 849482 : directive = d;
552 849482 : break;
553 : }
554 : }
555 :
556 849482 : if (!directive) {
557 : LogMessageWithContext(file, line,
558 : "Ignoring unrecognized chrome manifest directive '%s'.",
559 0 : token);
560 0 : continue;
561 : }
562 :
563 849482 : if (!directive->allowbootstrap && NS_BOOTSTRAPPED_LOCATION == type) {
564 : LogMessageWithContext(file, line,
565 : "Bootstrapped manifest not allowed to use '%s' directive.",
566 4 : token);
567 4 : continue;
568 : }
569 :
570 849478 : if (directive->componentonly && NS_SKIN_LOCATION == type) {
571 : LogMessageWithContext(file, line,
572 : "Skin manifest not allowed to use '%s' directive.",
573 0 : token);
574 0 : continue;
575 : }
576 :
577 849478 : NS_ASSERTION(directive->argc < 4, "Need to reset argv array length");
578 : char* argv[4];
579 2296779 : for (int i = 0; i < directive->argc; ++i)
580 1447301 : argv[i] = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
581 :
582 849478 : if (!argv[directive->argc - 1]) {
583 : LogMessageWithContext(file, line,
584 : "Not enough arguments for chrome manifest directive '%s', expected %i.",
585 2 : token, directive->argc);
586 2 : continue;
587 : }
588 :
589 849476 : bool ok = true;
590 849476 : TriState stAppVersion = eUnspecified;
591 849476 : TriState stGeckoVersion = eUnspecified;
592 849476 : TriState stApp = eUnspecified;
593 849476 : TriState stOsVersion = eUnspecified;
594 849476 : TriState stOs = eUnspecified;
595 849476 : TriState stABI = eUnspecified;
596 : #if defined(MOZ_WIDGET_ANDROID)
597 : TriState stTablet = eUnspecified;
598 : #endif
599 849476 : bool platform = false;
600 849476 : bool contentAccessible = false;
601 :
602 1752599 : while (NULL != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) && ok) {
603 53647 : ToLowerCase(token);
604 107294 : NS_ConvertASCIItoUTF16 wtoken(token);
605 :
606 102525 : if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
607 16282 : CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
608 9780 : CheckStringFlag(kABI, wtoken, abi, stABI) ||
609 9776 : CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) ||
610 6528 : CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) ||
611 6512 : CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion))
612 47135 : continue;
613 :
614 : #if defined(MOZ_WIDGET_ANDROID)
615 : bool tablet = false;
616 : if (CheckFlag(kTablet, wtoken, tablet)) {
617 : stTablet = (tablet == isTablet) ? eOK : eBad;
618 : continue;
619 : }
620 : #endif
621 :
622 17912 : if (directive->contentflags &&
623 6512 : (CheckFlag(kPlatform, wtoken, platform) ||
624 4888 : CheckFlag(kContentAccessible, wtoken, contentAccessible)))
625 6502 : continue;
626 :
627 10 : bool xpcNativeWrappers = true; // Dummy for CheckFlag.
628 10 : if (CheckFlag(kXPCNativeWrappers, wtoken, xpcNativeWrappers)) {
629 : LogMessageWithContext(file, line,
630 : "Ignoring obsolete chrome registration modifier '%s'.",
631 0 : token);
632 0 : continue;
633 : }
634 :
635 : LogMessageWithContext(file, line,
636 : "Unrecognized chrome manifest modifier '%s'.",
637 10 : token);
638 10 : ok = false;
639 : }
640 :
641 849476 : if (!ok ||
642 : stApp == eBad ||
643 : stAppVersion == eBad ||
644 : stGeckoVersion == eBad ||
645 : stOs == eBad ||
646 : stOsVersion == eBad ||
647 : #ifdef MOZ_WIDGET_ANDROID
648 : stTablet == eBad ||
649 : #endif
650 : stABI == eBad)
651 40633 : continue;
652 :
653 808843 : if (directive->regfunc) {
654 86183 : if (GeckoProcessType_Default != XRE_GetProcessType())
655 0 : continue;
656 :
657 86183 : if (!nsChromeRegistry::gChromeRegistry) {
658 : nsCOMPtr<nsIChromeRegistry> cr =
659 2838 : mozilla::services::GetChromeRegistryService();
660 1419 : if (!nsChromeRegistry::gChromeRegistry) {
661 : LogMessageWithContext(file, line,
662 0 : "Chrome registry isn't available yet.");
663 0 : continue;
664 : }
665 : }
666 :
667 : (nsChromeRegistry::gChromeRegistry->*(directive->regfunc))
668 86183 : (chromecx, line, argv, platform, contentAccessible);
669 : }
670 722660 : else if (directive->ischrome || !aChromeOnly) {
671 643530 : if (directive->isContract) {
672 137637 : CachedDirective* cd = contracts.AppendElement();
673 137637 : cd->lineno = line;
674 137637 : cd->argv[0] = argv[0];
675 137637 : cd->argv[1] = argv[1];
676 : }
677 : else
678 : (nsComponentManagerImpl::gComponentManager->*(directive->mgrfunc))
679 505893 : (mgrcx, line, argv);
680 : }
681 : }
682 :
683 236719 : for (PRUint32 i = 0; i < contracts.Length(); ++i) {
684 137637 : CachedDirective& d = contracts[i];
685 : nsComponentManagerImpl::gComponentManager->ManifestContract
686 137637 : (mgrcx, d.lineno, d.argv);
687 : }
688 99082 : }
|