Changeset 44135 in webkit
- Timestamp:
- May 25, 2009 2:33:33 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 8 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r44133 r44135 1 2009-05-25 Adam Barth <abarth@webkit.og> 2 3 Reviewed by Sam Weinig. 4 5 https://bugs.webkit.org/show_bug.cgi?id=26006 6 7 Test our use of dynamicGlobalObject and lexicalGlobalObject for 8 window.location. 9 10 * http/tests/security/frameNavigation/context-for-location-assign-expected.txt: Added. 11 * http/tests/security/frameNavigation/context-for-location-assign.html: Added. 12 * http/tests/security/frameNavigation/context-for-location-expected.txt: Added. 13 * http/tests/security/frameNavigation/context-for-location-href-expected.txt: Added. 14 * http/tests/security/frameNavigation/context-for-location-href.html: Added. 15 * http/tests/security/frameNavigation/context-for-location.html: Added. 16 * http/tests/security/frameNavigation/resources/middle-frame-for-location.html: Added. 17 * http/tests/security/frameNavigation/resources/target-for-location.html: Added. 18 1 19 2009-05-25 Adam Barth <abarth@webkit.org> 2 20 -
trunk/WebCore/ChangeLog
r44130 r44135 1 2009-05-25 Adam Barth <abarth@webkit.org> 2 3 Reviewed by Sam Weinig. 4 5 https://bugs.webkit.org/show_bug.cgi?id=26006 6 7 Sort out our use of dynamicGlobalObject and lexicalGlobalObject for 8 window.location. The correct use appears to be as follows: 9 10 1) Use dynamicGlobalObject to find the user gesture. 11 2) Use dynamicGlobalObject to complete URLs. 12 3) Use lexicalGlobalObject to find the referrer. 13 4) Use lexicalGlobalObject for the frame navigation checks. 14 5) Use lexicalGlobalObject for the XSS checks. 15 16 Tests: http/tests/security/frameNavigation/context-for-location-assign.html 17 http/tests/security/frameNavigation/context-for-location-href.html 18 http/tests/security/frameNavigation/context-for-location.html 19 20 * bindings/js/JSDOMBinding.cpp: 21 (WebCore::shouldAllowNavigation): 22 (WebCore::toLexicalFrame): 23 (WebCore::processingUserGesture): 24 (WebCore::completeURL): 25 * bindings/js/JSDOMBinding.h: 26 * bindings/js/JSDOMWindowCustom.cpp: 27 (WebCore::JSDOMWindow::setLocation): 28 * bindings/js/JSLocationCustom.cpp: 29 (WebCore::navigateIfAllowed): 30 (WebCore::JSLocation::setHref): 31 (WebCore::JSLocation::replace): 32 (WebCore::JSLocation::reload): 33 (WebCore::JSLocation::assign): 34 (WebCore::JSLocation::toString): 35 (WebCore::JSLocationPrototype::customPut): 36 * bindings/v8/V8Utilities.cpp: 37 (WebCore::processingUserGesture): 38 (WebCore::shouldAllowNavigation): 39 (WebCore::completeURL): 40 (WebCore::navigateIfAllowed): 41 * bindings/v8/V8Utilities.h: 42 * bindings/v8/custom/V8DOMWindowCustom.cpp: 43 (WebCore::V8Custom::WindowSetLocation): 44 * bindings/v8/custom/V8LocationCustom.cpp: 45 (WebCore::ACCESSOR_SETTER): 46 (WebCore::CALLBACK_FUNC_DECL): 47 1 48 2009-05-25 Fridrich Strba <fridrich.strba@bluewin.ch> 2 49 -
trunk/WebCore/bindings/js/JSDOMBinding.cpp
r43153 r44135 505 505 } 506 506 507 bool shouldAllowNavigation(ExecState* exec, Frame* frame) 508 { 509 Frame* lexicalFrame = toLexicalFrame(exec); 510 return lexicalFrame && lexicalFrame->loader()->shouldAllowNavigation(frame); 511 } 512 507 513 void printErrorMessageForFrame(Frame* frame, const String& message) 508 514 { … … 512 518 window->printErrorMessage(message); 513 519 } 520 521 Frame* toLexicalFrame(ExecState* exec) 522 { 523 return asJSDOMWindow(exec->lexicalGlobalObject())->impl()->frame(); 524 } 525 526 bool processingUserGesture(ExecState* exec) 527 { 528 Frame* frame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); 529 return frame && frame->script()->processingUserGesture(); 530 } 531 532 KURL completeURL(ExecState* exec, const String& relativeURL) 533 { 534 // For histoical reasons, we need to complete the URL using the dynamic frame. 535 Frame* frame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); 536 if (!frame) 537 return KURL(); 538 return frame->loader()->completeURL(relativeURL); 539 } 540 514 541 515 542 JSValue objectToStringFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) -
trunk/WebCore/bindings/js/JSDOMBinding.h
r43661 r44135 184 184 bool allowsAccessFromFrame(JSC::ExecState*, Frame*); 185 185 bool allowsAccessFromFrame(JSC::ExecState*, Frame*, String& message); 186 bool shouldAllowNavigation(JSC::ExecState*, Frame*); 186 187 void printErrorMessageForFrame(Frame*, const String& message); 187 188 JSC::JSValue objectToStringFunctionGetter(JSC::ExecState*, const JSC::Identifier& propertyName, const JSC::PropertySlot&); 189 190 Frame* toLexicalFrame(JSC::ExecState*); 191 bool processingUserGesture(JSC::ExecState*); 192 KURL completeURL(JSC::ExecState*, const String& relativeURL); 188 193 189 194 } // namespace WebCore -
trunk/WebCore/bindings/js/JSDOMWindowCustom.cpp
r44124 r44135 180 180 void JSDOMWindow::setLocation(ExecState* exec, JSValue value) 181 181 { 182 Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();183 if (! activeFrame)182 Frame* lexicalFrame = toLexicalFrame(exec); 183 if (!lexicalFrame) 184 184 return; 185 185 … … 187 187 // To avoid breaking old widgets, make "var location =" in a top-level frame create 188 188 // a property named "location" instead of performing a navigation (<rdar://problem/5688039>). 189 if (Settings* settings = activeFrame->settings()) {190 if (settings->usesDashboardBackwardCompatibilityMode() && ! activeFrame->tree()->parent()) {189 if (Settings* settings = lexicalFrame->settings()) { 190 if (settings->usesDashboardBackwardCompatibilityMode() && !lexicalFrame->tree()->parent()) { 191 191 if (allowsAccessFrom(exec)) 192 192 putDirect(Identifier(exec, "location"), value); … … 196 196 #endif 197 197 198 if (!activeFrame->loader()->shouldAllowNavigation(impl()->frame())) 198 Frame* frame = impl()->frame(); 199 ASSERT(frame); 200 201 if (!shouldAllowNavigation(exec, frame)) 199 202 return; 200 String dstUrl = activeFrame->loader()->completeURL(value.toString(exec)).string(); 201 if (!protocolIsJavaScript(dstUrl) || allowsAccessFrom(exec)) { 202 bool userGesture = activeFrame->script()->processingUserGesture(); 203 204 KURL url = completeURL(exec, value.toString(exec)); 205 if (url.isNull()) 206 return; 207 208 if (!protocolIsJavaScript(url) || allowsAccessFrom(exec)) { 203 209 // We want a new history item if this JS was called via a user gesture 204 impl()->frame()->loader()->scheduleLocationChange(dstUrl, activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture);210 frame->loader()->scheduleLocationChange(url, lexicalFrame->loader()->outgoingReferrer(), !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, processingUserGesture(exec)); 205 211 } 206 212 } -
trunk/WebCore/bindings/js/JSLocationCustom.cpp
r43929 r44135 146 146 static void navigateIfAllowed(ExecState* exec, Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList) 147 147 { 148 Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); 149 if (!protocolIsJavaScript(url) || allowsAccessFromFrame(exec, frame)) { 150 bool userGesture = activeFrame->script()->processingUserGesture(); 151 frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, userGesture); 152 } 148 Frame* lexicalFrame = toLexicalFrame(exec); 149 if (!lexicalFrame) 150 return; 151 152 if (!protocolIsJavaScript(url) || allowsAccessFromFrame(exec, frame)) 153 frame->loader()->scheduleLocationChange(url.string(), lexicalFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture(exec)); 153 154 } 154 155 … … 158 159 ASSERT(frame); 159 160 160 Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();161 if (!activeFrame)162 return; 163 if (!activeFrame->loader()->shouldAllowNavigation(frame))164 return;165 166 KURL url = activeFrame->loader()->completeURL(value.toString(exec)); 161 if (!shouldAllowNavigation(exec, frame)) 162 return; 163 164 KURL url = completeURL(exec, value.toString(exec)); 165 if (url.isNull()) 166 return; 167 167 168 navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); 168 169 } … … 262 263 return jsUndefined(); 263 264 264 Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); 265 if (!activeFrame) 266 return jsUndefined(); 267 if (!activeFrame->loader()->shouldAllowNavigation(frame)) 268 return jsUndefined(); 269 270 navigateIfAllowed(exec, frame, activeFrame->loader()->completeURL(args.at(0).toString(exec)), true, true); 265 if (!shouldAllowNavigation(exec, frame)) 266 return jsUndefined(); 267 268 KURL url = completeURL(exec, args.at(0).toString(exec)); 269 if (url.isNull()) 270 return jsUndefined(); 271 272 navigateIfAllowed(exec, frame, url, true, true); 271 273 return jsUndefined(); 272 274 } … … 275 277 { 276 278 Frame* frame = impl()->frame(); 279 if (!frame || !allowsAccessFromFrame(exec, frame)) 280 return jsUndefined(); 281 282 if (!protocolIsJavaScript(frame->loader()->url())) 283 frame->loader()->scheduleRefresh(processingUserGesture(exec)); 284 return jsUndefined(); 285 } 286 287 JSValue JSLocation::assign(ExecState* exec, const ArgList& args) 288 { 289 Frame* frame = impl()->frame(); 277 290 if (!frame) 278 291 return jsUndefined(); 279 292 280 JSDOMWindow* window = toJSDOMWindow(frame); 281 if (!window->allowsAccessFrom(exec)) 282 return jsUndefined(); 283 284 if (!protocolIsJavaScript(frame->loader()->url()) || (window && window->allowsAccessFrom(exec))) { 285 bool userGesture = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame()->script()->processingUserGesture(); 286 frame->loader()->scheduleRefresh(userGesture); 287 } 293 if (!shouldAllowNavigation(exec, frame)) 294 return jsUndefined(); 295 296 KURL url = completeURL(exec, args.at(0).toString(exec)); 297 if (url.isNull()) 298 return jsUndefined(); 299 300 // We want a new history item if this JS was called via a user gesture 301 navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); 288 302 return jsUndefined(); 289 303 } 290 304 291 JSValue JSLocation::assign(ExecState* exec, const ArgList& args)292 {293 Frame* frame = impl()->frame();294 if (!frame)295 return jsUndefined();296 297 Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();298 if (!activeFrame)299 return jsUndefined();300 if (!activeFrame->loader()->shouldAllowNavigation(frame))301 return jsUndefined();302 303 // We want a new history item if this JS was called via a user gesture304 navigateIfAllowed(exec, frame, activeFrame->loader()->completeURL(args.at(0).toString(exec)), !frame->script()->anyPageIsProcessingUserGesture(), false);305 return jsUndefined();306 }307 308 305 JSValue JSLocation::toString(ExecState* exec, const ArgList&) 309 306 { 310 307 Frame* frame = impl()->frame(); 311 if (!frame) 312 return jsUndefined(); 313 if (!allowsAccessFromFrame(exec, frame)) 308 if (!frame || !allowsAccessFromFrame(exec, frame)) 314 309 return jsUndefined(); 315 310 … … 319 314 bool JSLocationPrototype::customPut(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&) 320 315 { 316 return (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf); 317 } 318 319 void JSLocationPrototype::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) 320 { 321 321 if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf) 322 return true;323 return false;324 }325 326 void JSLocationPrototype::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction)327 {328 if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf)329 322 return; 330 323 Base::defineGetter(exec, propertyName, getterFunction); -
trunk/WebCore/bindings/v8/V8Utilities.cpp
r42647 r44135 38 38 39 39 #include <wtf/Assertions.h> 40 #include "Frame.h" 40 41 41 42 namespace WebCore { … … 72 73 } 73 74 75 bool processingUserGesture() 76 { 77 Frame* frame = V8Proxy::retrieveFrameForEnteredContext(); 78 return frame && frame->script()->processingUserGesture(); 79 } 80 81 bool shouldAllowNavigation(Frame* frame) 82 { 83 Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext(); 84 return callingFrame && callingFrame->loader()->shouldAllowNavigation(frame); 85 } 86 87 KURL completeURL(const String& relativeURL) 88 { 89 // For histoical reasons, we need to complete the URL using the dynamic frame. 90 Frame* frame = V8Proxy::retrieveFrameForEnteredContext(); 91 if (!frame) 92 return KURL(); 93 return frame->loader()->completeURL(relativeURL); 94 } 95 96 void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList) 97 { 98 Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext(); 99 if (!callingFrame) 100 return; 101 102 if (!protocolIsJavaScript(url) || ScriptController::isSafeScript(frame)) 103 frame->loader()->scheduleLocationChange(url.string(), callingFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture()); 104 } 105 74 106 } // namespace WebCore -
trunk/WebCore/bindings/v8/V8Utilities.h
r42647 r44135 36 36 namespace WebCore { 37 37 38 class Frame; 39 class KURL; 40 class String; 41 38 42 // Use an array to hold dependents. It works like a ref-counted scheme. 39 43 // A value can be added more than once to the DOM object. … … 41 45 void removeHiddenDependency(v8::Local<v8::Object>, v8::Local<v8::Value>, int cacheIndex); 42 46 47 bool processingUserGesture(); 48 bool shouldAllowNavigation(Frame* frame); 49 KURL completeURL(const String& relativeURL); 50 void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList); 51 43 52 } // namespace WebCore 44 53 -
trunk/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
r44124 r44135 36 36 #include "V8CustomEventListener.h" 37 37 #include "V8Proxy.h" 38 #include "V8Utilities.h" 38 39 39 40 #include "Base64.h" … … 802 803 803 804 804 void V8Custom::WindowSetLocation(DOMWindow* window, const String& v) 805 { 806 if (!window->frame()) 805 void V8Custom::WindowSetLocation(DOMWindow* window, const String& relativeURL) 806 { 807 Frame* frame = window->frame(); 808 if (!frame) 807 809 return; 808 810 809 Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); 810 if (!activeFrame) 811 if (!shouldAllowNavigation(frame)) 811 812 return; 812 813 813 if (!activeFrame->loader()->shouldAllowNavigation(window->frame())) 814 KURL url = completeURL(relativeURL); 815 if (url.isNull()) 814 816 return; 815 817 816 if (!parseURL(v).startsWith("javascript:", false) 817 || ScriptController::isSafeScript(window->frame())) { 818 String completedUrl = activeFrame->loader()->completeURL(v).string(); 819 820 // FIXME: The JSC bindings pass !anyPageIsProcessingUserGesture() for 821 // the lockHistory parameter. We should probably do something similar. 822 823 window->frame()->loader()->scheduleLocationChange(completedUrl, 824 activeFrame->loader()->outgoingReferrer(), false, false, 825 activeFrame->script()->processingUserGesture()); 826 } 818 navigateIfAllowed(frame, url, false, false); 827 819 } 828 820 -
trunk/WebCore/bindings/v8/custom/V8LocationCustom.cpp
r43512 r44135 36 36 #include "V8CustomEventListener.h" 37 37 #include "V8Location.h" 38 #include "V8Utilities.h" 38 39 #include "V8Proxy.h" 39 40 … … 52 53 // methods to the scriptController, we should be able to unify the code 53 54 // between JSC and V8: 54 // retrieveActiveFrame() - in JSC, this needs an ExecState.55 // toCallingFrame() - in JSC, this needs an ExecState. 55 56 // isSafeScript() 56 // Since JSC and V8 have different mechanisms for getting at the ActiveFrame,57 // Since JSC and V8 have different mechanisms for getting at the calling frame, 57 58 // we're just making all these custom for now. The functionality is simple 58 59 // and mirrors JSLocationCustom.cpp. 59 60 static void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList)61 {62 if (url.isEmpty())63 return;64 65 Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext();66 if (!activeFrame)67 return;68 69 if (!url.protocolIs("javascript") || ScriptController::isSafeScript(frame)) {70 bool userGesture = activeFrame->script()->processingUserGesture();71 frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, userGesture);72 }73 }74 60 75 61 ACCESSOR_SETTER(LocationHash) … … 138 124 v8::Handle<v8::Object> holder = info.Holder(); 139 125 Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); 140 String href = toWebCoreString(value); 141 142 Frame* frame = imp->frame(); 143 if (!frame) 144 return; 145 146 Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); 147 if (!activeFrame) 148 return; 149 150 if (!activeFrame->loader()->shouldAllowNavigation(frame)) 151 return; 152 153 navigateIfAllowed(frame, activeFrame->loader()->completeURL(href), false, false); 126 127 Frame* frame = imp->frame(); 128 if (!frame) 129 return; 130 131 if (!shouldAllowNavigation(frame)) 132 return; 133 134 KURL url = completeURL(toWebCoreString(value)); 135 if (url.isNull()) 136 return; 137 138 navigateIfAllowed(frame, url, false, false); 154 139 } 155 140 … … 286 271 287 272 Frame* frame = imp->frame(); 288 if (!frame) 289 return v8::Undefined(); 290 291 Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); 292 if (!activeFrame) 293 return v8::Undefined(); 294 295 if (!ScriptController::isSafeScript(frame)) 296 return v8::Undefined(); 297 298 bool userGesture = activeFrame->script()->processingUserGesture(); 299 frame->loader()->scheduleRefresh(userGesture); 273 if (!frame || !ScriptController::isSafeScript(frame)) 274 return v8::Undefined(); 275 276 if (!protocolIsJavaScript(frame->loader()->url())) 277 frame->loader()->scheduleRefresh(processingUserGesture()); 300 278 return v8::Undefined(); 301 279 } … … 306 284 v8::Handle<v8::Value> holder = args.Holder(); 307 285 Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); 308 String url = toWebCoreString(args[0]); 309 310 Frame* frame = imp->frame(); 311 if (!frame) 312 return v8::Undefined(); 313 314 Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); 315 if (!activeFrame) 316 return v8::Undefined(); 317 318 if (!activeFrame->loader()->shouldAllowNavigation(frame)) 319 return v8::Undefined(); 320 321 navigateIfAllowed(frame, activeFrame->loader()->completeURL(url), true, true); 286 287 Frame* frame = imp->frame(); 288 if (!frame) 289 return v8::Undefined(); 290 291 if (!shouldAllowNavigation(frame)) 292 return v8::Undefined(); 293 294 KURL url = completeURL(toWebCoreString(args[0])); 295 if (url.isNull()) 296 return v8::Undefined(); 297 298 navigateIfAllowed(frame, url, true, true); 322 299 return v8::Undefined(); 323 300 } … … 328 305 v8::Handle<v8::Value> holder = args.Holder(); 329 306 Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); 330 String url = toWebCoreString(args[0]); 331 332 Frame* frame = imp->frame(); 333 if (!frame) 334 return v8::Undefined(); 335 336 Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); 337 if (!activeFrame) 338 return v8::Undefined(); 339 340 if (!activeFrame->loader()->shouldAllowNavigation(frame)) 341 return v8::Undefined(); 342 343 navigateIfAllowed(frame, activeFrame->loader()->completeURL(url), false, false); 307 308 Frame* frame = imp->frame(); 309 if (!frame) 310 return v8::Undefined(); 311 312 if (!shouldAllowNavigation(frame)) 313 return v8::Undefined(); 314 315 KURL url = completeURL(toWebCoreString(args[0])); 316 if (url.isNull()) 317 return v8::Undefined(); 318 319 navigateIfAllowed(frame, url, false, false); 344 320 return v8::Undefined(); 345 321 }
Note: See TracChangeset
for help on using the changeset viewer.