ObjCPlugin.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
  3. * Copyright (C) 2006 James G. Speth (speth@end.com)
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
  15. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  17. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
  18. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  19. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  20. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  21. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  22. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #import "config.h"
  27. #import "ObjCPlugin.h"
  28. #import <WebKit/WebKit.h>
  29. #import <objc/runtime.h>
  30. // === NSObject category to expose almost everything to JavaScript ===
  31. // Warning: this class introduces huge security weaknesses, and should only be used
  32. // for testing inside of DumpRenderTree, and only with trusted code. By default, it has
  33. // the same restrictive behavior as the standard WebKit setup. However, scripts can use the
  34. // plugin's removeBridgeRestrictions: method to open up almost total access to the Cocoa
  35. // frameworks.
  36. static BOOL _allowsScriptsFullAccess = NO;
  37. @interface NSObject (ObjCScriptAccess)
  38. + (void)setAllowsScriptsFullAccess:(BOOL)value;
  39. + (BOOL)allowsScriptsFullAccess;
  40. @end
  41. @implementation NSObject (ObjCScriptAccess)
  42. + (void)setAllowsScriptsFullAccess:(BOOL)value
  43. {
  44. _allowsScriptsFullAccess = value;
  45. }
  46. + (BOOL)allowsScriptsFullAccess
  47. {
  48. return _allowsScriptsFullAccess;
  49. }
  50. + (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
  51. {
  52. return !_allowsScriptsFullAccess;
  53. }
  54. + (NSString *)webScriptNameForSelector:(SEL)selector
  55. {
  56. return nil;
  57. }
  58. @end
  59. @interface JSObjC : NSObject {
  60. }
  61. // expose some useful objc functions to the scripting environment
  62. - (id)lookUpClass:(NSString *)name;
  63. - (void)log:(NSString *)message;
  64. - (id)retainObject:(id)obj;
  65. - (id)classOfObject:(id)obj;
  66. - (NSString *)classNameOfObject:(id)obj;
  67. @end
  68. @implementation JSObjC
  69. + (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
  70. {
  71. return NO;
  72. }
  73. + (NSString *)webScriptNameForSelector:(SEL)selector
  74. {
  75. return nil;
  76. }
  77. - (id)invokeDefaultMethodWithArguments:(NSArray *)args
  78. {
  79. // this is a useful shortcut for accessing objective-c classes from the scripting
  80. // environment, e.g. 'var myObject = objc("NSObject").alloc().init();'
  81. if ([args count] == 1)
  82. return [self lookUpClass:[args objectAtIndex:0]];
  83. return nil;
  84. }
  85. - (id)lookUpClass:(NSString *)name
  86. {
  87. return NSClassFromString(name);
  88. }
  89. - (void)log:(NSString *)message
  90. {
  91. NSLog(@"%@", message);
  92. }
  93. - (id)retainObject:(id)obj
  94. {
  95. return [obj retain];
  96. }
  97. - (id)classOfObject:(id)obj
  98. {
  99. return (id)[obj class];
  100. }
  101. - (NSString *)classNameOfObject:(id)obj
  102. {
  103. return [obj className];
  104. }
  105. @end
  106. @implementation ObjCPlugin
  107. + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
  108. {
  109. if (aSelector == @selector(removeBridgeRestrictions:))
  110. return NO;
  111. if (aSelector == @selector(echo:))
  112. return NO;
  113. if (aSelector == @selector(throwIfArgumentIsNotHello:))
  114. return NO;
  115. if (aSelector == @selector(methodMappedToLongName))
  116. return NO;
  117. NSString *selectorName = NSStringFromSelector(aSelector);
  118. if ([selectorName hasPrefix:@"testConversion"])
  119. return NO;
  120. return YES;
  121. }
  122. + (NSString *)webScriptNameForSelector:(SEL)aSelector
  123. {
  124. if (aSelector == @selector(echo:))
  125. return @"echo";
  126. if (aSelector == @selector(throwIfArgumentIsNotHello:))
  127. return @"throwIfArgumentIsNotHello";
  128. if (aSelector == @selector(methodMappedToLongName))
  129. return [@"" stringByPaddingToLength:4096 withString: @"long" startingAtIndex:0];
  130. return nil;
  131. }
  132. + (NSString *)webScriptNameForKey:(const char *)key
  133. {
  134. if (strcmp(key, "throwOnDealloc") == 0)
  135. return @"throwOnDealloc";
  136. return nil;
  137. }
  138. + (BOOL)isKeyExcludedFromWebScript:(const char *)key
  139. {
  140. if (strcmp(key, "throwOnDealloc") == 0)
  141. return NO;
  142. return YES;
  143. }
  144. - (void)removeBridgeRestrictions:(id)container
  145. {
  146. // let scripts invoke any selector
  147. [NSObject setAllowsScriptsFullAccess:YES];
  148. // store a JSObjC instance into the provided container
  149. JSObjC *objc = [[JSObjC alloc] init];
  150. [container setValue:objc forKey:@"objc"];
  151. [objc release];
  152. }
  153. - (id)echo:(id)obj
  154. {
  155. return obj;
  156. }
  157. - (void)throwIfArgumentIsNotHello:(NSString *)str
  158. {
  159. if (![str isEqualToString:@"Hello"])
  160. [WebScriptObject throwException:[NSString stringWithFormat:@"%@ != Hello", str]];
  161. }
  162. - (NSString *)methodMappedToLongName
  163. {
  164. return @"methodMappedToLongName";
  165. }
  166. - (NSString *)testConversionColon:(int)useless
  167. {
  168. return @"testConversionColon:(int)useless";
  169. }
  170. - (NSString *)testConversionEscapeChar$a_b$_:(int)useless
  171. {
  172. return @"testConversionEscapeChar$a_b$_:(int)useless";
  173. }
  174. - (void)dealloc
  175. {
  176. if (throwOnDealloc)
  177. [WebScriptObject throwException:@"Throwing exception on dealloc of ObjCPlugin"];
  178. [super dealloc];
  179. }
  180. @end