From 065e8ea3cfe9eadd803cee2238e41837e0b327b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ce=CC=81dric=20Luthi?= Date: Thu, 14 May 2015 09:49:03 +0200 Subject: [PATCH] Add a fake window.navigator object in the JavaScript context The JavaScript execution of the player script would fail with `TypeError: undefined is not an object (evaluating 'window.navigator.j')` before it could evaluate the parts required to descramble the signature. Fixes #144 --- CHANGELOG.md | 4 ++++ README.md | 2 +- .../project.pbxproj | 4 ++-- XCDYouTubeKit.podspec | 2 +- XCDYouTubeKit/XCDYouTubePlayerScript.m | 17 +++++++++++------ 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50463460..5b4d3359 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +#### Version 2.1.3 + +* Adaptation to YouTube API change. (#144) + #### Version 2.1.2 * Fixed playback of some protected videos. (#122) diff --git a/README.md b/README.md index e4ea946c..e910c4a6 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ These steps will ensure that `#import ` will work **Warning**: If you use the iOS static library and you are targeting iOS 7, add the JavaScriptCore framework. If you are targeting iOS 5 or 6, you must add the following *Other Linker Flags* instead to your app: ``` --Wl,-U,_JSContextGetGlobalObject -Wl,-U,_JSEvaluateScript -Wl,-U,_JSGlobalContextCreate -Wl,-U,_JSGlobalContextRelease -Wl,-U,_JSObjectCallAsFunction -Wl,-U,_JSObjectGetPrototype -Wl,-U,_JSObjectIsFunction -Wl,-U,_JSObjectSetProperty -Wl,-U,_JSStringCopyCFString -Wl,-U,_JSStringCreateWithCFString -Wl,-U,_JSStringRelease -Wl,-U,_JSValueIsObject -Wl,-U,_JSValueIsString -Wl,-U,_JSValueMakeString -Wl,-U,_JSValueToStringCopy +-Wl,-U,_JSContextGetGlobalObject -Wl,-U,_JSEvaluateScript -Wl,-U,_JSGlobalContextCreate -Wl,-U,_JSGlobalContextRelease -Wl,-U,_JSObjectCallAsFunction -Wl,-U,_JSObjectIsFunction -Wl,-U,_JSObjectMake -Wl,-U,_JSObjectSetProperty -Wl,-U,_JSStringCopyCFString -Wl,-U,_JSStringCreateWithCFString -Wl,-U,_JSStringRelease -Wl,-U,_JSValueIsObject -Wl,-U,_JSValueIsString -Wl,-U,_JSValueMakeString -Wl,-U,_JSValueToStringCopy ``` See my [JavaScriptCore framework availability on iOS](http://stackoverflow.com/questions/23514579/javascriptcore-framework-availability-on-ios/23514580#23514580) answer on Stack Overflow for a complete explanation. diff --git a/XCDYouTubeKit Demo/XCDYouTubeKit Demo.xcodeproj/project.pbxproj b/XCDYouTubeKit Demo/XCDYouTubeKit Demo.xcodeproj/project.pbxproj index 556e4eab..27b3a28a 100644 --- a/XCDYouTubeKit Demo/XCDYouTubeKit Demo.xcodeproj/project.pbxproj +++ b/XCDYouTubeKit Demo/XCDYouTubeKit Demo.xcodeproj/project.pbxproj @@ -507,8 +507,8 @@ "-Wl,-U,_JSGlobalContextCreate", "-Wl,-U,_JSGlobalContextRelease", "-Wl,-U,_JSObjectCallAsFunction", - "-Wl,-U,_JSObjectGetPrototype", "-Wl,-U,_JSObjectIsFunction", + "-Wl,-U,_JSObjectMake", "-Wl,-U,_JSObjectSetProperty", "-Wl,-U,_JSStringCopyCFString", "-Wl,-U,_JSStringCreateWithCFString", @@ -538,8 +538,8 @@ "-Wl,-U,_JSGlobalContextCreate", "-Wl,-U,_JSGlobalContextRelease", "-Wl,-U,_JSObjectCallAsFunction", - "-Wl,-U,_JSObjectGetPrototype", "-Wl,-U,_JSObjectIsFunction", + "-Wl,-U,_JSObjectMake", "-Wl,-U,_JSObjectSetProperty", "-Wl,-U,_JSStringCopyCFString", "-Wl,-U,_JSStringCreateWithCFString", diff --git a/XCDYouTubeKit.podspec b/XCDYouTubeKit.podspec index daa93ccf..e90a8b27 100644 --- a/XCDYouTubeKit.podspec +++ b/XCDYouTubeKit.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| s.public_header_files = "XCDYouTubeKit/XCDYouTube{Client,Error,Kit,Operation,Video,VideoOperation,VideoPlayerViewController}.h" s.osx.exclude_files = "XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.{h,m}" s.ios.frameworks = "MediaPlayer" - s.ios.xcconfig = { "OTHER_LDFLAGS" => "-Wl,-U,_JSContextGetGlobalObject -Wl,-U,_JSEvaluateScript -Wl,-U,_JSGlobalContextCreate -Wl,-U,_JSGlobalContextRelease -Wl,-U,_JSObjectCallAsFunction -Wl,-U,_JSObjectGetPrototype -Wl,-U,_JSObjectIsFunction -Wl,-U,_JSObjectSetProperty -Wl,-U,_JSStringCopyCFString -Wl,-U,_JSStringCreateWithCFString -Wl,-U,_JSStringRelease -Wl,-U,_JSValueIsObject -Wl,-U,_JSValueIsString -Wl,-U,_JSValueMakeString -Wl,-U,_JSValueToStringCopy" } + s.ios.xcconfig = { "OTHER_LDFLAGS" => "-Wl,-U,_JSContextGetGlobalObject -Wl,-U,_JSEvaluateScript -Wl,-U,_JSGlobalContextCreate -Wl,-U,_JSGlobalContextRelease -Wl,-U,_JSObjectCallAsFunction -Wl,-U,_JSObjectIsFunction -Wl,-U,_JSObjectMake -Wl,-U,_JSObjectSetProperty -Wl,-U,_JSStringCopyCFString -Wl,-U,_JSStringCreateWithCFString -Wl,-U,_JSStringRelease -Wl,-U,_JSValueIsObject -Wl,-U,_JSValueIsString -Wl,-U,_JSValueMakeString -Wl,-U,_JSValueToStringCopy" } s.osx.frameworks = "JavaScriptCore" s.requires_arc = true end diff --git a/XCDYouTubeKit/XCDYouTubePlayerScript.m b/XCDYouTubeKit/XCDYouTubePlayerScript.m index 326f185e..3373fda4 100644 --- a/XCDYouTubeKit/XCDYouTubePlayerScript.m +++ b/XCDYouTubeKit/XCDYouTubePlayerScript.m @@ -33,13 +33,18 @@ - (instancetype) initWithString:(NSString *)string _context = JSGlobalContextCreate(NULL); - for (NSString *propertyName in @[ @"window", @"document", @"navigator" ]) + for (NSString *propertyPath in @[ @"window.navigator", @"document", @"navigator" ]) { - JSObjectRef globalObject = JSContextGetGlobalObject(_context); - JSStringRef propertyNameRef = JSStringCreateWithCFString((__bridge CFStringRef)propertyName); - JSValueRef dummyValueRef = JSObjectGetPrototype(_context, globalObject); - JSObjectSetProperty(_context, globalObject, propertyNameRef, dummyValueRef, 0, NULL); - JSStringRelease(propertyNameRef); + JSObjectRef object = JSContextGetGlobalObject(_context); + for (NSString *propertyName in [propertyPath componentsSeparatedByString:@"."]) + { + JSStringRef propertyNameRef = JSStringCreateWithCFString((__bridge CFStringRef)propertyName); + JSObjectRef defaultObject = JSObjectMake(_context, NULL, NULL); + JSObjectSetProperty(_context, object, propertyNameRef, defaultObject, 0, NULL); + JSStringRelease(propertyNameRef); + + object = defaultObject; + } } JSStringRef scriptRef = JSStringCreateWithCFString((__bridge CFStringRef)script);