|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* vim: set ts=8 sts=4 et sw=4 tw=99: */ |
|
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 /* |
|
8 * nsIScriptError implementation. Defined here, lacking a JS-specific |
|
9 * place to put XPCOM things. |
|
10 */ |
|
11 |
|
12 #include "xpcprivate.h" |
|
13 #include "jsprf.h" |
|
14 #include "nsGlobalWindow.h" |
|
15 #include "nsPIDOMWindow.h" |
|
16 #include "nsILoadContext.h" |
|
17 #include "nsIDocShell.h" |
|
18 |
|
19 NS_IMPL_ISUPPORTS(nsScriptError, nsIConsoleMessage, nsIScriptError) |
|
20 |
|
21 nsScriptError::nsScriptError() |
|
22 : mMessage(), |
|
23 mSourceName(), |
|
24 mLineNumber(0), |
|
25 mSourceLine(), |
|
26 mColumnNumber(0), |
|
27 mFlags(0), |
|
28 mCategory(), |
|
29 mOuterWindowID(0), |
|
30 mInnerWindowID(0), |
|
31 mTimeStamp(0), |
|
32 mIsFromPrivateWindow(false) |
|
33 { |
|
34 } |
|
35 |
|
36 nsScriptError::~nsScriptError() {} |
|
37 |
|
38 // nsIConsoleMessage methods |
|
39 NS_IMETHODIMP |
|
40 nsScriptError::GetMessageMoz(char16_t **result) { |
|
41 nsresult rv; |
|
42 |
|
43 nsAutoCString message; |
|
44 rv = ToString(message); |
|
45 if (NS_FAILED(rv)) |
|
46 return rv; |
|
47 |
|
48 *result = UTF8ToNewUnicode(message); |
|
49 if (!*result) |
|
50 return NS_ERROR_OUT_OF_MEMORY; |
|
51 |
|
52 return NS_OK; |
|
53 } |
|
54 |
|
55 // nsIScriptError methods |
|
56 NS_IMETHODIMP |
|
57 nsScriptError::GetErrorMessage(nsAString& aResult) { |
|
58 aResult.Assign(mMessage); |
|
59 return NS_OK; |
|
60 } |
|
61 |
|
62 NS_IMETHODIMP |
|
63 nsScriptError::GetSourceName(nsAString& aResult) { |
|
64 aResult.Assign(mSourceName); |
|
65 return NS_OK; |
|
66 } |
|
67 |
|
68 NS_IMETHODIMP |
|
69 nsScriptError::GetSourceLine(nsAString& aResult) { |
|
70 aResult.Assign(mSourceLine); |
|
71 return NS_OK; |
|
72 } |
|
73 |
|
74 NS_IMETHODIMP |
|
75 nsScriptError::GetLineNumber(uint32_t *result) { |
|
76 *result = mLineNumber; |
|
77 return NS_OK; |
|
78 } |
|
79 |
|
80 NS_IMETHODIMP |
|
81 nsScriptError::GetColumnNumber(uint32_t *result) { |
|
82 *result = mColumnNumber; |
|
83 return NS_OK; |
|
84 } |
|
85 |
|
86 NS_IMETHODIMP |
|
87 nsScriptError::GetFlags(uint32_t *result) { |
|
88 *result = mFlags; |
|
89 return NS_OK; |
|
90 } |
|
91 |
|
92 NS_IMETHODIMP |
|
93 nsScriptError::GetCategory(char **result) { |
|
94 *result = ToNewCString(mCategory); |
|
95 return NS_OK; |
|
96 } |
|
97 |
|
98 NS_IMETHODIMP |
|
99 nsScriptError::Init(const nsAString& message, |
|
100 const nsAString& sourceName, |
|
101 const nsAString& sourceLine, |
|
102 uint32_t lineNumber, |
|
103 uint32_t columnNumber, |
|
104 uint32_t flags, |
|
105 const char *category) |
|
106 { |
|
107 return InitWithWindowID(message, sourceName, sourceLine, lineNumber, |
|
108 columnNumber, flags, |
|
109 category ? nsDependentCString(category) |
|
110 : EmptyCString(), |
|
111 0); |
|
112 } |
|
113 |
|
114 NS_IMETHODIMP |
|
115 nsScriptError::InitWithWindowID(const nsAString& message, |
|
116 const nsAString& sourceName, |
|
117 const nsAString& sourceLine, |
|
118 uint32_t lineNumber, |
|
119 uint32_t columnNumber, |
|
120 uint32_t flags, |
|
121 const nsACString& category, |
|
122 uint64_t aInnerWindowID) |
|
123 { |
|
124 mMessage.Assign(message); |
|
125 mSourceName.Assign(sourceName); |
|
126 mLineNumber = lineNumber; |
|
127 mSourceLine.Assign(sourceLine); |
|
128 mColumnNumber = columnNumber; |
|
129 mFlags = flags; |
|
130 mCategory = category; |
|
131 mTimeStamp = JS_Now() / 1000; |
|
132 mInnerWindowID = aInnerWindowID; |
|
133 |
|
134 if (aInnerWindowID) { |
|
135 nsGlobalWindow* window = |
|
136 nsGlobalWindow::GetInnerWindowWithId(aInnerWindowID); |
|
137 if (window) { |
|
138 nsPIDOMWindow* outer = window->GetOuterWindow(); |
|
139 if (outer) |
|
140 mOuterWindowID = outer->WindowID(); |
|
141 |
|
142 nsIDocShell* docShell = window->GetDocShell(); |
|
143 nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell); |
|
144 |
|
145 if (loadContext) { |
|
146 // Never mark exceptions from chrome windows as having come from |
|
147 // private windows, since we always want them to be reported. |
|
148 nsIPrincipal* winPrincipal = window->GetPrincipal(); |
|
149 mIsFromPrivateWindow = loadContext->UsePrivateBrowsing() && |
|
150 !nsContentUtils::IsSystemPrincipal(winPrincipal); |
|
151 } |
|
152 |
|
153 } |
|
154 } |
|
155 |
|
156 return NS_OK; |
|
157 } |
|
158 |
|
159 NS_IMETHODIMP |
|
160 nsScriptError::ToString(nsACString& /*UTF8*/ aResult) |
|
161 { |
|
162 static const char format0[] = |
|
163 "[%s: \"%s\" {file: \"%s\" line: %d column: %d source: \"%s\"}]"; |
|
164 static const char format1[] = |
|
165 "[%s: \"%s\" {file: \"%s\" line: %d}]"; |
|
166 static const char format2[] = |
|
167 "[%s: \"%s\"]"; |
|
168 |
|
169 static const char error[] = "JavaScript Error"; |
|
170 static const char warning[] = "JavaScript Warning"; |
|
171 |
|
172 const char* severity = !(mFlags & JSREPORT_WARNING) ? error : warning; |
|
173 |
|
174 char* temp; |
|
175 char* tempMessage = nullptr; |
|
176 char* tempSourceName = nullptr; |
|
177 char* tempSourceLine = nullptr; |
|
178 |
|
179 if (!mMessage.IsEmpty()) |
|
180 tempMessage = ToNewUTF8String(mMessage); |
|
181 if (!mSourceName.IsEmpty()) |
|
182 tempSourceName = ToNewUTF8String(mSourceName); |
|
183 if (!mSourceLine.IsEmpty()) |
|
184 tempSourceLine = ToNewUTF8String(mSourceLine); |
|
185 |
|
186 if (nullptr != tempSourceName && nullptr != tempSourceLine) |
|
187 temp = JS_smprintf(format0, |
|
188 severity, |
|
189 tempMessage, |
|
190 tempSourceName, |
|
191 mLineNumber, |
|
192 mColumnNumber, |
|
193 tempSourceLine); |
|
194 else if (!mSourceName.IsEmpty()) |
|
195 temp = JS_smprintf(format1, |
|
196 severity, |
|
197 tempMessage, |
|
198 tempSourceName, |
|
199 mLineNumber); |
|
200 else |
|
201 temp = JS_smprintf(format2, |
|
202 severity, |
|
203 tempMessage); |
|
204 |
|
205 if (nullptr != tempMessage) |
|
206 nsMemory::Free(tempMessage); |
|
207 if (nullptr != tempSourceName) |
|
208 nsMemory::Free(tempSourceName); |
|
209 if (nullptr != tempSourceLine) |
|
210 nsMemory::Free(tempSourceLine); |
|
211 |
|
212 if (!temp) |
|
213 return NS_ERROR_OUT_OF_MEMORY; |
|
214 |
|
215 aResult.Assign(temp); |
|
216 JS_smprintf_free(temp); |
|
217 return NS_OK; |
|
218 } |
|
219 |
|
220 NS_IMETHODIMP |
|
221 nsScriptError::GetOuterWindowID(uint64_t *aOuterWindowID) |
|
222 { |
|
223 *aOuterWindowID = mOuterWindowID; |
|
224 return NS_OK; |
|
225 } |
|
226 |
|
227 NS_IMETHODIMP |
|
228 nsScriptError::GetInnerWindowID(uint64_t *aInnerWindowID) |
|
229 { |
|
230 *aInnerWindowID = mInnerWindowID; |
|
231 return NS_OK; |
|
232 } |
|
233 |
|
234 NS_IMETHODIMP |
|
235 nsScriptError::GetTimeStamp(int64_t *aTimeStamp) |
|
236 { |
|
237 *aTimeStamp = mTimeStamp; |
|
238 return NS_OK; |
|
239 } |
|
240 |
|
241 NS_IMETHODIMP |
|
242 nsScriptError::GetIsFromPrivateWindow(bool *aIsFromPrivateWindow) |
|
243 { |
|
244 *aIsFromPrivateWindow = mIsFromPrivateWindow; |
|
245 return NS_OK; |
|
246 } |