Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/build/Omnijar.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "Omnijar.h"
8
9
#include "nsDirectoryService.h"
10
#include "nsDirectoryServiceDefs.h"
11
#include "nsIFile.h"
12
#include "nsZipArchive.h"
13
#include "nsNetUtil.h"
14
15
namespace mozilla {
16
17
StaticRefPtr<nsIFile> Omnijar::sPath[2];
18
StaticRefPtr<nsZipArchive> Omnijar::sReader[2];
19
StaticRefPtr<nsZipArchive> Omnijar::sOuterReader[2];
20
bool Omnijar::sInitialized = false;
21
bool Omnijar::sIsUnified = false;
22
23
static const char* sProp[2] = {
24
  NS_GRE_DIR, NS_XPCOM_CURRENT_PROCESS_DIR
25
};
26
27
6
#define SPROP(Type) ((Type == mozilla::Omnijar::GRE) ? sProp[GRE] : sProp[APP])
28
29
void
30
Omnijar::CleanUpOne(Type aType)
31
3
{
32
3
  if (sReader[aType]) {
33
0
    sReader[aType]->CloseArchive();
34
0
    sReader[aType] = nullptr;
35
0
  }
36
3
  if (sOuterReader[aType]) {
37
0
    sOuterReader[aType]->CloseArchive();
38
0
    sOuterReader[aType] = nullptr;
39
0
  }
40
3
  sPath[aType] = nullptr;
41
3
}
42
43
void
44
Omnijar::InitOne(nsIFile* aPath, Type aType)
45
6
{
46
6
  nsCOMPtr<nsIFile> file;
47
6
  if (aPath) {
48
0
    file = aPath;
49
6
  } else {
50
6
    nsCOMPtr<nsIFile> dir;
51
6
    nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile),
52
6
                                      getter_AddRefs(dir));
53
6
    NS_NAMED_LITERAL_CSTRING(kOmnijarName, NS_STRINGIFY(OMNIJAR_NAME));
54
6
    if (NS_FAILED(dir->Clone(getter_AddRefs(file))) ||
55
6
        NS_FAILED(file->AppendNative(kOmnijarName))) {
56
0
      return;
57
0
    }
58
6
  }
59
6
  bool isFile;
60
6
  if (NS_FAILED(file->IsFile(&isFile)) || !isFile) {
61
0
    // If we're not using an omni.jar for GRE, and we don't have an
62
0
    // omni.jar for APP, check if both directories are the same.
63
0
    if ((aType == APP) && (!sPath[GRE])) {
64
0
      nsCOMPtr<nsIFile> greDir, appDir;
65
0
      bool equals;
66
0
      nsDirectoryService::gService->Get(sProp[GRE], NS_GET_IID(nsIFile),
67
0
                                        getter_AddRefs(greDir));
68
0
      nsDirectoryService::gService->Get(sProp[APP], NS_GET_IID(nsIFile),
69
0
                                        getter_AddRefs(appDir));
70
0
      if (NS_SUCCEEDED(greDir->Equals(appDir, &equals)) && equals) {
71
0
        sIsUnified = true;
72
0
      }
73
0
    }
74
0
    return;
75
0
  }
76
6
77
6
  bool equals;
78
6
  if ((aType == APP) && (sPath[GRE]) &&
79
6
      NS_SUCCEEDED(sPath[GRE]->Equals(file, &equals)) && equals) {
80
3
    // If we're using omni.jar on both GRE and APP and their path
81
3
    // is the same, we're in the unified case.
82
3
    sIsUnified = true;
83
3
    return;
84
3
  }
85
3
86
3
  RefPtr<nsZipArchive> zipReader = new nsZipArchive();
87
3
  if (NS_FAILED(zipReader->OpenArchive(file))) {
88
0
    return;
89
0
  }
90
3
91
3
  RefPtr<nsZipArchive> outerReader;
92
3
  RefPtr<nsZipHandle> handle;
93
3
  if (NS_SUCCEEDED(nsZipHandle::Init(zipReader, NS_STRINGIFY(OMNIJAR_NAME),
94
3
                                     getter_AddRefs(handle)))) {
95
0
    outerReader = zipReader;
96
0
    zipReader = new nsZipArchive();
97
0
    if (NS_FAILED(zipReader->OpenArchive(handle))) {
98
0
      return;
99
0
    }
100
3
  }
101
3
102
3
  CleanUpOne(aType);
103
3
  sReader[aType] = zipReader;
104
3
  sOuterReader[aType] = outerReader;
105
3
  sPath[aType] = file;
106
3
}
107
108
void
109
Omnijar::Init(nsIFile* aGrePath, nsIFile* aAppPath)
110
3
{
111
3
  InitOne(aGrePath, GRE);
112
3
  InitOne(aAppPath, APP);
113
3
  sInitialized = true;
114
3
}
115
116
void
117
Omnijar::CleanUp()
118
0
{
119
0
  CleanUpOne(GRE);
120
0
  CleanUpOne(APP);
121
0
  sInitialized = false;
122
0
}
123
124
already_AddRefed<nsZipArchive>
125
Omnijar::GetReader(nsIFile* aPath)
126
1
{
127
1
  MOZ_ASSERT(IsInitialized(), "Omnijar not initialized");
128
1
129
1
  bool equals;
130
1
  nsresult rv;
131
1
132
1
  if (sPath[GRE]) {
133
1
    rv = sPath[GRE]->Equals(aPath, &equals);
134
1
    if (NS_SUCCEEDED(rv) && equals) {
135
1
      return IsNested(GRE) ? GetOuterReader(GRE) : GetReader(GRE);
136
1
    }
137
0
  }
138
0
  if (sPath[APP]) {
139
0
    rv = sPath[APP]->Equals(aPath, &equals);
140
0
    if (NS_SUCCEEDED(rv) && equals) {
141
0
      return IsNested(APP) ? GetOuterReader(APP) : GetReader(APP);
142
0
    }
143
0
  }
144
0
  return nullptr;
145
0
}
146
147
nsresult
148
Omnijar::GetURIString(Type aType, nsACString& aResult)
149
19
{
150
19
  MOZ_ASSERT(IsInitialized(), "Omnijar not initialized");
151
19
152
19
  aResult.Truncate();
153
19
154
19
  // Return an empty string for APP in the unified case.
155
19
  if ((aType == APP) && sIsUnified) {
156
8
    return NS_OK;
157
8
  }
158
11
159
11
  nsAutoCString omniJarSpec;
160
11
  if (sPath[aType]) {
161
11
    nsresult rv = NS_GetURLSpecFromActualFile(sPath[aType], omniJarSpec);
162
11
    if (NS_WARN_IF(NS_FAILED(rv))) {
163
0
      return rv;
164
0
    }
165
11
166
11
    aResult = "jar:";
167
11
    if (IsNested(aType)) {
168
0
      aResult += "jar:";
169
0
    }
170
11
    aResult += omniJarSpec;
171
11
    aResult += "!";
172
11
    if (IsNested(aType)) {
173
0
      aResult += "/" NS_STRINGIFY(OMNIJAR_NAME) "!";
174
0
    }
175
11
  } else {
176
0
    nsCOMPtr<nsIFile> dir;
177
0
    nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile),
178
0
                                      getter_AddRefs(dir));
179
0
    nsresult rv = NS_GetURLSpecFromActualFile(dir, aResult);
180
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
181
0
      return rv;
182
0
    }
183
11
  }
184
11
  aResult += "/";
185
11
  return NS_OK;
186
11
}
187
188
} /* namespace mozilla */