Guest User

Untitled

a guest
Mar 7th, 2017
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 189.28 KB | None | 0 0
  1.  
  2. var _proxy_jslib_SCRIPT_NAME= "/nph-proxy.pl" ;
  3. var _proxy_jslib_SCRIPT_URL= "http://hideip.pw/nph-proxy.pl" ;
  4. var _proxy_jslib_THIS_HOST= "hideip.pw" ;
  5. var _proxy_jslib_PROXY_GROUP= [] ;
  6. var _proxy_jslib_ALL_TYPES= ['', 'application/x-javascript', 'application/x-ecmascript', 'application/x-vbscript', 'application/x-perlscript', 'application/javascript', 'application/ecmascript', 'text/javascript', 'text/ecmascript', 'text/jscript', 'text/livescript', 'text/vbscript', 'text/vbs', 'text/perlscript', 'text/tcl', 'text/x-scriptlet', 'text/scriptlet', 'application/hta', 'application/x-shockwave-flash', 'text/css', 'x-proxy/xhr'] ;
  7. var _proxy_jslib_MIME_TYPE_ID= {'':0, 'text/javascript':7, 'application/x-javascript':1, 'application/x-perlscript':4, 'application/x-vbscript':3, 'x-proxy/xhr':20, 'text/tcl':14, 'text/vbs':12, 'text/jscript':9, 'text/ecmascript':8, 'application/javascript':5, 'text/perlscript':13, 'text/livescript':10, 'application/ecmascript':6, 'application/x-ecmascript':2, 'text/vbscript':11, 'text/x-scriptlet':15, 'text/css':19, 'application/x-shockwave-flash':18, 'text/scriptlet':16, 'application/hta':17} ;
  8.  
  9.  
  10. function _proxy_jslib_proxy_encode(URL) {
  11. URL= URL.replace(/^([\w\+\.\-]+)\:\/\//, '$1/') ;
  12. // URL= URL.replace(/(.)/g, function (s,p1) { return p1.charCodeAt(0).toString(16) } ) ;
  13. // URL= URL.replace(/([a-mA-M])|[n-zN-Z]/g, function (s,p1) { return String.fromCharCode(s.charCodeAt(0)+(p1?13:-13)) }) ;
  14.  
  15. return URL ;
  16. }
  17.  
  18. function _proxy_jslib_proxy_decode(enc_URL) {
  19. // enc_URL= enc_URL.replace(/([a-mA-M])|[n-zN-Z]/g, function (s,p1) { return String.fromCharCode(s.charCodeAt(0)+(p1?13:-13)) }) ;
  20. // enc_URL= enc_URL.replace(/([\da-fA-F]{2})/g, function (s,p1) { return String.fromCharCode(eval('0x'+p1)) } ) ;
  21. enc_URL= enc_URL.replace(/^([\w\+\.\-]+)\//, '$1://') ;
  22. return enc_URL ;
  23. }
  24.  
  25. function _proxy_jslib_cookie_encode(cookie) {
  26. // cookie= cookie.replace(/(.)/g, function (s,p1) { return p1.charCodeAt(0).toString(16) } ) ;
  27. // cookie= cookie.replace(/([a-mA-M])|[n-zN-Z]/g, function (s,p1) { return String.fromCharCode(s.charCodeAt(0)+(p1?13:-13)) }) ;
  28. cookie= cookie.replace(/(\W)/g, function (s,p1) { return '%'+p1.charCodeAt(0).toString(16) } ) ;
  29. return cookie ;
  30. }
  31.  
  32. function _proxy_jslib_cookie_decode(enc_cookie) {
  33. enc_cookie= enc_cookie.replace(/%([\da-fA-F]{2})/g, function (s,p1) { return String.fromCharCode(eval('0x'+p1)) } ) ;
  34. // enc_cookie= enc_cookie.replace(/([a-mA-M])|[n-zN-Z]/g, function (s,p1) { return String.fromCharCode(s.charCodeAt(0)+(p1?13:-13)) }) ;
  35. // enc_cookie= enc_cookie.replace(/([\da-fA-F]{2})/g, function (s,p1) { return String.fromCharCode(eval('0x'+p1)) } ) ;
  36. return enc_cookie ;
  37. }
  38.  
  39.  
  40.  
  41.  
  42. var _proxy_jslib_browser_family ;
  43. var _proxy_jslib_RE_FULL_PATH ;
  44. var _proxy_jslib_url_start, _proxy_jslib_url_start_inframe, _proxy_jslib_url_start_noframe,
  45. _proxy_jslib_base_unframes,
  46. _proxy_jslib_is_in_frame, _proxy_jslib_lang, _proxy_jslib_flags, _proxy_jslib_URL, _proxy_jslib_origin ;
  47. var _proxy_jslib_cookies_are_banned_here, _proxy_jslib_doing_insert_here, _proxy_jslib_SESSION_COOKIES_ONLY,
  48. _proxy_jslib_COOKIE_PATH_FOLLOWS_SPEC, _proxy_jslib_RESPECT_THREE_DOT_RULE,
  49. _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, _proxy_jslib_RTMP_SERVER_PORT,
  50. _proxy_jslib_default_script_type, _proxy_jslib_default_style_type,
  51. _proxy_jslib_USE_DB_FOR_COOKIES, _proxy_jslib_PROXIFY_COMMENTS, _proxy_jslib_COOKIES_FROM_DB,
  52. _proxy_jslib_csp, _proxy_jslib_csp_st, _proxy_jslib_csp_is_supported, _proxy_jslib_eval_ok,
  53. _proxy_jslib_ALERT_ON_CSP_VIOLATIONi, _proxy_jslib_TIMEOUT_MULTIPLIER ;
  54. var _proxy_jslib_RE, _proxy_jslib_ARRAY64, _proxy_jslib_UNARRAY64 ;
  55. var _proxy_jslib_does_write ;
  56. var _proxy_jslib_write_buffers= [ {doc:document, has_jslib:true} ] ;
  57. var _proxy_jslib_locations= [] ;
  58. var _proxy_jslib_xhrwins= [] ;
  59. var _proxy_jslib_ret ;
  60. var _proxy_jslib_temp_counter= 1000 ;
  61. var _proxy_jslib_current_object_classid ;
  62. var _proxy_jslib_increments= {applets: 0, embeds: 0, forms: 0, ids: 0, layers: 0, anchors: 0, images: 0, links: 0} ;
  63.  
  64. // these must be updated when adding handled properties to _handle() or _assign()!
  65. var _proxy_jslib_handle_properties= 'eval insertAdjacentHTML setAttribute setAttributeNode getAttribute value insertRule innerHTML outerHTML outerText src currentSrc href background lowsrc action formAction useMap longDesc cite codeBase location poster open write writeln URL url newURL oldURL referrer baseURI body parentNode toString String setInterval setTimeout cookie domain frames parent top opener protocol host hostname port pathname search setStringValue setProperty setNamedItem load execScript navigate showModalDialog showModelessDialog addImport execCommand LoadMovie getElementById getElementsByTagName appendChild replaceChild insertBefore removeChild createElement text close origin postMessage pushState replaceState localStorage sessionStorage querySelector querySelectorAll send setRequestHeader'.split(/\s+/) ;
  66.  
  67. var _proxy_jslib_assign_properties= 'background src href lowsrc action useMap longDesc cite codeBase location poster profile cssText innerHTML outerHTML outerText nodeValue protocol host hostname port pathname search cookie domain value backgroundImage content cursor listStyle listStyleImage text textContent withCredentials'.split(/\s+/) ;
  68.  
  69. var _proxy_jslib_handle_props_hash, _proxy_jslib_assign_props_hash ;
  70.  
  71.  
  72. // Hack for sites that redefine core JavaScript objects. :P
  73. // Add more properties as needed.
  74. //var _proxy_jslib_ORIGINAL_ARRAY= {push: Array.prototype.push} ; // for some reason this doesn't work
  75. // This fails in MSIE, so put them in try/catch.
  76. try { var _proxy_jslib_ORIGINAL_ARRAY_push= Array.prototype.push } catch(e) {}
  77. try { var _proxy_jslib_ORIGINAL_WINDOW_alert= Window.prototype.alert } catch(e) {}
  78.  
  79.  
  80.  
  81. //---- first, the initialization functions -----------------------------
  82.  
  83. // set _proxy_jslib_URL, _proxy_jslib_url_start, _proxy_jslib_lang, _proxy_jslib_flags,
  84. // _proxy_jslib_is_in_frame, _proxy_jslib_url_start_inframe, _proxy_jslib_url_start_noframe
  85. function _proxy_jslib_init() {
  86. _proxy_jslib_csp_is_supported= _proxy_jslib_csp_is_supported_test() ;
  87.  
  88. _proxy_jslib_browser_family=
  89. navigator.appName.match(/Netscape/i) ? 'netscape'
  90. : navigator.appName.match(/Microsoft/i) ? 'msie'
  91. : '' ;
  92.  
  93. _proxy_jslib_set_RE() ;
  94.  
  95. _proxy_jslib_ARRAY64=
  96. '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split('') ;
  97. _proxy_jslib_UNARRAY64= {} ;
  98. for (var i= 0 ; i<64 ; i++) { _proxy_jslib_UNARRAY64[_proxy_jslib_ARRAY64[i]]= i }
  99.  
  100.  
  101. // initialize property-list hashes for _proxy_jslib_handle() and
  102. // _proxy_jslib_assign()
  103. _proxy_jslib_handle_props_hash= {} ;
  104. for (var i= 0 ; i<_proxy_jslib_handle_properties.length ; i++)
  105. _proxy_jslib_handle_props_hash['p_'+_proxy_jslib_handle_properties[i]]= true ;
  106. _proxy_jslib_assign_props_hash= {} ;
  107. for (var i= 0 ; i<_proxy_jslib_assign_properties.length ; i++)
  108. _proxy_jslib_assign_props_hash['p_'+_proxy_jslib_assign_properties[i]]= true ;
  109.  
  110.  
  111. // Mozilla sometimes adds 'wyciwyg://' to the URL
  112. var URL= document.URL.replace(/^wyciwyg:\/\/\d+\//i, '') ;
  113.  
  114. var u= _proxy_jslib_parse_full_url(URL) ;
  115.  
  116. _proxy_jslib_lang= u[1] ;
  117. _proxy_jslib_flags= _proxy_jslib_unpack_flags(u[2]) ;
  118. _proxy_jslib_URL= u[3] ;
  119. _proxy_jslib_flags[6]= '' ; // set expected type = none
  120.  
  121. if (_proxy_jslib_PROXY_GROUP.length) {
  122. _proxy_jslib_url_start= _proxy_jslib_PROXY_GROUP[Math.floor(Math.random()*_proxy_jslib_PROXY_GROUP.length)]
  123. +'/'+u[1]+'/'+_proxy_jslib_pack_flags(_proxy_jslib_flags)+'/' ;
  124. } else {
  125. _proxy_jslib_url_start= u[0]+'/'+u[1]+'/'+_proxy_jslib_pack_flags(_proxy_jslib_flags)+'/' ;
  126. }
  127. _proxy_jslib_is_in_frame= _proxy_jslib_flags[5] ;
  128. _proxy_jslib_flags[5]= 1 ; // that's the frame flag
  129. _proxy_jslib_url_start_inframe= u[0]+'/'+u[1]+'/'+_proxy_jslib_pack_flags(_proxy_jslib_flags)+'/' ;
  130. _proxy_jslib_flags[5]= 0 ;
  131. _proxy_jslib_url_start_noframe= u[0]+'/'+u[1]+'/'+_proxy_jslib_pack_flags(_proxy_jslib_flags)+'/' ;
  132. _proxy_jslib_flags[5]= _proxy_jslib_is_in_frame ;
  133.  
  134. // this begins life as the hostname. document.URL may not be set yet, so send URL.
  135. _proxy_jslib_init_domain(window, _proxy_jslib_URL) ;
  136.  
  137. _proxy_jslib_eval_ok= _proxy_jslib_match_csp_source_list(_proxy_jslib_csp['script-src'], "'unsafe-eval'") ;
  138.  
  139. // call _proxy_jslib_onload() and possibly an existing window.onload()
  140. // make sure _proxy_jslib_onload() is called even if window.onload() fails.
  141. var old_onload= window.onload ;
  142. window.onload= function() {
  143. try { if (old_onload) old_onload() } catch(e) {} ;
  144. _proxy_jslib_onload() ;
  145. }
  146.  
  147. //alert('end of init; _p_j_URL=\n['+_proxy_jslib_URL+']') ;
  148. }
  149.  
  150.  
  151. // set variables passed in from Perl program.
  152. function _proxy_jslib_pass_vars(base_url, origin, cookies_are_banned_here, doing_insert_here, SESSION_COOKIES_ONLY, COOKIE_PATH_FOLLOWS_SPEC, RESPECT_THREE_DOT_RULE, ALLOW_UNPROXIFIED_SCRIPTS, RTMP_SERVER_PORT, default_script_type, default_style_type, USE_DB_FOR_COOKIES, PROXIFY_COMMENTS, ALERT_ON_CSP_VIOLATION, COOKIES_FROM_DB, TIMEOUT_MULTIPLIER, csp) {
  153. // create global regex that matches a full URL, needed for _proxy_jslib_parse_full_url()
  154. // if being run from a daemon, make this something that won't choke inside parens
  155. var RE_SCRIPT_NAME= (_proxy_jslib_SCRIPT_NAME!='')
  156. ? _proxy_jslib_SCRIPT_NAME.replace(/(\W)/g, function (p) { return '\\'+p } )
  157. : '.{0}' ; // because "()" in a regex may throw an error
  158. _proxy_jslib_RE_FULL_PATH= new RegExp('^('+RE_SCRIPT_NAME+')\\/?([^\\/]*)\\/?([^\\/]*)\\/?(.*)') ;
  159.  
  160. // set base_ vars from base_url
  161. _proxy_jslib_set_base_vars(window.document, base_url) ;
  162.  
  163. // other settings
  164. _proxy_jslib_origin= origin ;
  165. _proxy_jslib_cookies_are_banned_here= cookies_are_banned_here ;
  166. _proxy_jslib_doing_insert_here= doing_insert_here ;
  167. _proxy_jslib_SESSION_COOKIES_ONLY= SESSION_COOKIES_ONLY ;
  168. _proxy_jslib_COOKIE_PATH_FOLLOWS_SPEC= COOKIE_PATH_FOLLOWS_SPEC ;
  169. _proxy_jslib_RESPECT_THREE_DOT_RULE= RESPECT_THREE_DOT_RULE ;
  170. _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS= ALLOW_UNPROXIFIED_SCRIPTS ;
  171. _proxy_jslib_USE_DB_FOR_COOKIES= USE_DB_FOR_COOKIES ;
  172. _proxy_jslib_PROXIFY_COMMENTS= PROXIFY_COMMENTS ;
  173. _proxy_jslib_ALERT_ON_CSP_VIOLATION= ALERT_ON_CSP_VIOLATION ;
  174. _proxy_jslib_COOKIES_FROM_DB= COOKIES_FROM_DB ;
  175. _proxy_jslib_TIMEOUT_MULTIPLIER= TIMEOUT_MULTIPLIER ;
  176. _proxy_jslib_RTMP_SERVER_PORT= RTMP_SERVER_PORT || 1935 ; // jsm-- get a better solution...
  177.  
  178. _proxy_jslib_default_script_type= default_script_type.toLowerCase() ;
  179. _proxy_jslib_default_style_type= default_style_type.toLowerCase() ;
  180.  
  181. _proxy_jslib_csp= (csp!='') ? eval('(' + csp + ')') || {} : {} ; // plain "{...}" in eval is treated as a block
  182. _proxy_jslib_csp_st= csp ; // save JSON string for later
  183.  
  184.  
  185. _proxy_jslib_init() ;
  186. }
  187.  
  188.  
  189. // lastly, do what's needed after the document fully loads
  190. function _proxy_jslib_onload() {
  191.  
  192. // if we're in frames, then try to update the URL in the top form
  193. if (_proxy_jslib_is_in_frame && (window.parent===window.top) && top._proxy_jslib_insertion_frame)
  194. top._proxy_jslib_insertion_frame.document.URLform.URL.value= _proxy_jslib_URL ;
  195.  
  196. }
  197.  
  198.  
  199. //---- the general handler routines _proxy_jslib_handle() and _proxy_jslib_assign() ----
  200.  
  201. // This is used when the property in question IS NOT being assigned to.
  202. function _proxy_jslib_handle (o, property, cur_val, calls_now, in_new_statement) {
  203. // performance tweak
  204. if (typeof(property)=='number') return _handle_default() ;
  205.  
  206. // guess when the window object is implied; this only matters with Window's
  207. // properties that we handle below
  208. if ((o===null) && (typeof(property)=='string') && property.match(/^(location|open|setInterval|setTimeout|frames|parent|top|opener|execScript|navigate|showModalDialog|showModelessDialog|parentWindow|String)$/) && (window[property]===cur_val)) o= window ;
  209.  
  210. // handle eval() specially-- it (oddly) can be a property of any object
  211. if (property=='eval') {
  212. if (!_proxy_jslib_eval_ok) _proxy_jslib_throw_csp_error("disallowed eval in handle()") ;
  213. if ((o!=null) && (o.eval)) {
  214. var oldeval= o.eval ;
  215. return function (code) {
  216. // return o.eval(_proxy_jslib_proxify_js(code, 0)) ;
  217. var ret ;
  218. o._proxy_jslib_oldeval= oldeval ;
  219. ret= o._proxy_jslib_oldeval(_proxy_jslib_proxify_js(code, 0)) ;
  220. delete o._proxy_jslib_oldeval ;
  221. return ret ;
  222. } ;
  223. } else {
  224. if (o!=null) return undefined ;
  225. var oldeval= eval ;
  226. return function (code) {
  227. return oldeval(_proxy_jslib_proxify_js(code, 0)) ;
  228. } ;
  229. }
  230. }
  231.  
  232. // if object is still null, merely return property value
  233. if (o==null) return cur_val ;
  234.  
  235.  
  236. // allow things like "if (element.insertAdjacentHTML)" to work as expected
  237. if (typeof(o)=='object' && !(property in o)) return void 0 ;
  238.  
  239.  
  240. // StorageList needs unique handling
  241. // Safari chokes here, so wrap in try/catch
  242. // jsm-- don't think this is correct....
  243. // try {
  244. // if ((_proxy_jslib_browser_family!='msie') && (o instanceof StorageList)) {
  245. // return o[property+'.cgiproxy.'+_proxy_jslib_THIS_HOST] ;
  246. // }
  247. // } catch(e) {} ;
  248.  
  249.  
  250. // performance tweak
  251. if (!_proxy_jslib_handle_props_hash['p_'+property]) return _handle_default() ;
  252.  
  253.  
  254. // If object is an XML Element, don't proxify anything. There is no
  255. // explicit XMLElement type, but any Element that's not HTMLElement is
  256. // an XML Element.
  257. // This should be cleaned up and possibly merged with _p_j_instanceof().
  258. if (_proxy_jslib_instanceof(o, 'Element') && !_proxy_jslib_instanceof(o, 'HTMLElement')) {
  259. return _handle_default() ;
  260. }
  261.  
  262.  
  263. // Main switch
  264.  
  265. // note use of closures to remember the object o
  266. // note also that in returned functions, we use "this" if it is available;
  267. // see comments above proxify_js() (Perl routine)
  268. // Store new windows in a list so we can insert JS later if needed.
  269. // Store windows instead of documents, because docs may not be created yet.
  270.  
  271. switch (property) {
  272.  
  273. // because some sites modify these in place, we must un-proxify these
  274. // when retrieving the value.
  275. // for Link objects, return the object, but handle toString() below to unproxify it when needed.
  276. // jsm-- this will still leave Link proxified when toString() is called implicitly.
  277. case 'src':
  278. case 'href':
  279. case 'background':
  280. case 'lowsrc':
  281. case 'action':
  282. case 'formAction':
  283. case 'useMap':
  284. case 'longDesc':
  285. case 'cite':
  286. case 'codeBase':
  287. case 'baseURI':
  288. case 'poster':
  289. var u= (o!=void 0) ? o[property] : cur_val ;
  290. if (u==void 0) return void 0 ;
  291. if (typeof u=='number') return u ;
  292. if (typeof u=='function') return _handle_default() ;
  293. // return unchanged if u is a non-String object
  294. if (u && (typeof u=='object') && !('toLowerCase' in u)) return u ;
  295. // return unchanged if o is not a Node
  296. if (!_proxy_jslib_instanceof(o, 'Node')) return u ;
  297. var pu= _proxy_jslib_parse_full_url(u) ;
  298. if (pu==void 0) return u ; // if it's not a URL
  299. //if (u=='') alert('in handle, first switch; typeof, o, property, u, caller=['+typeof(o)+']['+o+']['+property+']['+u+']\n['+arguments.callee.caller.caller+']') ;
  300. return pu[3] ;
  301.  
  302.  
  303. case 'location':
  304. if (_proxy_jslib_instanceof(o, 'Window') || _proxy_jslib_instanceof(o, 'Document')) {
  305. return _proxy_jslib_dup_location(o) ;
  306. } else {
  307. return _handle_default() ;
  308. }
  309.  
  310.  
  311. case 'open':
  312. if (_proxy_jslib_instanceof(o, 'XMLHttpRequest') || _proxy_jslib_instanceof(o, 'AnonXMLHttpRequest')) {
  313. return function(method, url, asyncflag, username, password) {
  314. if (typeof o._proxy_jslib_xhrdata.win=='number')
  315. o._proxy_jslib_xhrdata.win= _proxy_jslib_xhrwins[o._proxy_jslib_xhrdata.win] ;
  316.  
  317. // This follows the algorithm in the XMLHttpSpec version 2, section 4.71, at
  318. // http://www.w3.org/TR/XMLHttpRequest2/#the-open-method
  319.  
  320. url= _proxy_jslib_absolute_url(url.toString(), o._proxy_jslib_xhrdata.win.document) ;
  321. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['connect-src'], url))
  322. _proxy_jslib_throw_csp_error('connect-src violation in XHR.open()') ;
  323. if (this!==window) o= this ;
  324.  
  325. if (method.match(/^(?:CONNECT|DELETE|GET|HEAD|OPTIONS|POST|PUT|TRACE|TRACK)$/i))
  326. method= method.toUpperCase() ;
  327. if (method.match(/^(?:CONNECT|TRACE|TRACK)$/))
  328. throw new Error('SecurityError in XMLHttpRequest.open(): method is [' + method + ']') ;
  329.  
  330. var xhr_base_url= url.replace(/#.*/, '') ;
  331. var pu= _proxy_jslib_parse_url(xhr_base_url) ;
  332. var tup= pu[2].match(/^([^:]*):?(.*)/) ;
  333. var temp_user= tup[1] ;
  334. var temp_pwd= tup[2] ;
  335.  
  336. if ( !((arguments.length==2) ? true : asyncflag) && o._proxy_jslib_xhrdata.win.document
  337. && (o.timeout!=0 || o.withCredentials || o.responseType!='') )
  338. throw new Error('InvalidAccessError in XMLHttpRequest.open()') ;
  339.  
  340. if (arguments.length>=4) {
  341. if (username!=null && !_proxy_jslib_same_origin(url, o._proxy_jslib_xhrdata.origin))
  342. throw new Error('InvalidAccessError in XMLHttpRequest.open()') ;
  343. temp_user= username ;
  344. }
  345. if (arguments.length>=5) {
  346. if (password!=null && !_proxy_jslib_same_origin(url, o._proxy_jslib_xhrdata.origin))
  347. throw new Error('InvalidAccessError in XMLHttpRequest.open()') ;
  348. temp_pwd= password ;
  349. }
  350.  
  351. o._proxy_jslib_xhrdata.url= url ;
  352. o._proxy_jslib_xhrdata.method= method ;
  353. o._proxy_jslib_xhrdata.username= temp_user ;
  354. o._proxy_jslib_xhrdata.password= temp_pwd ;
  355. o._proxy_jslib_xhrdata.headers= {} ;
  356.  
  357. // proxify the URL using 'x-proxy/xhr' as the expected type
  358. var flags_5= _proxy_jslib_flags[5] ;
  359. var flags_6= _proxy_jslib_flags[6] ;
  360. _proxy_jslib_flags[5]= 1 ; // because of how this is used, don't insert the top form
  361. _proxy_jslib_flags[6]= 'x-proxy/xhr' ;
  362. var old_url_start= _proxy_jslib_url_start ;
  363.  
  364. try {
  365. _proxy_jslib_url_start= _proxy_jslib_url_start_by_flags(_proxy_jslib_flags) ;
  366. if (!_proxy_jslib_same_origin(url, o._proxy_jslib_xhrdata.origin)) {
  367. url= url.replace(/\:\/\//, '/') ; // scheme://rest -> scheme/rest
  368. var origin= o._proxy_jslib_xhrdata.origin.replace(/\//g, '%2f') ;
  369. var headers= '' ;
  370. for (var name in o._proxy_jslib_xhrdata.headers) headers+= name + ':' ;
  371. if (headers!='') headers= headers.replace(/:$/, '') ;
  372. else headers= ':' ; // avoid empty path segment
  373. var omit_credentials= o.withCredentials ? 0 : 1 ;
  374. url= _proxy_jslib_full_url('x-proxy://xhr/' + origin + '/' + headers
  375. + '/' + omit_credentials + '/' + url) ;
  376. } else {
  377. url= _proxy_jslib_full_url(url) ;
  378. }
  379. } finally {
  380. _proxy_jslib_url_start= old_url_start ;
  381. _proxy_jslib_flags[5]= flags_5 ;
  382. _proxy_jslib_flags[6]= flags_6 ;
  383. }
  384.  
  385. // false asyncflag would make connection synchronous
  386. if (arguments.length==2) {
  387. return o.open(method, url) ;
  388. } else {
  389. o._proxy_jslib_xhrdata.sync= !asyncflag ;
  390. return o.open(method, url, asyncflag, username, password) ;
  391. }
  392. } ;
  393.  
  394. } else if (_proxy_jslib_instanceof(o, 'Window')) {
  395. return function (url, name, features, replace) {
  396. if (this!==window) o= this ;
  397. var full_url= _proxy_jslib_full_url(url) ;
  398. var win= o.open(full_url, name, features, replace) ;
  399. if (url) _proxy_jslib_init_domain(win) ;
  400. // in the absence of spec, "about:blank" domain is that of parent window
  401. else win._proxy_jslib_document_domain= o._proxy_jslib_document_domain ;
  402. return win ;
  403. } ;
  404.  
  405. } else if (_proxy_jslib_instanceof(o, 'Document')) {
  406. return function(arg1, name, features, replace) {
  407. // arg1 should default to "text/html", but it doesn't
  408. // always in Firefox, so we force it
  409. if (arg1==void 0) arg1= 'text/html' ;
  410. if (this!==window) o= this ;
  411. if (arguments.length<=2) {
  412. return o.open(arg1, name) ;
  413. } else {
  414. // MSIE-specific
  415. return o.open(_proxy_jslib_full_url(arg1, o), name, features, replace) ;
  416. }
  417. } ;
  418. } else {
  419. return _handle_default() ;
  420. }
  421.  
  422.  
  423. case 'send':
  424. if (_proxy_jslib_instanceof(o, 'XMLHttpRequest') || _proxy_jslib_instanceof(o, 'AnonXMLHttpRequest')) {
  425. return function(data) {
  426. // this follows the algorithm in the XMLHttpRequest 2 spec, at
  427. // http://www.w3.org/TR/XMLHttpRequest2/#the-send-method
  428. var body, result ;
  429. if (o._proxy_jslib_xhrdata.method.match(/^(GET|HEAD)$/)) {
  430. data= null ;
  431. }
  432. if (arguments.length>0 && data!=null) {
  433. var encoding= null ;
  434. var mime_type= null ;
  435. try {
  436. if (data instanceof ArrayBuffer) { // MSIE chokes on this
  437. body= data ;
  438. } else if (data instanceof Blob) {
  439. if (data.type!='') mime_type= data.type ;
  440. body= data ;
  441. } else if (_proxy_jslib_instanceof(data, 'Document')) {
  442. encoding= data.charset ;
  443. mime_type= 'text/html;charset=' + encoding ;
  444. body= data.documentElement.innerHTML ;
  445. } else if (typeof data=='string') {
  446. encoding= 'UTF-8' ;
  447. mime_type= 'text/plain;charset=UTF-8' ;
  448. body= data ;
  449. } else if (data instanceof FormData) {
  450. body= data ;
  451. }
  452. } catch(e) {
  453. body= data ;
  454. }
  455. if (encoding!=null && o._proxy_jslib_xhrdata.headers['content-type']) {
  456. // should modify existing header, but can't
  457. o._proxy_jslib_xhrdata.headers['content-type']=
  458. o._proxy_jslib_xhrdata.headers['content-type']
  459. .replace(/\bcharset=[\w.$-]+/, 'charset='+encoding) ;
  460. }
  461. if (mime_type!=null && !o._proxy_jslib_xhrdata.headers['content-type']) {
  462. o.setRequestHeader('Content-Type', mime_type) ;
  463. o._proxy_jslib_xhrdata.headers['content-type']= mime_type ;
  464. }
  465. } else {
  466. body= null ;
  467. }
  468. if (!o._proxy_jslib_xhrdata.sync) o._proxy_jslib_xhrdata.upload_events_flag= 1 ;
  469. o._proxy_jslib_xhrdata.error_flag= 0 ;
  470. if (body=='' || body==null) o._proxy_jslib_xhrdata.upload_complete_flag= 1 ;
  471. if (o._proxy_jslib_xhrdata.sync) {
  472. o._proxy_jslib_xhrdata.send_flag= 1 ;
  473. o.dispatchEvent(o._proxy_jslib_xhrdata.win.document.createEvent('Event')
  474. .initEvent('readystatechange', false, false)) ;
  475. o.dispatchEvent(o._proxy_jslib_xhrdata.win.document.createEvent('ProgressEvent')
  476. .initEvent('loadstart', false, false)) ;
  477. if (!o._proxy_jslib_xhrdata.upload_complete_flag)
  478. o.upload.dispatchEvent(o._proxy_jslib_xhrdata.win.document.createEvent('ProgressEvent')
  479. .initEvent('loadstart', false, false)) ;
  480. }
  481. // this happens regardless of same/cross-origin, sync flag, etc.
  482. // all request event rules are handled on the server
  483. return o.send(body) ;
  484. } ;
  485. } else {
  486. return _handle_default() ;
  487. }
  488.  
  489.  
  490. case 'setRequestHeader':
  491. if (_proxy_jslib_instanceof(o, 'XMLHttpRequest') || _proxy_jslib_instanceof(o, 'AnonXMLHttpRequest')) {
  492. return function(name, value) {
  493. if (name.match(/[^\x00-\xff]/)) throw new SyntaxError() ;
  494. if ((''+value).match(/[^\x00-\xff]/)) throw new SyntaxError() ;
  495.  
  496. name= name.toLowerCase() ;
  497. if (name.match(/^(?:Accept-Charset|Accept-Encoding|Access-Control-Request-Headers|Access-Control-Request-Method|Connection|Content-Length|Cookie|Cookie2|Content-Transfer-Encoding|Date|Expect|Host|Keep-Alive|Origin|Referer|TE|Trailer|Transfer-Encoding|Upgrade|User-Agent|Via)$|^(?:Proxy-|Sec-)/i))
  498. return ;
  499.  
  500. if (name in o._proxy_jslib_xhrdata.headers) {
  501. o._proxy_jslib_xhrdata.headers[name]+= ', ' + value ;
  502. } else {
  503. o._proxy_jslib_xhrdata.headers[name]= value ;
  504. }
  505. return o.setRequestHeader(name, value) ;
  506. } ;
  507. } else {
  508. return _handle_default() ;
  509. }
  510.  
  511.  
  512. case 'write':
  513. if (_proxy_jslib_instanceof(o, 'Document')) {
  514. // buffer the output by document
  515. // no return value
  516. return function () {
  517. if (this!==window) o= this ;
  518. for (var i= 0 ; i<arguments.length ; i++)
  519. _proxy_jslib_write_via_buffer(o, arguments[i]) ;
  520. } ;
  521. } else {
  522. return _handle_default() ;
  523. }
  524. case 'writeln':
  525. if (_proxy_jslib_instanceof(o, 'Document')) {
  526. // buffer the output by document
  527. // no return value
  528. return function () {
  529. if (this!==window) o= this ;
  530. for (var i= 0 ; i<arguments.length ; i++)
  531. _proxy_jslib_write_via_buffer(o, arguments[i]) ;
  532. _proxy_jslib_write_via_buffer(o, '\n') ;
  533. } ;
  534. } else {
  535. return _handle_default() ;
  536. }
  537.  
  538.  
  539. case 'close':
  540. if (_proxy_jslib_instanceof(o, 'Document')) {
  541. return function() {
  542. if (this!==window) o= this ;
  543. var buf, i, p ;
  544. for (i in _proxy_jslib_write_buffers) {
  545. if (_proxy_jslib_write_buffers[i].doc===o) {
  546. buf= _proxy_jslib_write_buffers[i] ;
  547. if (buf.buf==void 0) break ;
  548. p= _proxy_jslib_proxify_html(buf.buf, o, !buf.has_jslib) ;
  549. if (p[3]) return ; // found frame document
  550. //if (confirm('flushing one buffer;\nhas_jslib=['+p[2]+']\nout=['+p[0]+']'))
  551. buf.buf= void 0 ;
  552. buf.has_jslib= false ;
  553. o.write(p[0]) ;
  554. break ;
  555. }
  556. }
  557. //alert('about to o.close()') ;
  558. o.close() ;
  559. //alert('ending Document.close()') ;
  560. } ;
  561. } else {
  562. return _handle_default() ;
  563. }
  564.  
  565.  
  566. case 'innerHTML':
  567. // only unproxify it if the object is an HTMLElement or Document
  568. if ((_proxy_jslib_instanceof(o, 'HTMLElement') || _proxy_jslib_instanceof(o, 'Document'))) {
  569. if (is_in_script(o, property)) {
  570. return _proxy_jslib_proxify_block(o[property], o.type || _proxy_jslib_default_script_type,
  571. true, true) ;
  572. } else {
  573. switch (o.tagName.toLowerCase()) {
  574. case 'style': return _proxy_jslib_proxify_css(o[property], true) ;
  575. case 'script': return _proxy_jslib_proxify_js(o[property], void 0, void 0, void 0, true) ;
  576. default: return _proxy_jslib_proxify_html(o[property], (o.ownerDocument || o), false, true)[0] ;
  577. }
  578. }
  579. } else {
  580. return _handle_default() ;
  581. }
  582.  
  583. case 'outerHTML':
  584. case 'outerText':
  585. // only unproxify it if the object is an HTMLElement or Document
  586. if ((_proxy_jslib_instanceof(o, 'HTMLElement') || _proxy_jslib_instanceof(o, 'Document'))) {
  587. return _proxy_jslib_proxify_html(o[property], (o.ownerDocument || o), false, true)[0] ; // unproxifies
  588. } else {
  589. return _handle_default() ;
  590. }
  591.  
  592.  
  593. case 'url':
  594. if (_proxy_jslib_instanceof(o, 'EventSource')) {
  595. var pu= _proxy_jslib_parse_full_url(o[property]) ;
  596. if (pu==void 0) return void 0 ;
  597. return pu[3] ;
  598. } else {
  599. return _handle_default() ;
  600. }
  601.  
  602. case 'newURL':
  603. case 'oldURL':
  604. if (_proxy_jslib_instanceof(o, 'HashChangeEvent')) {
  605. var pu= _proxy_jslib_parse_full_url(o[property]) ;
  606. if (pu==void 0) return void 0 ;
  607. return pu[3] ;
  608. } else {
  609. return _handle_default() ;
  610. }
  611.  
  612.  
  613.  
  614. case 'getElementById':
  615. if (_proxy_jslib_instanceof(o, 'Document')) {
  616. // Hack-- if element isn't in doc yet but is in output buffer, flush
  617. // buffer and try again.
  618. return function (elementId) {
  619. if (this!==window) o= this ;
  620. var e, i, buf, p ;
  621. e= o.getElementById(elementId) ;
  622. if (e!=null) return e ;
  623. for (i= 0 ; i<_proxy_jslib_write_buffers.length ; i++)
  624. if (_proxy_jslib_write_buffers[i] &&
  625. _proxy_jslib_write_buffers[i].doc===o) break ;
  626. if (i>=_proxy_jslib_write_buffers.length) return null ;
  627. buf= _proxy_jslib_write_buffers[i] ;
  628. if (buf.buf==void 0) return null ;
  629. if (buf.buf.match(new RegExp('\\bid\\s*=\\s*[\'"]?\\s*'+elementId+'\\s*[\'"]?', 'i'))) {
  630. p= _proxy_jslib_proxify_html(buf.buf, o, !buf.has_jslib) ;
  631. if (p[3]) return ; // found frame document
  632. buf.has_jslib= buf.has_jslib || p[2] ;
  633. buf.buf= p[1] ;
  634. o.write(p[0]) ;
  635. }
  636. return o.getElementById(elementId) ;
  637. } ;
  638. } else {
  639. return _handle_default() ;
  640. }
  641.  
  642. case 'getElementsByTagName':
  643. if (_proxy_jslib_instanceof(o, 'Document') || _proxy_jslib_instanceof(o, 'Element')) {
  644. return function (tagname) {
  645. if (this!==window) o= this ;
  646. var i, buf, pi, doc ;
  647. doc= (o.ownerDocument || o) ;
  648. for (i= 0 ; i<_proxy_jslib_write_buffers.length ; i++)
  649. if (_proxy_jslib_write_buffers[i] &&
  650. _proxy_jslib_write_buffers[i].doc===doc) break ;
  651. if (i>=_proxy_jslib_write_buffers.length) return o.getElementsByTagName(tagname) ;
  652. buf= _proxy_jslib_write_buffers[i] ;
  653. if ((buf.buf!=void 0) && (tagname=='*' || buf.buf.match(new RegExp('<'+tagname+'\\b', 'i')))) {
  654. p= _proxy_jslib_proxify_html(buf.buf, doc, !buf.has_jslib) ;
  655. if (p[3]) return ; // found frame document
  656. buf.has_jslib= buf.has_jslib || p[2] ;
  657. buf.buf= p[1] ;
  658. doc.write(p[0]) ;
  659. }
  660. // remove our two initial <script> elements
  661. if (tagname.toLowerCase()=='script') {
  662. var scripts= o.getElementsByTagName(tagname) ;
  663. var ret= [] ;
  664. for (i= 2 ; i<scripts.length ; i++) ret[i-2]= scripts[i] ;
  665. return ret ;
  666. }
  667. return o.getElementsByTagName(tagname) ;
  668. } ;
  669. } else {
  670. return _handle_default() ;
  671. }
  672.  
  673.  
  674. case 'appendChild':
  675. if (_proxy_jslib_instanceof(o, 'Node')) {
  676. return function (child) {
  677. if ((o.nodeName.toLowerCase()=='script') && (child.nodeType==3)) { // TEXT_NODE=3
  678. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['script-src'], "'unsafe-inline'"))
  679. _proxy_jslib_throw_csp_error("CSP script-src inline error") ;
  680. var type= o.type || _proxy_jslib_default_script_type ;
  681. var new_text= _proxy_jslib_proxify_block(child.data, type,
  682. _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, false) ;
  683. return o.appendChild(document.createTextNode(new_text)) ;
  684. } else if ((o.nodeName.toLowerCase()=='style') && child.nodeType==3) {
  685. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['style-src'], "'unsafe-inline'"))
  686. _proxy_jslib_throw_csp_error("CSP style-src inline error") ;
  687. var type= o.type || _proxy_jslib_default_style_type ;
  688. var new_text= _proxy_jslib_proxify_block(child.data, type,
  689. _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, false) ;
  690. return o.appendChild(document.createTextNode(new_text)) ;
  691. } else {
  692. return o.appendChild(child);
  693. }
  694. } ;
  695. } else {
  696. return _handle_default() ;
  697. }
  698.  
  699. case 'replaceChild':
  700. case 'insertBefore':
  701. if (_proxy_jslib_instanceof(o, 'Node')) {
  702. return function (child, old_child) {
  703. var ret ;
  704. if ((o.nodeName.toLowerCase()=='script') && (child.nodeType==3)) { // TEXT_NODE=3
  705. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['script-src'], "'unsafe-inline'"))
  706. _proxy_jslib_throw_csp_error("CSP script-src inline error") ;
  707. var type= o.type || _proxy_jslib_default_script_type ;
  708. var new_text= _proxy_jslib_proxify_block(child.data, type,
  709. _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, false) ;
  710. ret= o[property](document.createTextNode(new_text), old_child) ;
  711. if (property=='replaceChild')
  712. // unfortunately, next line would cause direct loads in some browsers
  713. // ret.textContent= _proxy_jslib_proxify_block(ret.textContent, type, void 0, true) ;
  714. return _proxy_jslib_proxify_block(ret.textContent, type, void 0, true) ;
  715. return ret ;
  716. } else if ((o.nodeName.toLowerCase()=='style') && child.nodeType==3) {
  717. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['style-src'], "'unsafe-inline'"))
  718. _proxy_jslib_throw_csp_error("CSP style-src inline error") ;
  719. var type= o.type || _proxy_jslib_default_style_type ;
  720. var new_text= _proxy_jslib_proxify_block(child.data, type,
  721. _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, false) ;
  722. ret= o[property](document.createTextNode(new_text), old_child) ;
  723. if (property=='replaceChild')
  724. // unfortunately, next line would cause direct loads in some browsers
  725. // ret.textContent= _proxy_jslib_proxify_block(ret.textContent, type, void 0, true) ;
  726. return _proxy_jslib_proxify_block(ret.textContent, type, void 0, true) ;
  727. return ret ;
  728. } else {
  729. while (old_child!=null
  730. && (old_child.className=='_proxy_jslib_jslib'
  731. || old_child.className=='_proxy_jslib_pv'))
  732. old_child= old_child.nextSibling ;
  733. return o[property](child, old_child);
  734. }
  735. } ;
  736. } else {
  737. return _handle_default() ;
  738. }
  739.  
  740. case 'removeChild':
  741. if (_proxy_jslib_instanceof(o, 'Node')) {
  742. return function (old_child) {
  743. var ret= o[property](old_child) ;
  744. var type ;
  745. if (ret.nodeType==3) {
  746. type= (o.nodeName.toLowerCase()=='script') ? (o.type || _proxy_jslib_default_script_type)
  747. : (o.nodeName.toLowerCase()=='style') ? (o.type || _proxy_jslib_default_style_type)
  748. : '' ;
  749. // unfortunately, next line would cause direct loads in some browsers
  750. // ret.textContent= _proxy_jslib_proxify_block(ret.textContent, type, true, true) ;
  751. return _proxy_jslib_proxify_block(ret.textContent, type, true, true) ;
  752. }
  753. return ret ;
  754. } ;
  755. } else {
  756. return _handle_default() ;
  757. }
  758.  
  759. case 'createElement':
  760. if (_proxy_jslib_instanceof(o, 'Document')) {
  761. return function (localName) {
  762. // for when pages redefine createElement()
  763. // jsm-- should use prototype methods everywhere? Note that
  764. // chaining would only work because _proxy_jslib_instanceof()
  765. // would return true, even though instanceof would not work.
  766. //var ret= o.createElement(localName) ;
  767. var p= HTMLDocument.prototype || Document.prototype ;
  768. var ret= p.createElement.call(o, localName) ;
  769. if (localName.toLowerCase()=='iframe')
  770. ret.contentDocument && ret.contentDocument.write(_proxy_jslib_iframe_init_html()) ;
  771. return ret ;
  772. } ;
  773. } else {
  774. return _handle_default() ;
  775. }
  776.  
  777.  
  778. case 'text':
  779. if (_proxy_jslib_instanceof(o, 'Node') && (o.nodeName.toLowerCase()=='script')) {
  780. return _proxy_jslib_proxify_js(o.text, 0, 0, 0, true) ;
  781. } else {
  782. return _handle_default() ;
  783. }
  784.  
  785.  
  786. case 'insertAdjacentHTML':
  787. if (_proxy_jslib_instanceof(o, 'HTMLElement')) {
  788. return function (where, text) {
  789. if (this!==window) o= this ;
  790. return o.insertAdjacentHTML(where, _proxy_jslib_proxify_html(text, o.ownerDocument, false)[0]) ;
  791. } ;
  792. } else {
  793. return _handle_default() ;
  794. }
  795.  
  796. case 'setAttribute':
  797. if (_proxy_jslib_instanceof(o, 'Element')) {
  798. return function (name, value) {
  799. if (this!==window) o= this ;
  800. return o.setAttribute(name.toLowerCase(),
  801. _proxy_jslib_proxify_attribute(o, o.attributes[name], name, value) ) ;
  802. } ;
  803. } else {
  804. return _handle_default() ;
  805. }
  806.  
  807. case 'setAttributeNode':
  808. if (_proxy_jslib_instanceof(o, 'Element')) {
  809. return function (newAttr) {
  810. if (this!==window) o= this ;
  811. newAttr.nodeValue= _proxy_jslib_proxify_attribute(o, newAttr, newAttr.nodeName, newAttr.nodeValue) ;
  812. return o.setAttributeNode(newAttr) ;
  813. } ;
  814. } else {
  815. return _handle_default() ;
  816. }
  817.  
  818. case 'getAttribute':
  819. if (_proxy_jslib_instanceof(o, 'Element')) {
  820. return function (name, flag) {
  821. var attr_val= o.getAttribute(name, flag) ;
  822. return _proxy_jslib_proxify_attribute(o, o.attributes[name], name, attr_val, 1) ;
  823. } ;
  824. } else {
  825. return _handle_default() ;
  826. }
  827.  
  828. case 'value':
  829. if (_proxy_jslib_instanceof(o, 'Attr')) {
  830. return _proxy_jslib_proxify_attribute(void 0, o, o.name, o.value, 1) ;
  831. } else {
  832. return _handle_default() ;
  833. }
  834.  
  835. case 'insertRule':
  836. if (_proxy_jslib_instanceof(o, 'CSSStyleSheet')) {
  837. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['style-src'], "'unsafe-inline'"))
  838. _proxy_jslib_throw_csp_error("CSP style-src inline error") ;
  839. return function (rule, index) {
  840. if (this!==window) o= this ;
  841. return o.insertRule(_proxy_jslib_proxify_css(rule), index) ;
  842. } ;
  843. } else {
  844. return _handle_default() ;
  845. }
  846.  
  847. case 'URL':
  848. case 'referrer':
  849. if (_proxy_jslib_instanceof(o, 'Document')) {
  850. var pu= _proxy_jslib_parse_full_url(o[property]) ;
  851. return ((pu==void 0) || pu[3].match(/^x-proxy/i)) ? null : pu[3] ;
  852. } else {
  853. return _handle_default() ;
  854. }
  855.  
  856. case 'body':
  857. if (_proxy_jslib_instanceof(o, 'Document')) {
  858. var ret= o.getElementById('_proxy_css_main_div') ;
  859. return ret ? ret : o.body ;
  860. } else {
  861. return _handle_default() ;
  862. }
  863.  
  864. case 'parentNode':
  865. if (_proxy_jslib_instanceof(o, 'Node')) {
  866. // return o.id=='_proxy_css_main_div' ? o.ownerDocument.documentElement : o.parentNode ;
  867. return o.id=='_proxy_css_main_div' ? o.parentNode.parentNode : o.parentNode ;
  868. } else {
  869. return _handle_default() ;
  870. }
  871.  
  872. case 'toString':
  873. if (_proxy_jslib_instanceof(o, 'Link')) {
  874. return function () {
  875. if (this!==window) o= this ;
  876. return _proxy_jslib_parse_full_url(o.toString())[3] ;
  877. } ;
  878. } else {
  879. if (typeof o=='function') {
  880. // for Function.toString, unproxify JS code
  881. return function () {
  882. var s= o.toString() ;
  883. return s.match(/^\n?function\b/)
  884. ? _proxy_jslib_proxify_js(s, 0, 0, in_new_statement, true)
  885. : s ;
  886. } ;
  887. } else {
  888. return _handle_default() ;
  889. }
  890. }
  891.  
  892.  
  893. case 'setInterval':
  894. case 'setTimeout':
  895. if (_proxy_jslib_instanceof(o, 'Window')) {
  896. var oldmethod= o[property] ;
  897.  
  898. // Function.apply() not available in MSIE, yet "Function.apply"
  899. // returns true, so just trap all errors.
  900. // jsm-- this will also trap any errors in called routines....
  901. return function (codefunc, time) {
  902.  
  903. time*= _proxy_jslib_TIMEOUT_MULTIPLIER ;
  904.  
  905. if (this!==window) o= this ;
  906. try {
  907. if (typeof(codefunc)=='function') {
  908. return oldmethod.apply(o, arguments) ;
  909. } else {
  910. if (!_proxy_jslib_eval_ok)
  911. _proxy_jslib_throw_csp_error("can't "+property+" without unsafe-eval") ;
  912. return oldmethod.call(o, _proxy_jslib_proxify_js(codefunc), time) ;
  913. }
  914. } catch (e) {
  915. var ret ;
  916. o._proxy_jslib_oldmethod= oldmethod ;
  917. if (typeof(codefunc)=='function') {
  918. ret= o._proxy_jslib_oldmethod(codefunc, time) ;
  919. } else {
  920. if (!_proxy_jslib_eval_ok)
  921. _proxy_jslib_throw_csp_error("can't "+property+" without unsafe-eval") ;
  922. ret= o._proxy_jslib_oldmethod(_proxy_jslib_proxify_js(codefunc), time) ;
  923. }
  924. try {
  925. delete o._proxy_jslib_oldmethod ;
  926. } catch(e) {
  927. }
  928. return ret ;
  929. }
  930. } ;
  931.  
  932. } else {
  933. return _handle_default() ;
  934. }
  935.  
  936.  
  937. case 'cookie':
  938. if (_proxy_jslib_instanceof(o, 'Document')) {
  939. return _proxy_jslib_cookie_from_client(o) ;
  940. } else {
  941. return _handle_default() ;
  942. }
  943.  
  944.  
  945. case 'domain':
  946. if (_proxy_jslib_instanceof(o, 'Document')) {
  947. // technically, Document.domain is just the hostname, though
  948. // the same-origin policy uses scheme, hostname, and port
  949. var w= o.defaultView || o.parentWindow ;
  950. if (!w._proxy_jslib_document_domain) _proxy_jslib_init_domain(w) ;
  951. if (w._proxy_jslib_document_domain.match(/^https?\:\/\//i))
  952. return _proxy_jslib_parse_url(w._proxy_jslib_document_domain)[4] ;
  953. //else alert("bad w._proxy_jslib_document_domain: " + w._proxy_jslib_document_domain) ; // jsm-- remove
  954. } else {
  955. return _handle_default() ;
  956. }
  957.  
  958.  
  959.  
  960. case 'frames':
  961. if (_proxy_jslib_instanceof(o, 'Window')) {
  962. var f, ret= [], useret ;
  963. if (!_proxy_jslib_document_domain) _proxy_jslib_init_domain(window) ;
  964. for (f=0 ; f<o.frames.length ; f++) {
  965. try {
  966. if (!o.frames[f]._proxy_jslib_document_domain) _proxy_jslib_init_domain(o.frames[f]) ;
  967. if ((o.frames[f]._proxy_jslib_document_domain!=_proxy_jslib_document_domain)
  968. && (o.frames[f]._proxy_jslib_document_domain))
  969. {
  970. //alert('frame differs in domain; f, domains of window, o.frames[f]=['+f+']['+_proxy_jslib_document_domain+']['+o.frames[f]._proxy_jslib_document_domain+']') ; // jsm-- test a bunch, then remove
  971. // include both the numbered frame and the (non-standard) named frame
  972. ret[f]= _proxy_jslib_dup_window_safe(o.frames[f]) ;
  973. if (o.frames[f].name) ret[o.frames[f].name]= ret[f] ;
  974. useret= true ;
  975. } else {
  976. ret[f]= o.frames[f] ;
  977. if (o.frames[f].name) ret[o.frames[f].name]= ret[f] ;
  978. }
  979. } catch (e) {
  980. alert('Window.frames error: '+e) ;
  981. }
  982. }
  983. return useret ? ret : o.frames ;
  984.  
  985. } else {
  986. return _handle_default() ;
  987. }
  988.  
  989.  
  990. case 'parent':
  991. if (_proxy_jslib_instanceof(o, 'Window')) {
  992. // if we're in main frame, pretend it's its own "parent".
  993. var w= (o.top._proxy_jslib_main_frame===o) ? o : o.parent ;
  994. if (!_proxy_jslib_document_domain) _proxy_jslib_init_domain(window) ;
  995. if (!w._proxy_jslib_document_domain) _proxy_jslib_init_domain(w) ;
  996. if (w._proxy_jslib_document_domain && (w._proxy_jslib_document_domain!=_proxy_jslib_document_domain)) {
  997. // alert('Tried to access parent window, but has different domain; domains are [' + _proxy_jslib_document_domain + '] and [' + w._proxy_jslib_document_domain + ']') ;
  998. return _proxy_jslib_dup_window_safe(w) ;
  999. }
  1000. return w ;
  1001. } else {
  1002. return _handle_default() ;
  1003. }
  1004.  
  1005. case 'top':
  1006. if (_proxy_jslib_instanceof(o, 'Window')) {
  1007. // if window uses frames, translate "top" to "top._proxy_jslib_main_frame".
  1008. var w= (o.top._proxy_jslib_main_frame!==void 0) ? o.top._proxy_jslib_main_frame : o.top ;
  1009. if (!_proxy_jslib_document_domain) _proxy_jslib_init_domain(window) ;
  1010. if (!w._proxy_jslib_document_domain) _proxy_jslib_init_domain(w) ;
  1011. if (w._proxy_jslib_document_domain && (w._proxy_jslib_document_domain!=_proxy_jslib_document_domain)) {
  1012. // alert('Tried to access top window, but has different domain; domains are [' + _proxy_jslib_document_domain + '] and [' + w._proxy_jslib_document_domain + ']') ;
  1013. return _proxy_jslib_dup_window_safe(w) ;
  1014. }
  1015. return w ;
  1016. } else {
  1017. return _handle_default() ;
  1018. }
  1019.  
  1020. case 'opener':
  1021. if (_proxy_jslib_instanceof(o, 'Window')) {
  1022. if (!o.opener) return null ;
  1023. if (!_proxy_jslib_document_domain) _proxy_jslib_init_domain(window) ;
  1024. if (!o.opener._proxy_jslib_document_domain) _proxy_jslib_init_domain(o.opener) ;
  1025. if (o.opener._proxy_jslib_document_domain && (o.opener._proxy_jslib_document_domain!=_proxy_jslib_document_domain)) {
  1026. // alert('Tried to access opener window, but has different domain; domains are [' + _proxy_jslib_document_domain + '] and [' + w._proxy_jslib_document_domain + ']') ;
  1027. return _proxy_jslib_dup_window_safe(o.opener) ;
  1028. }
  1029. return o.opener ;
  1030. } else {
  1031. return _handle_default() ;
  1032. }
  1033.  
  1034.  
  1035. // _proxy_jslib_parse_url() returns full_match, protocol, authentication, host, hostname, port, pathname, search, hash
  1036.  
  1037. case 'protocol':
  1038. if (_proxy_jslib_instanceof(o, 'Link')) {
  1039. return _proxy_jslib_parse_url(_proxy_jslib_parse_full_url(o.href)[3])[1] ;
  1040. } else {
  1041. return _handle_default() ;
  1042. }
  1043.  
  1044. case 'host':
  1045. if (_proxy_jslib_instanceof(o, 'Link')) {
  1046. return _proxy_jslib_parse_url(_proxy_jslib_parse_full_url(o.href)[3])[3] ;
  1047. } else {
  1048. return _handle_default() ;
  1049. }
  1050.  
  1051. case 'hostname':
  1052. if (_proxy_jslib_instanceof(o, 'Link')) {
  1053. return _proxy_jslib_parse_url(_proxy_jslib_parse_full_url(o.href)[3])[4] ;
  1054. } else {
  1055. return _handle_default() ;
  1056. }
  1057.  
  1058. case 'port':
  1059. if (_proxy_jslib_instanceof(o, 'Link')) {
  1060. return _proxy_jslib_parse_url(_proxy_jslib_parse_full_url(o.href)[3])[5] ;
  1061. } else {
  1062. return _handle_default() ;
  1063. }
  1064.  
  1065. case 'pathname':
  1066. if (_proxy_jslib_instanceof(o, 'Link')) {
  1067. return _proxy_jslib_parse_url(_proxy_jslib_parse_full_url(o.href)[3])[6] ;
  1068. } else {
  1069. return _handle_default() ;
  1070. }
  1071.  
  1072. case 'search':
  1073. if (_proxy_jslib_instanceof(o, 'Link')) {
  1074. return _proxy_jslib_parse_url(_proxy_jslib_parse_full_url(o.href)[3])[7] ;
  1075. } else {
  1076. return _handle_default() ;
  1077. }
  1078.  
  1079.  
  1080.  
  1081. case 'LoadMovie':
  1082. if (_proxy_jslib_instanceof(o, 'FlashPlayer')) {
  1083. return function (layer, url) {
  1084. if (this!==window) o= this ;
  1085. return o.LoadMovie(layer, _proxy_jslib_full_url(url)) ;
  1086. } ;
  1087. } else {
  1088. return _handle_default() ;
  1089. }
  1090.  
  1091.  
  1092. case 'setStringValue':
  1093. if (_proxy_jslib_instanceof(o, 'CSSPrimitiveValue')) {
  1094. return function (type, value) {
  1095. if (this!==window) o= this ;
  1096. if (type==CSSPrimitiveValue.CSS_URI)
  1097. return o.setStringValue(type, _proxy_jslib_full_url(value)) ;
  1098. return o.setStringValue(type, value) ;
  1099. } ;
  1100. } else {
  1101. return _handle_default() ;
  1102. }
  1103.  
  1104. case 'setProperty':
  1105. if (_proxy_jslib_instanceof(o, 'CSSStyleDeclaration')) {
  1106. return function (name, value, priority) {
  1107. if (this!==window) o= this ;
  1108. return o.setProperty(name, _proxy_jslib_proxify_css(value), priority) ;
  1109. } ;
  1110. } else {
  1111. return _handle_default() ;
  1112. }
  1113.  
  1114. case 'setNamedItem':
  1115. if (_proxy_jslib_instanceof(o, 'NamedNodeMap')) {
  1116. return function (node) {
  1117. if (this!==window) o= this ;
  1118. node.nodeValue= _proxy_jslib_proxify_attribute(void 0, node, node.nodeName, node.nodeValue) ;
  1119. return o.setNamedItem(node) ;
  1120. } ;
  1121. } else {
  1122. return _handle_default() ;
  1123. }
  1124.  
  1125.  
  1126. // Deproxify String() parameter if it's a Link or Location
  1127. case 'String':
  1128. if (_proxy_jslib_instanceof(o, 'Window')) {
  1129. return function(s) {
  1130. if (_proxy_jslib_instanceof(s, 'Link'))
  1131. return _proxy_jslib_parse_full_url(s.href)[3];
  1132. return String(s);
  1133. } ;
  1134. } else {
  1135. return _handle_default() ;
  1136. }
  1137.  
  1138.  
  1139. case 'origin':
  1140. if (_proxy_jslib_instanceof(o, 'MessageEvent')) {
  1141. if (o[property]==void 0) return void 0 ;
  1142. if (o[property]=='*') return '*' ;
  1143. if (!o.source) return void 0 ;
  1144. var u= _proxy_jslib_parse_full_url(o.source.location.href)[3] ;
  1145. var pu= _proxy_jslib_parse_url(u) ;
  1146. return pu[1] + '//' + pu[3] ;
  1147. } else {
  1148. return _handle_default() ;
  1149. }
  1150.  
  1151. case 'postMessage':
  1152. if (_proxy_jslib_instanceof(o, 'Window')) {
  1153. return function(message, targetOrigin, ports) {
  1154. return _proxy_jslib_postMessage(o, message, targetOrigin, ports) ;
  1155. } ;
  1156. } else {
  1157. return _handle_default() ;
  1158. }
  1159.  
  1160.  
  1161. case 'pushState':
  1162. case 'replaceState':
  1163. if (_proxy_jslib_instanceof(o, 'History')) {
  1164. return function(data, title, url) {
  1165. // url argument is optional
  1166. if (url==void 0) return o[property](data, title) ;
  1167.  
  1168. // must verify that origins of url and Document match!
  1169. var doc_pu= _proxy_jslib_parse_url(_proxy_jslib_parse_full_url(document.URL)[3]) ;
  1170. var new_url= _proxy_jslib_full_url(url) ;
  1171. var o_pu= _proxy_jslib_parse_url(_proxy_jslib_parse_full_url(new_url)[3]) ;
  1172. if (o_pu[3]!=doc_pu[3]) {
  1173. alert('History.'+property+'() not allowed unless origins match: ['+o_pu[3]+'] ['+doc_pu[3]+']') ;
  1174. return void 0 ;
  1175. }
  1176. return o[property](data, title, new_url) ;
  1177. }
  1178. } else {
  1179. return _handle_default() ;
  1180. }
  1181.  
  1182.  
  1183. case 'currentSrc':
  1184. if (_proxy_jslib_instanceof(o, 'MediaElement')) {
  1185. return _proxy_jslib_parse_full_url(o[property])[3] ;
  1186. } else {
  1187. return _handle_default() ;
  1188. }
  1189.  
  1190.  
  1191. case 'importScripts':
  1192. if (_proxy_jslib_instanceof(o, 'WorkerGlobalScope')) {
  1193. return function() {
  1194. var fakedoc= {URL: o.location} ; // need this for _proxy_jslib_full_url() call
  1195. _proxy_jslib_set_base_vars(fakedoc) ;
  1196. for (var i= 0 ; i<arguments.length ; i++)
  1197. o.importScripts(_proxy_jslib_full_url(arguments[i], fakedoc)) ;
  1198. } ;
  1199. } else {
  1200. return _handle_default() ;
  1201. }
  1202.  
  1203.  
  1204. // Netscape-specific in this block
  1205. case 'load':
  1206. if (_proxy_jslib_instanceof(o, 'Layer')) {
  1207. if (!o.load) return undefined ;
  1208. return function (url, width) {
  1209. if (this!==window) o= this ;
  1210. return o.load(_proxy_jslib_full_url(url), width) ;
  1211. } ;
  1212. } else {
  1213. return _handle_default() ;
  1214. }
  1215.  
  1216.  
  1217.  
  1218. // MSIE-specific in this block
  1219.  
  1220. case 'execScript':
  1221. if (_proxy_jslib_instanceof(o, 'Window')) {
  1222. if (!o.execScript) return undefined ;
  1223. return function(code, language) {
  1224. if (this!==window) o= this ;
  1225. if (language && language.match(/^\s*(javascript|jscript|ecmascript|livescript|$)/i))
  1226. return o.execScript(_proxy_jslib_proxify_js(code), language) ;
  1227. // either disallow or execute unchanged scripts we don't support
  1228. if (_proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS)
  1229. return o.execScript(code, language) ;
  1230. return ;
  1231. } ;
  1232. } else {
  1233. return _handle_default() ;
  1234. }
  1235.  
  1236. case 'navigate':
  1237. if (_proxy_jslib_instanceof(o, 'Window')) {
  1238. if (!o.navigate) return undefined ;
  1239. return function (url) {
  1240. if (this!==window) o= this ;
  1241. return o.navigate(_proxy_jslib_full_url(url, o.document)) ;
  1242. } ;
  1243. } else {
  1244. return _handle_default() ;
  1245. }
  1246.  
  1247. case 'showModalDialog':
  1248. if (_proxy_jslib_instanceof(o, 'Window')) {
  1249. if (!o.showModalDialog) return undefined ;
  1250. return function(url, args, features) {
  1251. if (this!==window) o= this ;
  1252. return o.showModalDialog(_proxy_jslib_full_url(url, o.document), args, features) ;
  1253. } ;
  1254. } else {
  1255. return _handle_default() ;
  1256. }
  1257.  
  1258. case 'showModelessDialog':
  1259. if (_proxy_jslib_instanceof(o, 'Window')) {
  1260. if (!o.showModelessDialog) return undefined ;
  1261. return function(url, args, features) {
  1262. if (this!==window) o= this ;
  1263. return o.showModelessDialog(_proxy_jslib_full_url(url, o.document), args, features) ;
  1264. } ;
  1265. } else {
  1266. return _handle_default() ;
  1267. }
  1268.  
  1269. case 'addImport':
  1270. if (_proxy_jslib_instanceof(o, 'CSSStyleSheet')) {
  1271. if (!o.addImport) return undefined ;
  1272. return function(url, index) {
  1273. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['style-src'], url))
  1274. _proxy_jslib_throw_csp_error("CSP style-src inline error") ;
  1275. if (this!==window) o= this ;
  1276. return o.addImport(_proxy_jslib_full_url(url, o.document), index) ;
  1277. } ;
  1278. } else {
  1279. return _handle_default() ;
  1280. }
  1281.  
  1282.  
  1283. // We can't really support Storage objects well, since we'd need to
  1284. // handle e.g. "localStorage.foo= bar", and a dup'ed Storage object
  1285. // wouldn't have changes reflected in the actual Storage object.
  1286. // getters and setters would require knowing property names in advance.
  1287. case 'localStorage':
  1288. case 'sessionStorage':
  1289. if (_proxy_jslib_instanceof(o, 'Window')) {
  1290. return undefined ;
  1291. } else {
  1292. return _handle_default() ;
  1293. }
  1294.  
  1295.  
  1296. // part of the _proxy_css_main_div hack....
  1297. case 'querySelector':
  1298. case 'querySelectorAll':
  1299. if (_proxy_jslib_instanceof(o, 'Document') || _proxy_jslib_instanceof(o, 'DocumentFragment')) {
  1300. return function(selectors) {
  1301. if (_proxy_jslib_doing_insert_here)
  1302. selectors= selectors.replace(/\bbody\s*>/gi, 'div#_proxy_css_main_div>') ;
  1303. return o[property](selectors) ;
  1304. } ;
  1305. } else {
  1306. return _handle_default() ;
  1307. }
  1308.  
  1309.  
  1310. // Document.execCommand() is a non-standard method supported by both
  1311. // MSIE and Firefox, though they support different sets of commands.
  1312. // Note that values must be proxified relative to the calling Document
  1313. // object, not to the current document.
  1314. case 'execCommand':
  1315. if (_proxy_jslib_instanceof(o, 'Document')) {
  1316. return function(cmd, do_UI, value) {
  1317. var ret ;
  1318. //alert('in execCommand(); params=['+cmd+']['+do_UI+']['+value+']') ; //jsm-- remove
  1319. cmd= cmd.toLowerCase() ;
  1320. if (_proxy_jslib_browser_family=='netscape') {
  1321. if ((cmd=='createlink') || (cmd=='insertimage')) {
  1322. ret= o.execCommand(cmd, do_UI, _proxy_jslib_full_url(value, o)) ;
  1323. } else if (cmd=='inserthtml') {
  1324. ret= o.execCommand(cmd, do_UI, _proxy_jslib_proxify_html(value, o)[0]) ;
  1325. } else {
  1326. ret= o.execCommand(cmd, do_UI, value) ;
  1327. }
  1328. } else if (_proxy_jslib_browser_family=='msie') {
  1329. if ((cmd=='createlink') || (cmd=='insertimage')) {
  1330. ret= o.execCommand(cmd, do_UI, _proxy_jslib_full_url(value, o)) ;
  1331. } else if (cmd.match(/^insert/)) {
  1332. alert('tried to execCommand('+cmd+')') ;
  1333. ret= undefined ;
  1334. } else {
  1335. ret= o.execCommand(cmd, do_UI, value) ;
  1336. }
  1337. }
  1338.  
  1339. return ret ;
  1340. } ;
  1341. } else {
  1342. return _handle_default() ;
  1343. }
  1344.  
  1345.  
  1346.  
  1347. // don't need to handle Document.parentWindow, do we?
  1348.  
  1349.  
  1350. default:
  1351. return _handle_default() ;
  1352.  
  1353. }
  1354.  
  1355.  
  1356.  
  1357.  
  1358. // must be inside _proxy_jslib_handle() to retain o, property for closure
  1359. function _handle_default() {
  1360.  
  1361. if (calls_now && !in_new_statement && (typeof(o[property])=='function')) {
  1362. // Firefox (erroneously) reports that typeof(Function.prototype)
  1363. // is 'function', not 'object' as it should be.
  1364. if (o==Function && property=='prototype') return o[property] ;
  1365.  
  1366. var fn= o[property] ;
  1367. var ret= function () {
  1368. // Handle "phantom functions"-- sometimes Firefox
  1369. // seems to create Function objects with no
  1370. // properties, where typeof=='function' but there
  1371. // is no apply() method, where the constructor of
  1372. // the function is undefined, and where
  1373. // "fn instanceof Function" is false. These were
  1374. // causing CNN video controls to not work. Oddly,
  1375. // calling the phantom function with parameters
  1376. // somehow makes it work-- does it alter a property
  1377. // value, a flag, or what? I don't know.
  1378. // Additionally, calling the function via eval does
  1379. // not make it work, so we can't use the first
  1380. // method below. Possibly this is because of the
  1381. // closure and the scope of o and property. Also,
  1382. // calling fn() doesn't make it work, even though
  1383. // fn was set to o[property] .
  1384. if (fn.apply==void 0) {
  1385. // This doesn't work. :P
  1386. //var argst= '' ;
  1387. //for (var i= 0 ; i<arguments.length ; i++)
  1388. // argst+= 'arguments['+i+'],' ;
  1389. //argst= argst.slice(0, -1) ;
  1390. //eval('return o[property]('+argst+')') ;
  1391.  
  1392. // lame! will fail when arguments.length>10 .
  1393. return o[property](arguments[0], arguments[1],
  1394. arguments[2], arguments[3],
  1395. arguments[4], arguments[5],
  1396. arguments[6], arguments[7],
  1397. arguments[8], arguments[9]) ;
  1398. }
  1399.  
  1400. // Function.apply() not available in MSIE :P
  1401. if (this!==window) {
  1402. return fn.apply(this, arguments) ;
  1403. } else {
  1404. return fn.apply(o, arguments) ;
  1405. }
  1406. } ;
  1407. // must copy all other properties too, in case anything's dereferenced
  1408. for (var p in o[property]) ret[p]= o[property][p] ;
  1409. return ret ;
  1410.  
  1411. } else {
  1412. try {
  1413. // hack for weird MSIE bug-- for some reason, it can't always
  1414. // access Element.getElementsByTagName() .
  1415. if (_proxy_jslib_browser_family=='msie' && property=='getElementsByTagName')
  1416. return function(tagname) {
  1417. if (this!==window) o= this ;
  1418. return o.getElementsByTagName(tagname) ;
  1419. } ;
  1420.  
  1421. return o[property] ;
  1422.  
  1423. } catch(e) {
  1424. //alert('in _handle_default() catch block; property=['+property+']; e=['+e+']') ;
  1425. return undefined ;
  1426. }
  1427. }
  1428.  
  1429. }
  1430.  
  1431.  
  1432. }
  1433.  
  1434.  
  1435.  
  1436. // This is used when the property in question IS being assigned to, WITH an object.
  1437. function _proxy_jslib_assign (prefix, o, property, op, val) {
  1438. var new_val ;
  1439.  
  1440. // handle prefix
  1441. if (prefix=='delete') return delete o[property] ;
  1442. if (prefix=='++') {
  1443. val= o[property]+1 ;
  1444. op= '=' ;
  1445. } else if (prefix=='--') {
  1446. val= o[property]-1 ;
  1447. op= '=' ;
  1448. }
  1449.  
  1450. // sanity check
  1451. //if (o==null) alert('in assign, o is null, property, caller=\n['+property+']\n['+arguments.callee.caller+']') ; // jsm-- remove in production release?
  1452.  
  1453. // performance tweak
  1454. if (!_proxy_jslib_assign_props_hash['p_'+property]) return _assign_default() ;
  1455.  
  1456. var opmod= op.match(/=/) ? op.replace(/=$/, '') : '' ;
  1457.  
  1458. var u ;
  1459. if (_proxy_jslib_instanceof(o, 'Link') || _proxy_jslib_instanceof(o, 'Location'))
  1460. u= _proxy_jslib_parse_url(_proxy_jslib_instanceof(o, 'Link') ? _proxy_jslib_parse_full_url(o.href)[3] : o.href) ;
  1461. // u[] has full_match, protocol, authentication, host, hostname, port, pathname, search, hash
  1462.  
  1463.  
  1464. // For unknown object types, transform common URL properties such as "src".
  1465. // It's better to proxify a property too much than to open a privacy hole,
  1466. // which is what happens if such a property is a URL that does not get
  1467. // proxified.
  1468. // Don't do this if the value it's being assigned to is a non-String object.
  1469. // This helps when variables have the same name as properties.
  1470. // We don't cover all combinations of properties and operators here; e.g.
  1471. // URL-like properties are unlikely to use ++ or --, and other
  1472. // combinations don't usually make sense. We can revisit if needed.
  1473. // here we ignore case of "+=", etc.; revisit later if needed
  1474. switch (property) {
  1475.  
  1476. case 'src':
  1477. if (_proxy_jslib_instanceof(o, 'Element')) {
  1478. var o_tagname= o.tagName.toLowerCase() ;
  1479. if (o_tagname=='script') {
  1480. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['script-src'], _proxy_jslib_absolute_url(val)))
  1481. _proxy_jslib_throw_csp_error("CSP script-src error: " + val) ;
  1482. } else if (o_tagname=='img') {
  1483. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['img-src'], _proxy_jslib_absolute_url(val)))
  1484. _proxy_jslib_throw_csp_error("CSP img-src error: " + val) ;
  1485. } else if (o_tagname=='video' || o_tagname=='audio' || o_tagname=='source' || o_tagname=='track') {
  1486. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['media-src'], _proxy_jslib_absolute_url(val)))
  1487. _proxy_jslib_throw_csp_error("CSP media-src error: " + val) ;
  1488. } else if (o_tagname=='frame' || o_tagname=='iframe') {
  1489. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['frame-src'], _proxy_jslib_absolute_url(val)))
  1490. _proxy_jslib_throw_csp_error("CSP frame-src error: " + val) ;
  1491. }
  1492. }
  1493. // falls through to next block
  1494.  
  1495. case 'href':
  1496. // sloppy-- really need to separate out these properties
  1497. if (property=='href') {
  1498. if (_proxy_jslib_instanceof(o, 'Element')) {
  1499. if ((o.tagName.toLowerCase()=='base')) {
  1500. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['base-uri'], _proxy_jslib_absolute_url(val)))
  1501. _proxy_jslib_throw_csp_error("CSP base-uri error: " + val) ;
  1502. _proxy_jslib_set_base_vars(o.ownerDocument, _proxy_jslib_absolute_url(val)) ;
  1503. }
  1504. }
  1505.  
  1506. // handle our dup'ed Location object
  1507. if (o._proxy_jslib_original_win) {
  1508. var o_win= o._proxy_jslib_original_win ;
  1509. if (opmod!='') {
  1510. new_val= o.href ;
  1511. eval('new_val' + op + 'val') ;
  1512. } else {
  1513. new_val= val ;
  1514. }
  1515.  
  1516. if (o_win.top===o_win)
  1517. o_win.location.href= _proxy_jslib_full_url_by_frame(new_val, o_win.document, 0) ;
  1518. else
  1519. o_win.location.href= _proxy_jslib_full_url(new_val, o_win.document) ;
  1520.  
  1521. _proxy_jslib_init_domain(o_win) ;
  1522. return new_val ;
  1523. }
  1524. }
  1525.  
  1526. case 'action':
  1527. if (_proxy_jslib_instanceof(o, 'Element')) {
  1528. if ((o.tagName.toLowerCase()=='form') && (property=='action')) {
  1529. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['form-action'], _proxy_jslib_absolute_url(val)))
  1530. _proxy_jslib_throw_csp_error("CSP form-action error: " + val) ;
  1531. }
  1532. }
  1533.  
  1534. case 'lowsrc':
  1535. case 'formAction':
  1536. case 'useMap':
  1537. case 'longDesc':
  1538. case 'cite':
  1539. case 'codeBase':
  1540. case 'location':
  1541. case 'poster':
  1542. // don't convert if o is not a Node or a Location or a Window (including dup'ed of any)
  1543. if (!_proxy_jslib_instanceof(o, 'Node') && !_proxy_jslib_instanceof(o, 'Location') && !_proxy_jslib_instanceof(o, 'Window') )
  1544. return eval('o[property]'+op+'val') ;
  1545. if (opmod!='') {
  1546. new_val= _proxy_jslib_parse_full_url(o[property])[3] ;
  1547. eval('new_val' + op + 'val') ;
  1548. } else {
  1549. new_val= val ;
  1550. }
  1551.  
  1552. // this won't catch e.g. "top.location.href=u"... :P
  1553. if ((property=='location') && (o.top===o)) {
  1554. o[property]= _proxy_jslib_full_url_by_frame(new_val, o.ownerDocument, 0) ;
  1555. } else if ( (o.ownerDocument &&
  1556. (o.ownerDocument.defaultView||o.ownerDocument.parentWindow)._proxy_jslib_base_unframes && o.target==void 0) ||
  1557. (o.target && o.target.match(/^_(top|blank)$/i)) )
  1558. {
  1559. o[property]= _proxy_jslib_full_url_by_frame(new_val, o.ownerDocument, 0) ;
  1560.  
  1561. } else if (property=='src' && _proxy_jslib_instanceof(o, 'Element') && o.nodeName.match(/^i?frame$/i)) {
  1562. o[property]= _proxy_jslib_full_url_by_frame(new_val, o.ownerDocument, 1, void 0, 1) ;
  1563.  
  1564. } else if (property=='src' && _proxy_jslib_instanceof(o, 'Element') && o.nodeName.match(/^script$/i)) {
  1565. var old_url_start= _proxy_jslib_url_start ;
  1566. var flags_6= _proxy_jslib_flags[6] ;
  1567. _proxy_jslib_flags[6]= ((o.type!=void 0) && (o.type!='')) ? o.type : _proxy_jslib_default_script_type ;
  1568. try {
  1569. _proxy_jslib_url_start= _proxy_jslib_url_start_by_flags(_proxy_jslib_flags) ;
  1570. o[property]= _proxy_jslib_full_url(new_val, o.ownerDocument) ;
  1571. } finally {
  1572. _proxy_jslib_url_start= old_url_start ;
  1573. _proxy_jslib_flags[6]= flags_6 ;
  1574. }
  1575.  
  1576. } else {
  1577. o[property]= _proxy_jslib_full_url(new_val, o.ownerDocument, void 0, void 0,
  1578. property=='src' && o.nodeName.match(/^i?frame$/i) ) ;
  1579. }
  1580. if (_proxy_jslib_instanceof(o, 'Window')) _proxy_jslib_init_domain(o) ;
  1581. // return unproxified value
  1582. return new_val ;
  1583.  
  1584.  
  1585. case 'profile':
  1586. if (!o.tagName || o.tagName.toLowerCase()!='head')
  1587. return o[property]= val ;
  1588. var u= val.split(/\s+/) ;
  1589. for (var i= 0 ; i<u.length ; i++)
  1590. u[i]= _proxy_jslib_full_url(u[i], o.ownerDocument) ;
  1591. o[property]= u.join(' ') ;
  1592. return val ;
  1593.  
  1594. case 'cssText':
  1595. if (_proxy_jslib_instanceof(o, 'CSSStyleDeclaration')) {
  1596. o[property]= _proxy_jslib_proxify_css(val) ;
  1597. return val ;
  1598. } else {
  1599. return _assign_default() ;
  1600. }
  1601.  
  1602.  
  1603. // these are properties of HTMLElement, i.e. could be one of many object types
  1604. case 'innerHTML':
  1605. // only proxify it if the object is an HTMLElement or Document
  1606. // MSIE has trouble with instanceof :P
  1607. if (!_proxy_jslib_instanceof(o, 'HTMLElement') && !_proxy_jslib_instanceof(o, 'Document'))
  1608. return _assign_default() ;
  1609.  
  1610. // also avoid if it's in a script element, which jQuery uses
  1611. if (is_in_script(o, property)) return _assign_default() ;
  1612.  
  1613. if (op!='=') {
  1614. // unproxify it first by calling _proxify_html() with reverse=true
  1615. // unfortunately, innerHTML is sometimes used for <style> and <script> elements
  1616. switch (o.tagName.toLowerCase()) {
  1617. case 'style': new_val= _proxy_jslib_proxify_css(o[property], true) ; break ;
  1618. case 'script': new_val= _proxy_jslib_proxify_js(o[property], void 0, void 0, void 0, true) ; break ;
  1619. default: new_val= _proxy_jslib_proxify_html(o[property], (o.ownerDocument || o), false, true)[0] ;
  1620. }
  1621. eval('new_val' + op + 'val') ;
  1622. switch (o.tagName.toLowerCase()) {
  1623. case 'style': o[property]= _proxy_jslib_proxify_css(new_val) ; break ;
  1624. case 'script': o[property]= _proxy_jslib_proxify_js(new_val) ; break ;
  1625. default: o[property]= _proxy_jslib_proxify_html(new_val, (o.ownerDocument || o))[0] ;
  1626. }
  1627. return new_val ;
  1628. } else {
  1629. switch (o.tagName.toLowerCase()) {
  1630. case 'style': o[property]= _proxy_jslib_proxify_css(val) ; break ;
  1631. case 'script': o[property]= _proxy_jslib_proxify_js(val) ; break ;
  1632. default: o[property]= _proxy_jslib_proxify_html(val, (o.ownerDocument || o))[0] ;
  1633. }
  1634. return val ;
  1635. }
  1636.  
  1637.  
  1638. case 'outerHTML':
  1639. case 'outerText':
  1640. // only proxify it if the object is an HTMLElement or Document
  1641. // MSIE has trouble with instanceof :P
  1642. if (!_proxy_jslib_instanceof(o, 'HTMLElement') && !_proxy_jslib_instanceof(o, 'Document'))
  1643. return _assign_default() ;
  1644.  
  1645. // also avoid if it's in a script element, which jQuery uses
  1646. if (is_in_script(o, property)) return _assign_default() ;
  1647.  
  1648. if (op!='=') {
  1649. // unproxify it first by calling _proxify_html() with reverse=true
  1650. new_val= _proxy_jslib_proxify_html(o[property], (o.ownerDocument || o), false, true)[0] ;
  1651. eval('new_val' + op + 'val') ;
  1652. return new_val ;
  1653. } else {
  1654. o[property]= _proxy_jslib_proxify_html(val, (o.ownerDocument || o))[0] ;
  1655. return val ;
  1656. }
  1657.  
  1658.  
  1659. // same for properties of Node
  1660. case 'nodeValue':
  1661. if (opmod!='') { eval('new_val= o[property]' + opmod + 'val') }
  1662. else { new_val= val }
  1663. if (_proxy_jslib_instanceof(o, 'Attr')) {
  1664. o[property]= _proxy_jslib_proxify_attribute(void 0, o, property, new_val) ;
  1665. } else if (_proxy_jslib_instanceof(o, 'Node')) {
  1666. o[property]= _proxy_jslib_proxify_attribute(o, void 0, property, new_val) ;
  1667. }
  1668. return new_val ;
  1669.  
  1670.  
  1671. // Various parts of Link and (dup'ed) Location objects
  1672.  
  1673. case 'protocol':
  1674. if (_proxy_jslib_instanceof(o, 'Link') || _proxy_jslib_instanceof(o, 'Location')) {
  1675. o.href= _proxy_jslib_full_url(val+'//'+(u[2]!='' ? u[2]+'@' : '')+u[3]+u[6]+u[7]+u[8], o.ownerDocument) ;
  1676. if (_proxy_jslib_instanceof(o, 'Location')) o._proxy_jslib_original_win.location.href= o.href ;
  1677. return val ;
  1678. } else {
  1679. return _assign_default() ;
  1680. }
  1681.  
  1682. case 'host':
  1683. if (_proxy_jslib_instanceof(o, 'Link') || _proxy_jslib_instanceof(o, 'Location')) {
  1684. o.href= _proxy_jslib_full_url(u[1]+'//'+(u[2]!='' ? u[2]+'@' : '')+val+u[6]+u[7]+u[8], o.ownerDocument) ;
  1685. if (_proxy_jslib_instanceof(o, 'Location')) o._proxy_jslib_original_win.location.href= o.href ;
  1686. return val ;
  1687. } else {
  1688. return _assign_default() ;
  1689. }
  1690.  
  1691. case 'hostname':
  1692. if (_proxy_jslib_instanceof(o, 'Link') || _proxy_jslib_instanceof(o, 'Location')) {
  1693. o.href= _proxy_jslib_full_url(u[1]+'//'+(u[2]!='' ? u[2]+'@' : '')+val+(u[5]!='' ? ':'+u[5] : '')+u[6]+u[7]+u[8], o.ownerDocument) ;
  1694. if (_proxy_jslib_instanceof(o, 'Location')) o._proxy_jslib_original_win.location.href= o.href ;
  1695. return val ;
  1696. } else {
  1697. return _assign_default() ;
  1698. }
  1699.  
  1700. case 'port':
  1701. if (_proxy_jslib_instanceof(o, 'Link') || _proxy_jslib_instanceof(o, 'Location')) {
  1702. o.href= _proxy_jslib_full_url(u[1]+'//'+(u[2]!='' ? u[2]+'@' : '')+u[4]+(val!='' ? ':'+val : '')+u[6]+u[7]+u[8], o.ownerDocument) ;
  1703. if (_proxy_jslib_instanceof(o, 'Location')) o._proxy_jslib_original_win.location.href= o.href ;
  1704. return val ;
  1705. } else {
  1706. return _assign_default() ;
  1707. }
  1708.  
  1709. case 'pathname':
  1710. if (_proxy_jslib_instanceof(o, 'Link') || _proxy_jslib_instanceof(o, 'Location')) {
  1711. o.href= _proxy_jslib_full_url(u[1]+'//'+(u[2]!='' ? u[2]+'@' : '')+u[3]+val+u[7]+u[8], o.ownerDocument) ;
  1712. if (_proxy_jslib_instanceof(o, 'Location')) o._proxy_jslib_original_win.location.href= o.href ;
  1713. return val ;
  1714. } else {
  1715. return _assign_default() ;
  1716. }
  1717.  
  1718. case 'search':
  1719. if (_proxy_jslib_instanceof(o, 'Link') || _proxy_jslib_instanceof(o, 'Location')) {
  1720. o.href= _proxy_jslib_full_url(u[1]+'//'+(u[2]!='' ? u[2]+'@' : '')+u[3]+u[6]+val+u[8], o.ownerDocument) ;
  1721. if (_proxy_jslib_instanceof(o, 'Location')) o._proxy_jslib_original_win.location.href= o.href ;
  1722. return val ;
  1723. } else {
  1724. return _assign_default() ;
  1725. }
  1726.  
  1727.  
  1728. case 'cookie':
  1729. if (_proxy_jslib_instanceof(o, 'Document')) {
  1730. // simple way to test validity of cookie
  1731. var new_cookie= _proxy_jslib_cookie_to_client(val, o) ;
  1732. if (new_cookie=='') return '' ;
  1733. if (_proxy_jslib_USE_DB_FOR_COOKIES) {
  1734. _proxy_jslib_store_cookie_in_db(val) ;
  1735. var c= val.match(/^\s*([^\=]+\=[^\;]*)/)[1] ;
  1736. if (c!=void 0) _proxy_jslib_COOKIES_FROM_DB+= ';' + c ;
  1737. return _proxy_jslib_COOKIES_FROM_DB ;
  1738. }
  1739. return o.cookie= new_cookie ;
  1740. } else {
  1741. return _assign_default() ;
  1742. }
  1743.  
  1744.  
  1745. // We store w._proxy_jslib_document_domain as "scheme://hostname:port",
  1746. // but Document.domain uses only hostname.
  1747. case 'domain':
  1748. if (_proxy_jslib_instanceof(o, 'Document')) {
  1749. var w= o.defaultView || o.parentWindow ;
  1750. if (!w._proxy_jslib_document_domain) _proxy_jslib_init_domain(w) ;
  1751. if (!w._proxy_jslib_document_domain) return ; // unsupported scheme
  1752. var pwurl= _proxy_jslib_parse_url(w._proxy_jslib_document_domain) ;
  1753. var old_domain= pwurl[4] ;
  1754. if (old_domain.match(/^[\d\.]+$/)) {
  1755. alert('Warning: tried to change document.domain from an IP address: ['+old_domain+']') ;
  1756. return ;
  1757. }
  1758. val= val.replace(/\.+$/, '') ;
  1759. // new domain must be suffix of old domain, must contain a
  1760. // ".", and must be a complete domain suffix of old value
  1761. // (tested here by prefixing with "." before suffix check,
  1762. // but allowing if strings are equal).
  1763. if ( ( (('.'+val)==old_domain.slice(-val.length-1))
  1764. || (val==old_domain) )
  1765. && val.match(/\./) )
  1766. {
  1767. return (w._proxy_jslib_document_domain= pwurl[1] + '//' + val + ':' + pwurl[5]) ;
  1768. }
  1769. // else alert('Warning: tried to set document.domain to illegal value: ['+val+'] existing domain: ['+w._proxy_jslib_document_domain+']') ; // jsm
  1770. break ;
  1771. } else {
  1772. return _assign_default() ;
  1773. }
  1774.  
  1775.  
  1776. case 'withCredentials':
  1777. if (_proxy_jslib_instanceof(o, 'XMLHttpRequest') || _proxy_jslib_instanceof(o, 'AnonXMLHttpRequest')) {
  1778. if (typeof o._proxy_jslib_xhrdata.win=='number')
  1779. o._proxy_jslib_xhrdata.win= _proxy_jslib_xhrwins[o._proxy_jslib_xhrdata.win] ;
  1780. if (o._proxy_jslib_xhrdata.anon)
  1781. throw new Error('InvalidAccessError setting XMLHttpRequest.withCredentials') ;
  1782. if (o._proxy_jslib_xhrdata.win.document && o._proxy_jslib_xhrdata.sync)
  1783. throw new Error('InvalidAccessError setting XMLHttpRequest.withCredentials') ;
  1784. return o.withCredentials= val ;
  1785. } else {
  1786. return _assign_default() ;
  1787. }
  1788.  
  1789.  
  1790. // various CSS settings
  1791.  
  1792. case 'value':
  1793. if (_proxy_jslib_instanceof(o, 'Attr')) {
  1794. if (opmod!='') {
  1795. new_val= _proxy_jslib_proxify_attribute(void 0, o, o.name, val, 1) ;
  1796. eval('new_val' + opmod + '= val') ;
  1797. } else {
  1798. new_val= val ;
  1799. }
  1800. o.value= _proxy_jslib_proxify_attribute(void 0, o, o.name, new_val) ;
  1801. return new_val ;
  1802. } else {
  1803. return _assign_default() ;
  1804. }
  1805.  
  1806.  
  1807. case 'background':
  1808. case 'backgroundImage':
  1809. case 'content':
  1810. case 'cursor':
  1811. case 'listStyle':
  1812. case 'listStyleImage':
  1813. if (_proxy_jslib_instanceof(o, 'CSS2Properties') || _proxy_jslib_instanceof(o, 'CSSStyleDeclaration')) {
  1814. o[property]= _proxy_jslib_proxify_css(val) ;
  1815. return val ;
  1816. } else {
  1817. return _assign_default() ;
  1818. }
  1819.  
  1820.  
  1821. case 'text':
  1822. case 'textContent':
  1823. if (_proxy_jslib_instanceof(o, 'Node')) {
  1824. if (o.nodeName.match(/^script$/i)) {
  1825. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['script-src'], "'unsafe-inline'"))
  1826. _proxy_jslib_throw_csp_error("CSP inline script-src error") ;
  1827. var type= o.type || _proxy_jslib_default_script_type ;
  1828. o[property]= _proxy_jslib_proxify_block(val, type,
  1829. _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, 0) ;
  1830. return val ;
  1831. } else if (o.nodeName.match(/^style$/i)) {
  1832. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['style-src'], "'unsafe-inline'"))
  1833. _proxy_jslib_throw_csp_error("CSP inline style-src error") ;
  1834. var type= o.type || _proxy_jslib_default_style_type ;
  1835. o[property]= _proxy_jslib_proxify_block(val, type,
  1836. _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, 0) ;
  1837. return val ;
  1838. } else {
  1839. return _assign_default() ;
  1840. }
  1841.  
  1842. } else {
  1843. return _assign_default() ;
  1844. }
  1845.  
  1846.  
  1847.  
  1848. default:
  1849. return _assign_default() ;
  1850. }
  1851.  
  1852.  
  1853. function _assign_default() {
  1854. if (op=='++') return o[property]++ ;
  1855. else if (op=='--') return o[property]-- ;
  1856. else if (op=='=') return o[property]= val ; // optimization to not use eval
  1857. else return eval('o[property]'+op+'val') ;
  1858. }
  1859. }
  1860.  
  1861.  
  1862.  
  1863. // This is used when the property in question IS being assigned to, WITHOUT an object.
  1864. // The value returned is the value to set the variable to.
  1865. function _proxy_jslib_assign_rval (prefix, property, op, val, cur_val) {
  1866.  
  1867. // handle prefix
  1868. if (prefix=='delete') return undefined ; // not quite the same as delete, but close enough?
  1869. if (prefix=='++') {
  1870. val= 1 ;
  1871. op= '+=' ;
  1872. } else if (prefix=='--') {
  1873. val= 1 ;
  1874. op= '-=' ;
  1875. }
  1876.  
  1877. if (val && (typeof val=='object') && (!('toLowerCase' in val)))
  1878. return val ;
  1879. var new_val ;
  1880. if (op=='=')
  1881. new_val= val ; // optimization to not use eval
  1882. else {
  1883. new_val= cur_val ;
  1884. eval('new_val' + op + 'val') ;
  1885. }
  1886.  
  1887. switch (property) {
  1888. // when there's no object, "location" is the only property that needs proxification
  1889. case 'location':
  1890. return _proxy_jslib_full_url(new_val) ;
  1891. default:
  1892. return new_val ;
  1893. }
  1894. }
  1895.  
  1896.  
  1897.  
  1898. // Next two routines are used when in a with() block.
  1899. function _proxy_jslib_with_handle (with_objs, property, cur_val, calls_now, in_new_statement) {
  1900. for (var i= with_objs.length-1 ; i>=0 ; i--)
  1901. if (property in with_objs[i])
  1902. return _proxy_jslib_handle(with_objs[i], property, with_objs[i][property], calls_now, in_new_statement) ;
  1903. return _proxy_jslib_handle(null, property, cur_val, calls_now, in_new_statement) ;
  1904. }
  1905.  
  1906. function _proxy_jslib_with_assign_rval (with_objs, prefix, property, op, val, cur_val) {
  1907. for (var i= with_objs.length-1 ; i>=0 ; i--)
  1908. if (property in with_objs[i])
  1909. return _proxy_jslib_assign(prefix, with_objs[i], property, op, val) ;
  1910. return _proxy_jslib_assign_rval(prefix, property, op, val, cur_val) ;
  1911. }
  1912.  
  1913.  
  1914.  
  1915. function _proxy_jslib_new(o) {
  1916. // note that we need to match classes in other windows too
  1917. // can't use Function.toString() or Object.toString() to reliably get
  1918. // class name portably, and accessing non-existant object types sometimes
  1919. // causes JS to crash, so we use this messy approach to get oclass for
  1920. // any classes we care about
  1921. var oclass ;
  1922. try { if (o===XMLHttpRequest) oclass= 'XMLHttpRequest' } catch (e) {}
  1923. if (!oclass) try { if (o===AnonXMLHttpRequest) oclass= 'AnonXMLHttpRequest' } catch (e) {}
  1924. if (!oclass) try { if (o===EventSource) oclass= 'EventSource' } catch (e) {}
  1925. if (!oclass) try { if (o===WebSocket) oclass= 'WebSocket' } catch (e) {}
  1926. if (!oclass) try { if (o===Worker) oclass= 'Worker' } catch (e) {}
  1927. if (!oclass) try { if (o===SharedWorker) oclass= 'SharedWorker' } catch (e) {}
  1928. if (!oclass) try { if (o===Audio) oclass= 'Audio' } catch (e) {}
  1929. if (!oclass) try { if (o===Function) oclass= 'Function' } catch (e) {}
  1930. // use Function.prototype.toString in case toString is overridden
  1931. // MSIE adds \n to start of Function.toString() :P
  1932. if (!oclass) try { oclass= Function.prototype.toString.call(o).match(/^\n?function ([$\w.]*)/)[1] } catch (e) {}
  1933. if (!oclass) oclass= '' ;
  1934.  
  1935. if ((oclass=='EventSource') || (oclass=='WebSocket')) {
  1936. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['connect-src'], _proxy_jslib_absolute_url(arguments[1])))
  1937. _proxy_jslib_throw_csp_error("connect-src violation with " + oclass) ;
  1938. arguments[1]= _proxy_jslib_full_url(arguments[1]) ;
  1939. } else if ((oclass=='Worker') || (oclass=='SharedWorker')) {
  1940. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['script-src'], _proxy_jslib_absolute_url(arguments[1])))
  1941. _proxy_jslib_throw_csp_error("script-src violation with " + oclass) ;
  1942. arguments[1]= _proxy_jslib_full_url(arguments[1]) ;
  1943. } else if (oclass=='Audio') {
  1944. arguments[1]= _proxy_jslib_full_url(arguments[1]) ;
  1945. } else if (oclass=='Function') {
  1946. if (!_proxy_jslib_eval_ok) _proxy_jslib_throw_csp_error("can't new Function without unsafe-eval") ;
  1947. arguments[arguments.length-1]= _proxy_jslib_proxify_js(arguments[arguments.length-1]) ;
  1948. }
  1949.  
  1950. // eval() takes a while, so avoid it for most common cases
  1951. var ret ;
  1952. if (arguments.length==1) ret= new o ;
  1953. else if (arguments.length==2) ret= new o(arguments[1]) ;
  1954. else if (arguments.length==3) ret= new o(arguments[1], arguments[2]) ;
  1955. else if (arguments.length==4) ret= new o(arguments[1], arguments[2], arguments[3]) ;
  1956. else if (arguments.length==5) ret= new o(arguments[1], arguments[2], arguments[3], arguments[4]) ;
  1957. else {
  1958. var out_args= [] ;
  1959. // Note starts with 1, not 0, since arguments[0] is o .
  1960. for (var i= 1 ; i<arguments.length ; i++) out_args[i-1]= 'arguments[' + i + ']' ;
  1961. var new_statement= 'new o(' + out_args.join(', ') + ')' ;
  1962. ret= eval(new_statement) ;
  1963. }
  1964.  
  1965. // Bug in browsers: using a DOM object in ret._proxy_jslib_xhrdata (like "{win: window}")
  1966. // at this point crashes JS, and can't even trap it with try/catch. But storing
  1967. // the windows in the _proxy_jslib_wins array, and setting the win property later,
  1968. // avoids the error.
  1969. if (oclass=='XMLHttpRequest') {
  1970. _proxy_jslib_xhrwins.push(window) ;
  1971. ret._proxy_jslib_xhrdata= {origin: _proxy_jslib_origin,
  1972. win: _proxy_jslib_xhrwins.length-1
  1973. } ;
  1974. } else if (oclass=='AnonXMLHttpRequest') {
  1975. _proxy_jslib_xhrwins.push(window) ;
  1976. ret._proxy_jslib_xhrdata= {origin: _proxy_jslib_origin,
  1977. win: _proxy_jslib_xhrwins.length-1,
  1978. anon: true
  1979. } ;
  1980. }
  1981.  
  1982. return ret ;
  1983. }
  1984.  
  1985.  
  1986. //---- below are used to support the API functions above ---------------
  1987.  
  1988.  
  1989. // This is used for a test handling 'innerHTML' etc.
  1990. function is_in_script(el, property) {
  1991. if (!_proxy_jslib_instanceof(el, 'HTMLElement')) return 0 ;
  1992. var p= property=='innerHTML' ? el : el.parentNode ;
  1993. while (p) {
  1994. if (p.tagName=='SCRIPT') return 1 ;
  1995. p= p.parentNode ;
  1996. }
  1997. return 0 ;
  1998. }
  1999.  
  2000.  
  2001. function _proxy_jslib_write_via_buffer(doc, html) {
  2002. var i, buf ;
  2003. for (i= 0 ; i<_proxy_jslib_write_buffers.length ; i++) {
  2004. if (_proxy_jslib_write_buffers[i].doc===doc) {
  2005. buf= _proxy_jslib_write_buffers[i] ;
  2006. break ;
  2007. }
  2008. }
  2009. if (!buf) {
  2010. buf= _proxy_jslib_write_buffers[_proxy_jslib_write_buffers.length]=
  2011. { doc: doc, buf: html } ;
  2012. } else {
  2013. if (buf.buf==void 0) buf.buf= '' ;
  2014. buf.buf+= html ;
  2015. }
  2016. // _proxy_jslib_flush_write_buffer(buf) ;
  2017. }
  2018.  
  2019.  
  2020. // careful-- output of document.write() may be (erroneously?) parsed and
  2021. // executed immediately after document.write() statement. To help with
  2022. // that, we clear the buffer before calling document.write().
  2023. // Hack here for JS insertions-- if document was created and nothing written on
  2024. // it yet, then insert the JS library if needed.
  2025. // Another hack-- since _proxy_jslib_write_buffers may be reset if what's
  2026. // written includes jslib, we exit the loop if that happens.
  2027. function _proxy_jslib_flush_write_buffers() {
  2028. var buf, i, p ;
  2029.  
  2030. for (i= 0 ; (_proxy_jslib_write_buffers!=void 0) && (i<_proxy_jslib_write_buffers.length) ; i++) {
  2031. buf= _proxy_jslib_write_buffers[i] ;
  2032. if (buf.buf==void 0) continue ;
  2033.  
  2034. p= _proxy_jslib_proxify_html(buf.buf, buf.doc, !buf.has_jslib) ;
  2035. if (p[3]) return ; // found frame document
  2036. buf.has_jslib= buf.has_jslib || p[2] ;
  2037. buf.buf= p[1] ;
  2038. // buf.doc.write(p[0]) ;
  2039. // for when Document.write is redefined :P
  2040. // really should fix all other calls to Document.write(); they will
  2041. // currently double-proxify something, not cause a privacy hole
  2042. var doc_write= HTMLDocument.prototype.write || Document.prototype.write ;
  2043. doc_write.call(buf.doc, p[0]) ;
  2044. }
  2045. }
  2046.  
  2047.  
  2048. function _proxy_jslib_flush_write_buffer(buf) {
  2049. var p= _proxy_jslib_proxify_html(buf.buf, buf.doc, !buf.has_jslib) ;
  2050. if (p[3]) return ; // found frame document
  2051. buf.has_jslib= buf.has_jslib || p[2] ;
  2052. //alert('in flush; in=['+buf.buf+']\n\nout=['+p[0]+']\n\nremainder=['+p[1]+']') ;
  2053. buf.buf= p[1] ;
  2054. // for when Document.write is redefined :P
  2055. var doc_write= HTMLDocument.prototype.write || Document.prototype.write ;
  2056. doc_write.call(buf.doc, p[0]) ;
  2057. }
  2058.  
  2059.  
  2060.  
  2061. // include fields needed for type ID, plus any other "authorized" fields.
  2062. // this should really be redone....
  2063. function _proxy_jslib_dup_window_safe(w) {
  2064. return { _proxy_jslib_original_window: w,
  2065. navigator: w.navigator,
  2066. clearInterval: w.clearInterval,
  2067. moveBy: w.moveBy,
  2068. self: w,
  2069.  
  2070. location: w.location,
  2071. postMessage: function (message, targetOrigin, ports) {
  2072. return _proxy_jslib_postMessage(w, message, targetOrigin, ports) ;
  2073. }
  2074. } ;
  2075. }
  2076.  
  2077.  
  2078. // since *some* sites do things like compare "top.location==self.location", we
  2079. // have to keep a cache of locations
  2080. // we currently don't keep this up-to-date when values change, but we could....
  2081. function _proxy_jslib_dup_location(o) {
  2082. var pl= _proxy_jslib_parse_full_url(o.location.href) ; // o can be either Window or Document object
  2083. var url= pl[3] || '' ;
  2084. if (_proxy_jslib_locations[url]) return _proxy_jslib_locations[url] ;
  2085. var is_in_frame= pl[2] ? _proxy_jslib_unpack_flags(pl[2])[5] : 0 ;
  2086. pl= url ? _proxy_jslib_parse_url(url) : [] ;
  2087.  
  2088. return _proxy_jslib_locations[url]=
  2089. { _proxy_jslib_original_win: o.defaultView||o.parentWindow||o,
  2090. hash: pl[8],
  2091. host: pl[3],
  2092. hostname: pl[4],
  2093. href: pl[0],
  2094. pathname: pl[6],
  2095. port: pl[5],
  2096. protocol: pl[1],
  2097. search: pl[7],
  2098. origin: (o.defaultView||o.parentWindow||o)._proxy_jslib_origin, // non-standard
  2099.  
  2100. assign: function (url) {
  2101. return o.location.assign(_proxy_jslib_full_url_by_frame(url, o.document||o, is_in_frame)) ;
  2102. },
  2103. reload: function (force) {
  2104. return o.location.reload(force) ;
  2105. },
  2106. replace: function (url) {
  2107. return o.location.replace(_proxy_jslib_full_url_by_frame(url, o.document||o, is_in_frame)) ;
  2108. },
  2109. toString: function () {
  2110. return this.href ;
  2111. }
  2112. } ;
  2113. }
  2114.  
  2115.  
  2116. // used in two places
  2117. function _proxy_jslib_postMessage(win, message, targetOrigin, ports) {
  2118. if ((targetOrigin=='*') || (targetOrigin=='/'))
  2119. if (ports==void 0) {
  2120. return win.postMessage(message, targetOrigin) ; // Firefox chokes on undefined ports
  2121. } else {
  2122. return win.postMessage(message, targetOrigin, ports) ;
  2123. }
  2124.  
  2125. // security check-- targetOrigin must match win.location.href
  2126. // in scheme/host/port, unless win.location.href is empty or
  2127. // about:blank
  2128. var u= _proxy_jslib_parse_full_url(win.location.href)[3] ;
  2129. if (u && u!='about:blank') {
  2130. var pu1= _proxy_jslib_parse_url(u) ;
  2131. var pu2= _proxy_jslib_parse_url(targetOrigin) ;
  2132. var port1= pu1[5] || (pu1[1]=='https' ? 443 : 80) ;
  2133. var port2= pu2[5] || (pu2[1]=='https' ? 443 : 80) ;
  2134. if ((pu1[1]!=pu2[1]) || (pu1[4]!=pu2[4]) || (port1!=port2))
  2135. return void 0 ;
  2136. }
  2137.  
  2138. // all postMessage's use _proxy_jslib_url_start; we enforce targetOrigin above
  2139. if (ports==void 0) {
  2140. return win.postMessage(message, _proxy_jslib_url_start) ; // Firefox chokes on undefined ports
  2141. } else {
  2142. return win.postMessage(message, _proxy_jslib_url_start, ports) ;
  2143. }
  2144. }
  2145.  
  2146.  
  2147. // Same-origin policy requires matching scheme, hostname, and port.
  2148. // This sets w._proxy_jslib_document_domain to "scheme://hostname:port", which
  2149. // must be maintained.
  2150. // For about:blank pages, this sets w._proxy_jslib_document_domain to undefined.
  2151. // If the optional url parameter isn't provided, uses w.document.URL .
  2152. // Note that Document.domain only uses hostname; we accommodate this when getting
  2153. // or setting it.
  2154. function _proxy_jslib_init_domain(w, url) {
  2155. if (!url) {
  2156. if (!w.location || !w.location.href || w.location.href=='about:blank') {
  2157. w._proxy_jslib_document_domain= void 0 ;
  2158. return ;
  2159. }
  2160. url= w.location.href.replace(/^wyciwyg:\/\/\d+\//i, '') ;
  2161. url= _proxy_jslib_parse_full_url(url)[3] ;
  2162. if (!url) return ; // means on start page
  2163. url= decodeURIComponent(url) ;
  2164. }
  2165. if (!url.match(/^(?:https?|ftp):/i)) {
  2166. w._proxy_jslib_document_domain= void 0 ;
  2167. return ;
  2168. }
  2169. var purl= _proxy_jslib_parse_url(url) ;
  2170. purl[3]= purl[3].replace(/\.+$/, '') ;
  2171. if (!purl[5]) purl[5]= (purl[1]=='http:') ? 80
  2172. : (purl[1]=='https:') ? 443
  2173. : 0 ;
  2174. if (!purl[5]) w._proxy_jslib_document_domain= void 0 ;
  2175. else w._proxy_jslib_document_domain= purl[1] + '//' + purl[3] + ':' + purl[5] ;
  2176. }
  2177.  
  2178.  
  2179. // Return code to insert jslib and _proxy_jslib_pass_vars() call into an iframe.
  2180. // This is only needed for <iframe> elements with no src attribute or with a
  2181. // "javascript:" src.
  2182. function _proxy_jslib_iframe_init_html() {
  2183. var jslib_element= '<script class="_proxy_jslib_jslib" type="text/javascript" src="'
  2184. + _proxy_jslib_html_escape(_proxy_jslib_url_start_inframe
  2185. + _proxy_jslib_wrap_proxy_encode('x-proxy://scripts/jslib'))
  2186. + '"><\/script>\n' ;
  2187.  
  2188. var base_url_jsq= document._proxy_jslib_base_url.replace(/(["\\])/g, function (p) { return "\\"+p } ) ;
  2189. if (base_url_jsq!=void 0) base_url_jsq= '"' + base_url_jsq + '"' ;
  2190. var cookies_from_db_jsq= _proxy_jslib_COOKIES_FROM_DB.replace(/(["\\])/g, function (p) { return "\\"+p } ) ;
  2191.  
  2192. var pv_element= '<script class="_proxy_jslib_pv" type="text/javascript">_proxy_jslib_pass_vars('
  2193. + base_url_jsq + ',"'
  2194. + _proxy_jslib_origin + '", '
  2195. + _proxy_jslib_cookies_are_banned_here + ','
  2196. + _proxy_jslib_doing_insert_here + ','
  2197. + _proxy_jslib_SESSION_COOKIES_ONLY + ','
  2198. + _proxy_jslib_COOKIE_PATH_FOLLOWS_SPEC + ','
  2199. + _proxy_jslib_RESPECT_THREE_DOT_RULE + ','
  2200. + _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS + ',"'
  2201. + _proxy_jslib_RTMP_SERVER_PORT + '","'
  2202. + _proxy_jslib_default_script_type + '","'
  2203. + _proxy_jslib_default_style_type + '",'
  2204. + _proxy_jslib_USE_DB_FOR_COOKIES + ','
  2205. + _proxy_jslib_PROXIFY_COMMENTS + ','
  2206. + _proxy_jslib_ALERT_ON_CSP_VIOLATION + ',"'
  2207. + cookies_from_db_jsq + '",'
  2208. + _proxy_jslib_TIMEOUT_MULTIPLIER + ',"'
  2209. + _proxy_jslib_csp_st + '")<\/script>' ;
  2210.  
  2211. return jslib_element + pv_element ;
  2212. }
  2213.  
  2214.  
  2215.  
  2216.  
  2217. // returns proxified URL, relative to doc
  2218. function _proxy_jslib_full_url(uri_ref, doc, reverse, retain_query, is_frame_src) {
  2219. var script, r_l, m1, m2, r_q, query,
  2220. data_type, data_clauses, data_content, data_charset, data_base64 ;
  2221.  
  2222. if (!uri_ref) return uri_ref ;
  2223.  
  2224. // Disable retain_query until potential anonymity issues are resolved.
  2225. retain_query= false ;
  2226.  
  2227. // Apparently some non-string objects are passed here... Location? Link?
  2228. uri_ref= uri_ref.toString() ;
  2229.  
  2230. // Hack to prevent double-proxified URLs in SWFs, meaning we can't chain
  2231. // through the same script location.
  2232. // This also helps to avoid double-proxifying bugs in general.
  2233. if (!reverse && (uri_ref.indexOf(_proxy_jslib_SCRIPT_URL)==0))
  2234. return uri_ref ;
  2235.  
  2236. // leave blob: URLs unchanged
  2237. if (uri_ref.match(/^blob\:/i)) return uri_ref ;
  2238.  
  2239. // hack for my.yahoo.com; it creates the non-functional src="//:" on purpose (?)
  2240. if (uri_ref=='//:') return uri_ref ;
  2241.  
  2242. if (!doc) doc= window.document ;
  2243.  
  2244. //if (uri_ref==null) alert('null; caller=['+arguments.callee.caller+']') ; // caller==null
  2245. //if (uri_ref.match(/\/[01]{6}[A-Z]\//)) alert('in full_url; uri_ref, caller=\n['+uri_ref+']\n['+arguments.callee.caller+']') ; // jsm
  2246. if (uri_ref==null) return '' ;
  2247. if (reverse) return _proxy_jslib_parse_full_url(uri_ref)[3] ;
  2248.  
  2249. if (!doc._proxy_jslib_base_url) _proxy_jslib_set_base_vars(doc, _proxy_jslib_parse_full_url(doc.URL)[3]) ;
  2250.  
  2251. uri_ref= uri_ref.replace(/^\s+|\s+$/g, '') ;
  2252. // if (/^x\-proxy\:\/\//i.test(uri_ref)) return '' ;
  2253. if (uri_ref.match(/^about\:\s*blank$/i)) return uri_ref ;
  2254.  
  2255. if (/^(javascript|livescript)\:/i.test(uri_ref)) {
  2256. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['script-src'], "'unsafe-inline'"))
  2257. _proxy_jslib_throw_csp_error("CSP inline script-src error: 'javascript:' URL") ;
  2258. script= uri_ref.replace(/^(javascript|livescript)\:/i, '') ;
  2259. r_l= _proxy_jslib_separate_last_js_statement(script) ;
  2260. r_l[1]= r_l[1].replace(/\s*;\s*$/, '') ;
  2261.  
  2262. // special case-- frames with src attribute of "javascript:..."
  2263. if (is_frame_src) {
  2264. return "javascript: '<body>"
  2265. + _proxy_jslib_iframe_init_html().replace(/(['\\])/g, function (p) { return "\\"+p } )
  2266. + "<script>"
  2267. + _proxy_jslib_proxify_js(r_l[0], 0).replace(/(['\\])/g, function (p) { return "\\"+p } )
  2268. + "; document.write(_proxy_jslib_proxify_html("
  2269. + _proxy_jslib_proxify_js(r_l[1], 0).replace(/(['\\])/g, function (p) { return "\\"+p } )
  2270. + ")[0])</script></body>'" ;
  2271. }
  2272.  
  2273. return 'javascript:' + _proxy_jslib_proxify_js(r_l[0], 1)
  2274. + '; _proxy_jslib_proxify_html(' + _proxy_jslib_proxify_js(r_l[1], 0) + ')[0]' ;
  2275.  
  2276. // The "FSCommand:" URL may be called by Flash apps.
  2277. } else if (m1= uri_ref.match(/^(fscommand:)(.*)/i)) {
  2278. return m1[1] + _proxy_jslib_proxify_js(m1[2]) ;
  2279.  
  2280. } else if (m1= uri_ref.match(/^data:([\w\.\+\$\-]+\/[\w\.\+\$\-]+)?;?([^\,]*)\,?(.*)/i)) {
  2281. data_type= m1[1].toLowerCase() ;
  2282. if (data_type=='text/html' || data_type=='text/css' || data_type.match(/script/i)) {
  2283. data_clauses= m1[2].split(/;/) ;
  2284. data_content= m1[3] ;
  2285. for (var i= 0 ; i<data_clauses.length ; i++) {
  2286. if (m2= data_clauses[i].match(/^charset=(\S+)/i)) {
  2287. data_charset= m2[1] ;
  2288. } else if (data_clauses[i].toLowerCase()=='base64') {
  2289. data_base64= 1 ;
  2290. }
  2291. }
  2292. data_content= data_base64
  2293. ? atob(data_content)
  2294. : data_content.replace(/%([\da-fA-F]{2})/g,
  2295. function (s,p1) { return String.fromCharCode(eval('0x'+p1)) } ) ; // probably slow
  2296. data_content= (data_type=='text/html') ? _proxy_jslib_proxify_html(data_content)[0]
  2297. : _proxy_jslib_proxify_block(data_content, data_type, 1) ;
  2298. data_content= btoa(data_content) ;
  2299. return data_charset ? 'data:' + data_type + ';charset=' + data_charset + ';base64,' + data_content
  2300. : 'data:' + data_type + ';base64,' + data_content ;
  2301. } else {
  2302. return uri_ref ;
  2303. }
  2304. }
  2305.  
  2306. var uf= uri_ref.match(/^([^\#]*)(\#.*)?/) ;
  2307. var uri= uf[1] ;
  2308. var frag= uf[2] || '' ;
  2309. if (uri=='') return uri_ref ;
  2310.  
  2311. uri= uri.replace(/[\r\n]/g, '') ;
  2312.  
  2313. if (retain_query) {
  2314. r_q= uri.split(/\?/) ;
  2315. uri= r_q[0] ;
  2316. query= r_q[1] ;
  2317. if (query) query= '?'+query ;
  2318. else query= '' ;
  2319. }
  2320.  
  2321. if (doc._proxy_jslib_base_url) {
  2322. while (uri.match(/^\/\.\.?\//)) uri= uri.replace(/^\/\.\.?\//, '/') ;
  2323. if (doc._proxy_jslib_base_path.length==doc._proxy_jslib_base_host.length+1)
  2324. while (uri.match(/^\.\.?\//)) uri= uri.replace(/^\.\.?\//, '') ;
  2325. }
  2326.  
  2327. var absurl ;
  2328. if (/^[\w\+\.\-]*\:/.test(uri)) { absurl= uri }
  2329. else if (/^\/\//.test(uri)) { absurl= doc._proxy_jslib_base_scheme + uri }
  2330. else if (/^\//.test(uri)) { absurl= doc._proxy_jslib_base_host + uri }
  2331. else if (/^\?/.test(uri)) { absurl= doc._proxy_jslib_base_file + uri }
  2332. else { absurl= doc._proxy_jslib_base_path + uri }
  2333.  
  2334. var ret= _proxy_jslib_url_start + _proxy_jslib_wrap_proxy_encode(absurl) + (retain_query ? query : '') + frag ;
  2335. return ret ;
  2336. }
  2337.  
  2338.  
  2339. function _proxy_jslib_full_url_by_frame(uri_ref, doc, is_frame, reverse, is_frame_src) {
  2340. var old_url_start= _proxy_jslib_url_start ;
  2341. _proxy_jslib_url_start= is_frame ? _proxy_jslib_url_start_inframe : _proxy_jslib_url_start_noframe ;
  2342. try {
  2343. var ret= _proxy_jslib_full_url(uri_ref, doc, reverse, void 0, is_frame_src) ;
  2344. } finally {
  2345. _proxy_jslib_url_start= old_url_start ;
  2346. }
  2347. return ret ;
  2348. }
  2349.  
  2350.  
  2351. // initializes _base vars for the given document
  2352. function _proxy_jslib_set_base_vars(doc, base_url) {
  2353. if (!base_url) base_url= _proxy_jslib_parse_full_url(doc.URL)[3] ;
  2354.  
  2355. // handle "about:blank", etc.
  2356. if (!base_url.match(/^\s*https?\:\/\//i)) {
  2357. doc._proxy_jslib_base_url= doc._proxy_jslib_base_scheme= doc._proxy_jslib_base_host=
  2358. doc._proxy_jslib_base_path= doc._proxy_jslib_base_file= '' ;
  2359. return ;
  2360. }
  2361.  
  2362. doc._proxy_jslib_base_url= base_url.replace(/^\s+|\s+$/g, '')
  2363. .replace(/^([\w\+\.\-]+\:\/\/[^\/\?]+)\/?/, "$1/") ;
  2364. doc._proxy_jslib_base_scheme= doc._proxy_jslib_base_url.match(/^([\w\+\.\-]+\:)\/\//)[1] ;
  2365. doc._proxy_jslib_base_host= doc._proxy_jslib_base_url.match(/^([\w\+\.\-]+\:\/\/[^\/\?]+)/)[1] ;
  2366. doc._proxy_jslib_base_path= doc._proxy_jslib_base_url.match(/^([^\?]*\/)/)[1] ;
  2367. doc._proxy_jslib_base_file= doc._proxy_jslib_base_url.match(/^([^\?]*)/)[1] ;
  2368. }
  2369.  
  2370.  
  2371. function _proxy_jslib_absolute_url(uri, doc) {
  2372. var absurl ;
  2373. doc= doc || document ;
  2374.  
  2375. if (/^[\w\+\.\-]*\:/.test(uri)) { absurl= uri }
  2376. else if (/^\/\//.test(uri)) { absurl= doc._proxy_jslib_base_scheme + uri }
  2377. else if (/^\//.test(uri)) { absurl= doc._proxy_jslib_base_host + uri }
  2378. else if (/^\?/.test(uri)) { absurl= doc._proxy_jslib_base_file + uri }
  2379. else { absurl= doc._proxy_jslib_base_path + uri }
  2380.  
  2381. return absurl ;
  2382. }
  2383.  
  2384.  
  2385.  
  2386. function _proxy_jslib_wrap_proxy_encode(URL) {
  2387. var uf= URL.match(/^([^\#]*)(\#.*)?/) ;
  2388. var uri= uf[1] ;
  2389. var frag= uf[2] ? uf[2] : '' ;
  2390.  
  2391. uri= _proxy_jslib_proxy_encode(uri) ;
  2392. uri= uri.replace(/\=/g, '=3d').replace(/\?/g, '=3f').replace(/\#/g, '=23')
  2393. .replace(/\%/g, '=25').replace(/\&/g, '=26').replace(/\;/g, '=3b')
  2394. .replace(/\[/g, '=5b').replace(/\]/g, '=5d') ;
  2395. while (uri.match(/\/\//)) uri= uri.replace(/\/\//g, '=2f=2f') ;
  2396.  
  2397. return uri + frag ;
  2398. }
  2399.  
  2400. function _proxy_jslib_wrap_proxy_decode(enc_URL) {
  2401. var uf= enc_URL.match(/^([^\?\#]*)([^\#]*)(.*)/) ;
  2402. var uri= uf[1] ;
  2403. var query= uf[2] ;
  2404. var frag= uf[3] ? uf[3] : '' ;
  2405.  
  2406. // Unfortunately, this little function turns out to be a CPU hog
  2407. //uri= uri.replace(/\=(..)/g, function (s,p1) { return String.fromCharCode(eval('0x'+p1)) } ) ;
  2408. uri= uri.replace(/\=2f/g, '/').replace(/\=25/g, '%').replace(/\=23/g, '#')
  2409. .replace(/\=3f/g, '?').replace(/\=26/g, '&').replace(/\=3b/g, ';')
  2410. .replace(/\=3d/g, '=') ;
  2411. uri= _proxy_jslib_proxy_decode(uri) ;
  2412.  
  2413. return uri + query + frag ;
  2414. }
  2415.  
  2416.  
  2417. // Next few functions for Flash 9+ support.
  2418. function _proxy_jslib_full_url_connect(url) {
  2419. var m ;
  2420. //alert('starting _proxy_jslib_full_url_connect('+url+'), typeof=['+(typeof url)+']') ;
  2421. if (!url) return url ;
  2422. if (url.match(/^https?\:\/\//i)) return _proxy_jslib_full_url(url) ;
  2423. if (m= url.match(/^rtmp\:\/\/([^\/]*\/[^\/]*)\/(.*)/i)) {
  2424. var new_app= encodeURIComponent(m[1]) ; // not perfect, but good for now?
  2425. var portst= _proxy_jslib_RTMP_SERVER_PORT==1935 ? '' : ':' + _proxy_jslib_RTMP_SERVER_PORT ;
  2426. return 'rtmp://' + _proxy_jslib_THIS_HOST + portst + '/' + new_app + '/' + m[2] ;
  2427. }
  2428. return url ;
  2429. }
  2430.  
  2431. function _proxy_jslib_full_url_play(url) {
  2432. //alert('starting _proxy_jslib_full_url_play('+url+'), typeof=['+(typeof url)+']') ;
  2433. if (!url) return url ;
  2434. if (typeof url!='string') return url ; // in case called for wrong 'play'
  2435. if (!url.match(/^https?\:\/\//i)) return url ;
  2436. return _proxy_jslib_full_url(url) ; // could use retain_query param when supported
  2437. }
  2438.  
  2439. // simple function for Flash to call, for e.g. flash.display.LoaderInfo.loaderURL
  2440. function _proxy_jslib_reverse_full_url(url) {
  2441. //alert('starting _proxy_jslib_reverse_full_url('+url+')') ;
  2442. return _proxy_jslib_parse_full_url(url)[3] ;
  2443. }
  2444.  
  2445. // simple function for Flash's flash.external.ExternalInterface.call(),
  2446. // which actually can take any JS as its first parameter.
  2447. function _proxy_jslib_proxify_js_array_0(a) {
  2448. //alert('starting _proxy_jslib_proxify_js_array_0()') ;
  2449. if ((a instanceof Array) && ((typeof a[0]=='string') || (a[0] instanceof String)))
  2450. a[0]= _proxy_jslib_proxify_js(a[0]+'()').replace(/\(\)$/, '') ;
  2451. //alert('after _proxy_jslib_proxify_js_array_0:\na=['+JSON.stringify(a)+']\ntypeof a[0]=['+(typeof a[0])+']') ;
  2452. return a ;
  2453. }
  2454.  
  2455. // used when handling apply(), when target object is flash.external.ExternalInterface.call() . :P
  2456. // gets a two-item array, whose second item is an array with call's parameters,
  2457. // the first of which is a function name or body.
  2458. function _proxy_jslib_proxify_js_array_1_0(a) {
  2459. //alert('starting _proxy_jslib_proxify_js_array_1_0; a[1][0]=['+a[1][0]+']') ;
  2460. if ((a instanceof Array) && ((typeof a[1][0]=='string') || (a[1][0] instanceof String)))
  2461. a[1][0]= _proxy_jslib_proxify_js(a[1][0]+'()').replace(/\(\)$/, '') ;
  2462. //alert('ending _proxy_jslib_proxify_js_array_1_0; a[1][0]=['+a[1][0]+']') ;
  2463. return a ;
  2464. }
  2465.  
  2466. var _proxy_jslib_in_mb= 0 ;
  2467. var _proxy_jslib_call_stack= [] ;
  2468. function alert_obj(obj) {
  2469. if (obj==1954) _proxy_jslib_in_mb++ ;
  2470. if (typeof obj=='number' && obj>0) _proxy_jslib_call_stack.unshift(obj) ;
  2471. if (_proxy_jslib_call_stack.length>50) _proxy_jslib_call_stack.pop() ;
  2472. if (_proxy_jslib_in_mb<4) return ;
  2473. alert('in alert_obj, call stack=\n' + _proxy_jslib_call_stack + '\nobj= [' + JSON.stringify(obj) + ']') ;
  2474. // alert('in alert_obj: count=['+_proxy_jslib_in_mb+']; typeof=['+(typeof obj)+'][' + Function.prototype.toString(obj) + ']') ;
  2475. if (typeof obj=='number' && obj==-_proxy_jslib_call_stack[0]) _proxy_jslib_call_stack.shift() ;
  2476. }
  2477.  
  2478.  
  2479.  
  2480. function _proxy_jslib_cookie_to_client(cookie, doc) {
  2481. if (_proxy_jslib_cookies_are_banned_here) return '' ;
  2482.  
  2483. var u= _proxy_jslib_parse_url((doc.defaultView||doc.parentWindow)._proxy_jslib_URL) ;
  2484. if (u==null) {
  2485. alert("CGIProxy Error: Can't parse URL <"+(doc.defaultView||doc.parentWindow)._proxy_jslib_URL+">; not setting cookie.") ;
  2486. return '' ;
  2487. }
  2488. var origin_host= u[4] ;
  2489. var source_path= u[6] ;
  2490. if (source_path.substr(0,1)!='/') source_path= '/' + source_path ;
  2491.  
  2492. cookie= cookie.replace(/[\0\n\r]/g, '') ; // prevent HTTP header injection
  2493.  
  2494. var name, value, expires_clause, path, domain, secure_clause ;
  2495. var new_name, new_value, new_cookie ;
  2496.  
  2497. name= value= expires_clause= path= domain= secure_clause=
  2498. new_name= new_value= new_cookie= '' ;
  2499.  
  2500. if (/^\s*([^\=\;\,\s]*)\s*\=?\s*([^\;]*)/.test(cookie)) {
  2501. name= RegExp.$1 ; value= RegExp.$2 ;
  2502. }
  2503. if (/\;\s*(expires\s*\=[^\;]*)/i.test(cookie)) expires_clause= RegExp.$1 ;
  2504. if (/\;\s*path\s*\=\s*([^\;\,\s]*)/i.test(cookie)) path= RegExp.$1 ;
  2505. if (/\;\s*domain\s*\=\s*([^\;\,\s]*)/i.test(cookie)) domain= RegExp.$1 ;
  2506. if (/\;\s*(secure\b)/i.test(cookie)) secure_clause= RegExp.$1 ;
  2507.  
  2508. if (path=='') path= _proxy_jslib_COOKIE_PATH_FOLLOWS_SPEC ? source_path : '/' ;
  2509.  
  2510. if (domain=='') {
  2511. domain= origin_host ;
  2512. } else {
  2513. domain= domain.replace(/\.+$/, '') ;
  2514. domain= domain.replace(/\.{2,}/g, '.') ;
  2515. if ( (origin_host.substr(origin_host.length-domain.length)!=domain.toLowerCase()) && ('.'+origin_host!=domain) )
  2516. return '' ;
  2517. if (domain.match(/^[\d\.]$/) && (domain!=origin_host)) return '' ; // illegal to use partial IP address
  2518. var dots= domain.match(/\./g) ;
  2519. if (_proxy_jslib_RESPECT_THREE_DOT_RULE) {
  2520. if (dots.length<3 && !( dots.length>=2 && /\.(com|edu|net|org|gov|mil|int)$/i.test(domain) ) )
  2521. return '' ;
  2522. } else {
  2523. if (dots.length<2) {
  2524. if (domain.match(/^\./)) return '' ;
  2525. domain= '.'+domain ;
  2526. if (dots.length<1) return '' ;
  2527. }
  2528. }
  2529. }
  2530.  
  2531. new_name= _proxy_jslib_cookie_encode('COOKIE;'+name+';'+path+';'+domain) ;
  2532. new_value= _proxy_jslib_cookie_encode(value+';'+secure_clause) ;
  2533.  
  2534. if (_proxy_jslib_SESSION_COOKIES_ONLY && (expires_clause!='')) {
  2535. /^expires\s*\=\s*(.*)$/i.test(expires_clause) ;
  2536. var expires_date= RegExp.$1.replace(/\-/g, ' ') ; // Date.parse() can't handle "-"
  2537. if ( Date.parse(expires_date) > (new Date()).getTime() ) expires_clause= '' ;
  2538. }
  2539.  
  2540. new_cookie= new_name+'='+new_value ;
  2541. if (expires_clause!='') new_cookie= new_cookie+'; '+expires_clause ;
  2542. new_cookie= new_cookie+'; path='+_proxy_jslib_SCRIPT_NAME+'/' ;
  2543. // if (secure_clause!='') new_cookie= new_cookie+'; '+secure_clause ;
  2544.  
  2545. return new_cookie ;
  2546. }
  2547.  
  2548.  
  2549. function _proxy_jslib_cookie_from_client(doc) {
  2550. if (_proxy_jslib_cookies_are_banned_here) return _proxy_jslib_COOKIES_FROM_DB ;
  2551. if (!doc.cookie) return _proxy_jslib_COOKIES_FROM_DB ;
  2552.  
  2553. var target_path, target_server, target_scheme ;
  2554. var u= _proxy_jslib_parse_url((doc.defaultView||doc.parentWindow)._proxy_jslib_URL) ;
  2555. if (u==null) {
  2556. alert("CGIProxy Error: Can't parse URL <"+(doc.defaultView||doc.parentWindow)._proxy_jslib_URL+">; not using cookie.") ;
  2557. return ;
  2558. }
  2559. target_scheme= u[1] ;
  2560. target_server= u[4] ;
  2561. target_path= u[6] ;
  2562. if (target_path.substr(0,1)!='/') target_path= '/' + target_path ;
  2563.  
  2564. var matches= new Array() ;
  2565. var pathlen= new Object() ;
  2566. var cookies= doc.cookie.split(/\s*;\s*/) ;
  2567. //for (var c in cookies) {
  2568. for (var c= 0 ; c < cookies.length ; c++) {
  2569. var nv= cookies[c].split('=', 2) ;
  2570. var name= _proxy_jslib_cookie_decode(nv[0]) ;
  2571. var value= _proxy_jslib_cookie_decode(nv[1]) ;
  2572. var n= name.split(/;/) ;
  2573. if (n[0]=='COOKIE') {
  2574. var cname, path, domain, cvalue, secure ;
  2575. cname= n[1] ; path= n[2] ; domain= n[3].toLowerCase() ;
  2576. var v= value.split(/;/) ;
  2577. cvalue= v[0] ; secure= v[1] ;
  2578. if (secure!='' && secure!=null && target_scheme!='https:') continue ;
  2579. if ( ((target_server.substr(target_server.length-domain.length)==domain)
  2580. || (domain=='.'+target_server))
  2581. && target_path.substr(0, path.length)==path )
  2582. {
  2583. matches[matches.length]= cname ? cname+'='+cvalue : cvalue ;
  2584. pathlen[cname+'='+cvalue]= path.length ;
  2585. }
  2586. }
  2587. }
  2588.  
  2589. matches.sort(function (v1,v2) { return (pathlen[v2]-pathlen[v1]) } ) ;
  2590.  
  2591. if (_proxy_jslib_COOKIES_FROM_DB!='') matches.unshift(_proxy_jslib_COOKIES_FROM_DB) ;
  2592.  
  2593. return matches.join('; ') ;
  2594. }
  2595.  
  2596.  
  2597. // this doesn't need to process a response
  2598. function _proxy_jslib_store_cookie_in_db(cookie) {
  2599. var url= _proxy_jslib_url_start_inframe
  2600. + _proxy_jslib_wrap_proxy_encode('x-proxy://cookies/set-cookie?'
  2601. + _proxy_jslib_origin + '&' + _proxy_jslib_cookie_encode(cookie)) ;
  2602. var xhr= new XMLHttpRequest() ;
  2603. xhr.open('GET', url) ;
  2604. xhr.send() ;
  2605. }
  2606.  
  2607.  
  2608.  
  2609.  
  2610. // returns [new_html, remainder, jslib_added, found_frameset]
  2611. // call with reverse=true to un-proxify a block of HTML-- convenient but kinda hacky
  2612. // if still_needs_jslib, then insert jslib; we insert jslib in all pages, since
  2613. // we can't predict future writes on the same page.
  2614. function _proxy_jslib_proxify_html(html, doc, still_needs_jslib, reverse) {
  2615. var out= [] ;
  2616. var match, m2, last_lastIndex= 0, remainder ;
  2617. var tag_name, html_pos, head_pos ;
  2618. var base_url, base_url_jsq, jslib_block, insert_string, insert_pos ;
  2619. var jslib_added= false ;
  2620.  
  2621. if (html==void 0) return [void 0, void 0, false, false] ;
  2622. if (typeof html=='number') return [html, void 0, false, false] ;
  2623.  
  2624. // force html to a string
  2625. html= html.toString() ;
  2626.  
  2627. // start, comment, script_block, style_block, decl_bang, decl_question, tag
  2628. // note that a unique instance of RE must be created, in case of recursion
  2629. var RE= new RegExp(/([^\<]*(?:\<(?![\w\/\!])[^\<]*)*)(?:(\<\!\-\-(?=[\s\S]*?\-\-\>)[\s\S]*?\-\-\s*\>|\<\!\-\-(?![\s\S]*?\-\-\>)[\s\S]*?\>)|(\<script\b[\s\S]*?\<\/script\b[\s\S]*?\>)|(\<style\b[\s\S]*?\<\/style\b[\s\S]*?\>)|(\<\![^\>]*\>)|(\<\?[^\>]*\>)|(\<[^\>]*\>))?/gi) ;
  2630. var RE2= new RegExp(/[^\>]*(?:\>|$)/g) ;
  2631.  
  2632. while ((last_lastIndex!=html.length) && (match= RE.exec(html))) {
  2633. if (match.index!=last_lastIndex) {
  2634. remainder= html.slice(last_lastIndex) ;
  2635. break ;
  2636. }
  2637. last_lastIndex= RE2.lastIndex= RE.lastIndex ;
  2638.  
  2639. out.push(match[1]) ;
  2640.  
  2641. if (match[2]) {
  2642. out.push(_proxy_jslib_proxify_comment(match[2], doc, reverse)) ;
  2643. } else if (match[3]) {
  2644. out.push(_proxy_jslib_proxify_script_block(match[3], doc, reverse)) ;
  2645. } else if (match[4]) {
  2646. out.push(_proxy_jslib_proxify_style_block(match[4], doc, reverse)) ;
  2647. } else if (match[5]) {
  2648. out.push(_proxy_jslib_proxify_decl_bang(match[5], doc, reverse)) ;
  2649. } else if (match[6]) {
  2650. out.push(_proxy_jslib_proxify_decl_question(match[6], doc, reverse)) ;
  2651.  
  2652. } else if (match[7]) {
  2653. m2= match[7].match(/^\<\s*(\/?[A-Za-z][\w\.\:\-]*)/) ;
  2654. if (!m2) continue ; // hack until we parse more rigorously
  2655. tag_name= m2[1].toLowerCase() ;
  2656.  
  2657. // these would indicate incomplete blocks
  2658. if ((tag_name=='script') || (tag_name=='style')) {
  2659. remainder= match[7]+html.slice(last_lastIndex) ;
  2660. break ;
  2661. }
  2662.  
  2663. if ((tag_name=='frameset') && _proxy_jslib_doing_insert_here && !_proxy_jslib_is_in_frame && !reverse) {
  2664. _proxy_jslib_return_frame_doc(_proxy_jslib_wrap_proxy_encode(_proxy_jslib_URL), doc) ;
  2665. return ['', void 0, false, true] ;
  2666. }
  2667.  
  2668. if (tag_name=='/object') _proxy_jslib_current_object_classid= '' ;
  2669.  
  2670. // if undefined return value, add up to next ">" and try again
  2671. var new_element= _proxy_jslib_proxify_element(match[7], doc, reverse) ;
  2672. while (new_element==void 0 && last_lastIndex!=html.length) {
  2673. m2= RE2.exec(html) ;
  2674. last_lastIndex= RE.lastIndex= RE2.lastIndex ;
  2675. match[7]+= m2[0] ;
  2676. new_element= _proxy_jslib_proxify_element(match[7], doc, reverse) ;
  2677. }
  2678. out.push(new_element) ;
  2679.  
  2680. if (tag_name=='html') { html_pos= out.length }
  2681. else if (tag_name=='head') { head_pos= out.length }
  2682.  
  2683. // no <...> block left
  2684. } else {
  2685. break ;
  2686. }
  2687. }
  2688.  
  2689. if ((last_lastIndex!=html.length) && !remainder)
  2690. remainder= html.slice(last_lastIndex) ;
  2691.  
  2692.  
  2693. // Don't worry about top insertion. Hacky.
  2694. // Don't handle _proxy_jslib_needs_jslib, since a not-jslib-requiring write
  2695. // may be followed by a jslib-requiring write; add the JS insertion to all pages.
  2696. if (still_needs_jslib && !reverse) {
  2697.  
  2698. jslib_block= '<script class="_proxy_jslib_jslib" type="text/javascript" src="'
  2699. + _proxy_jslib_html_escape(_proxy_jslib_url_start+_proxy_jslib_wrap_proxy_encode('x-proxy://scripts/jslib'))
  2700. + '"><\/script>\n' ;
  2701.  
  2702. if (!doc._proxy_jslib_base_url) {
  2703. base_url= _proxy_jslib_parse_full_url(doc.URL)[3] ;
  2704. _proxy_jslib_set_base_vars(doc, base_url) ;
  2705. }
  2706. base_url_jsq= doc._proxy_jslib_base_url
  2707. .replace(/(["\\])/g, function (p) { return '\\'+p } ) ;
  2708. if (base_url_jsq!=void 0) base_url_jsq= '"' + base_url_jsq + '"' ;
  2709. var cookies_from_db_jsq= _proxy_jslib_COOKIES_FROM_DB.replace(/(["\\\\])/g, function (p) { return "\\\\"+p } ) ;
  2710. insert_string= '<script class="_proxy_jslib_pv" type="text/javascript">_proxy_jslib_pass_vars('
  2711. + base_url_jsq + ',"'
  2712. + _proxy_jslib_origin + '",'
  2713. + _proxy_jslib_cookies_are_banned_here + ','
  2714. + _proxy_jslib_doing_insert_here + ','
  2715. + _proxy_jslib_SESSION_COOKIES_ONLY + ','
  2716. + _proxy_jslib_COOKIE_PATH_FOLLOWS_SPEC + ','
  2717. + _proxy_jslib_RESPECT_THREE_DOT_RULE + ','
  2718. + _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS + ',"'
  2719. + _proxy_jslib_RTMP_SERVER_PORT + '","'
  2720. + _proxy_jslib_default_script_type + '","'
  2721. + _proxy_jslib_default_style_type + '",'
  2722. + _proxy_jslib_USE_DB_FOR_COOKIES + ','
  2723. + _proxy_jslib_PROXIFY_COMMENTS + ','
  2724. + _proxy_jslib_ALERT_ON_CSP_VIOLATION + ',"'
  2725. + cookies_from_db_jsq + '",'
  2726. + _proxy_jslib_TIMEOUT_MULTIPLIER + ',"'
  2727. + _proxy_jslib_csp_st + '")<\/script>\n' ;
  2728. insert_pos= head_pos || html_pos || 0 ;
  2729. out.splice(insert_pos, 0, jslib_block, insert_string) ;
  2730. jslib_added= true ;
  2731. }
  2732.  
  2733. return [out.join(''), remainder, jslib_added] ;
  2734. }
  2735.  
  2736.  
  2737.  
  2738. function _proxy_jslib_proxify_comment(comment, doc, reverse) {
  2739. if (!_proxy_jslib_PROXIFY_COMMENTS) return comment ;
  2740. var m= comment.match(/^\<\!\-\-([\S\s]*?)(\-\-\s*)?>$/) ;
  2741. var contents= m[1] ;
  2742. var end= m[2] ;
  2743. contents= _proxy_jslib_proxify_html(contents, doc, false, reverse)[0] ;
  2744. comment= '<!--' + contents + end + '>' ;
  2745. return comment ;
  2746. }
  2747.  
  2748.  
  2749. function _proxy_jslib_proxify_decl_bang(decl_bang, doc, reverse) {
  2750. var q ;
  2751. var inside= decl_bang.match(/^\<\!([^>]*)/)[1] ;
  2752. var words= inside.match(/\"[^\"\>]*\"?|\'[^\'\>]*\'?|[^\'\"][^\s\>]*/g) ;
  2753. for (var i=0 ; i<words.length ; i++) {
  2754. words[i]= words[i].replace(/^\s*/, '') ;
  2755. if (words[i].match(/^[\'\"]?http\:\/\/www\.w3\.org\//)) continue ;
  2756. if (words[i].match(/^[\"\']?[\w\+\.\-]+\:\/\//)) {
  2757. if (words[i].match(/^'/)) { q= "'" ; words[i]= words[i].replace(/^\'|\'$/g, '') }
  2758. else if (words[i].match(/^"/)) { q= '"' ; words[i]= words[i].replace(/^\"|\"$/g, '') }
  2759. else { q= '' }
  2760. words[i]= q + _proxy_jslib_full_url(words[i], doc, reverse) + q ;
  2761. }
  2762. }
  2763. decl_bang= '<!' + words.join(' ') + '>' ;
  2764. return decl_bang ;
  2765. }
  2766.  
  2767.  
  2768. function _proxy_jslib_proxify_decl_question(decl_question, doc, reverse) {
  2769. return decl_question ;
  2770. }
  2771.  
  2772.  
  2773. function _proxy_jslib_proxify_script_block(script_block, doc, reverse) {
  2774. var m1, m2, tag, script, attrs, attr, name ;
  2775. attr= new Object() ;
  2776.  
  2777. m1= script_block.match(/^(\<\s*script\b[^\>]*\>)([\s\S]*)\<\s*\/script\b[^\>]*\>$/i) ;
  2778.  
  2779. script= m1[2] ;
  2780. if (script.match(/\S/) && !_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['script-src'], "'unsafe-inline'"))
  2781. _proxy_jslib_throw_csp_error("CSP script-src inline error") ;
  2782.  
  2783. tag= _proxy_jslib_proxify_element(m1[1], doc, reverse) ;
  2784.  
  2785. attrs= tag.match(/^\<\s*script\b([^\>]*)\>/i)[1] ;
  2786.  
  2787. while (m2= attrs.match(/([A-Za-z][\w\.\:\-]*)\s*(\=\s*(\"([^\"\>]*)\"?|\'([^\'\>]*)\'?|([^\'\"][^\s\>]*)))?/)) {
  2788. attrs= attrs.substr(m2[0].length) ;
  2789. name= m2[1].toLowerCase() ;
  2790. if (attr[name]!=null) continue ;
  2791. attr[name]= m2[4] ? m2[4] : m2[5] ? m2[5] : m2[6] ? m2[6] : '' ;
  2792. attr[name]= _proxy_jslib_html_unescape(attr[name]) ;
  2793. }
  2794. if (attr.type!=null) attr.type= attr.type.toLowerCase() ;
  2795. if (!attr.type && attr.language) {
  2796. attr.type= attr.language.match(/javascript|ecmascript|livescript|jscript/i)
  2797. ? 'application/x-javascript'
  2798. : attr.language.match(/css/i) ? 'text/css'
  2799. : attr.language.match(/vbscript/i) ? 'application/x-vbscript'
  2800. : attr.language.match(/perl/i) ? 'application/x-perlscript'
  2801. : attr.language.match(/tcl/i) ? 'text/tcl'
  2802. : '' ;
  2803. }
  2804. if (!attr.type) attr.type= _proxy_jslib_default_script_type ;
  2805.  
  2806. // For now, don't worry about "<\/script" (unescaped) inside JS-written scripts.
  2807.  
  2808. script= _proxy_jslib_proxify_block(script, attr.type,
  2809. _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, reverse) ;
  2810.  
  2811. return tag+script+'<\/script>' ;
  2812. }
  2813.  
  2814.  
  2815. function _proxy_jslib_proxify_style_block(style_block, doc, reverse) {
  2816. var m1, m2, tag, stylesheet, attrs, type ;
  2817. m1= style_block.match(/^(\<\s*style\b[^\>]*\>)([\s\S]*)\<\s*\/style\b[^\>]*\>$/i) ;
  2818.  
  2819. stylesheet= m1[2] ;
  2820. if (stylesheet.match(/\S/) && !_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['style-src'], "'unsafe-inline'"))
  2821. _proxy_jslib_throw_csp_error("CSP style-src inline error") ;
  2822.  
  2823. tag= _proxy_jslib_proxify_element(m1[1], doc, reverse) ;
  2824.  
  2825. attrs= tag.match(/^\<\s*style\b([^\>]*)\>/i)[1] ;
  2826.  
  2827. while (m2= attrs.match(/([A-Za-z][\w\.\:\-]*)\s*(\=\s*(\"([^\"\>]*)\"?|\'([^\'\>]*)\'?|([^\'\"][^\s\>]*)))?/)) {
  2828. attrs= attrs.substr(m2[0].length) ;
  2829. if (m2[1].toLowerCase()=='type') {
  2830. type= m2[4]!=null ? m2[4] : m2[5]!=null ? m2[5] : m2[6]!=null ? m2[6] : '' ;
  2831. type= _proxy_jslib_html_unescape(type).toLowerCase() ;
  2832. break ;
  2833. }
  2834. }
  2835. if (!type) type= _proxy_jslib_default_style_type ;
  2836. stylesheet= _proxy_jslib_proxify_block(stylesheet, type,
  2837. _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, reverse) ;
  2838.  
  2839. return tag+stylesheet+'<\/style>' ;
  2840. }
  2841.  
  2842.  
  2843.  
  2844. // returns undef on error, like when "<>" are in an attribute (hacky)
  2845. function _proxy_jslib_proxify_element(element, doc, reverse) {
  2846. // Unfortunately, attr{} may have extra properties if a Web page changes
  2847. // anything in the Object prototype. Thus, we use names[] to keep track
  2848. // of the tag's attributes. We do this elsewhere too.
  2849. var m1, m2, tag_name, attrs, attr= {}, names= [], name, i, rebuild, end_slash,
  2850. old_url_start ;
  2851. if (!doc) doc= window.document ;
  2852.  
  2853. if (!(m1= element.match(/^\<\s*([A-Za-z][\w\.\:\-]*)\s*([\s\S]*)$/))) return element ;
  2854. tag_name= m1[1].toLowerCase() ;
  2855. attrs= m1[2] ;
  2856. // ignore possibility of <frameset> tag
  2857. if (attrs=='') return element ;
  2858.  
  2859. // note that last match indicates an unterminated string
  2860. while (m2= attrs.match(/([A-Za-z][\w\.\:\-]*)\s*(\=\s*(\"([^\"]*)\"|\'([^\']*)\'|([^\'\"][^\s\>]*)|(\'[^\']*$|\"[^\"]*$)))?/)) {
  2861. // if ends on broken string, return undef
  2862. if (m2[7]) return void 0 ;
  2863. attrs= attrs.substr(m2.index+m2[0].length) ;
  2864. name= m2[1].toLowerCase() ;
  2865. if (name in attr) { rebuild= 1 ; continue }
  2866. // must compare to both undefined and '' to cover all browsers
  2867. attr[name]= (m2[4]!=void 0 && m2[4]!='') ? m2[4]
  2868. : (m2[5]!=void 0 && m2[5]!='') ? m2[5]
  2869. : (m2[6]!=void 0 && m2[6]!='') ? m2[6]
  2870. : '' ;
  2871. attr[name]= _proxy_jslib_html_unescape(attr[name]) ;
  2872. names.push(name) ;
  2873. }
  2874.  
  2875.  
  2876. // Now we have tag_name, attr[], and names[] set.
  2877.  
  2878. // for (name in attr) {
  2879. for (i= 0 ; i<names.length ; i++) {
  2880. name= names[i] ;
  2881. // for now, simply delete attributes with script macros
  2882. if (attr[name].match(/\&\{.*\}\;/)) { delete attr[name] ; rebuild= 1 ; continue }
  2883.  
  2884. if (name.match(/^on/)) {
  2885. attr[name]= _proxy_jslib_proxify_block(attr[name], _proxy_jslib_default_script_type, _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, reverse) ;
  2886. rebuild= 1 ;
  2887. }
  2888. }
  2889.  
  2890.  
  2891. if (tag_name=='object') {
  2892. _proxy_jslib_current_object_classid= attr.classid ;
  2893. if (attr.data) {
  2894. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['object-src'], _proxy_jslib_absolute_url(attr.data)))
  2895. _proxy_jslib_throw_csp_error('object-src violation in <object data> attribute') ;
  2896. var old_url_start= _proxy_jslib_url_start ;
  2897. var flags_5= _proxy_jslib_flags[5] ;
  2898. _proxy_jslib_flags[5]= 1 ;
  2899. try {
  2900. _proxy_jslib_url_start= _proxy_jslib_url_start_by_flags(_proxy_jslib_flags) ;
  2901. attr.data= _proxy_jslib_full_url(attr.data, doc, reverse) ;
  2902. } finally {
  2903. _proxy_jslib_url_start= old_url_start ;
  2904. _proxy_jslib_flags[5]= flags_5 ;
  2905. }
  2906. rebuild= 1 ;
  2907. }
  2908.  
  2909. } else if (tag_name=='param') {
  2910. // if (_proxy_jslib_current_object_classid &&
  2911. // _proxy_jslib_current_object_classid.match(/^\s*clsid\:\{?D27CDB6E-AE6D-11CF-96B8-444553540000\}?\s*$/i))
  2912. // {
  2913. if (attr.name && attr.name.match(/^movie$/i)) {
  2914. attr.value= _proxy_jslib_full_url(attr.value, doc, reverse, 1) ;
  2915. rebuild= 1 ;
  2916. }
  2917. // }
  2918.  
  2919. } else if (tag_name=='applet') {
  2920. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['object-src'], _proxy_jslib_absolute_url(attr.code)))
  2921. _proxy_jslib_throw_csp_error('object-src violation in <applet code> attribute') ;
  2922. var arcs= attr.archive.split(/\s+/) ;
  2923. for (var i= 0 ; i<arcs.length ; i++)
  2924. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['object-src'], _proxy_jslib_absolute_url(arcs[i])))
  2925. _proxy_jslib_throw_csp_error('object-src violation in <applet archive> attribute') ;
  2926. var old_base_url= doc._proxy_jslib_base_url ;
  2927. if (attr.codebase) _proxy_jslib_set_base_vars(doc, attr.codebase) ;
  2928. attr.code= _proxy_jslib_full_url(attr.code, doc, reverse) ;
  2929. for (var i ; i<arcs.length ; i++)
  2930. arcs[i]= _proxy_jslib_full_url(arcs[i], doc, reverse) ;
  2931. attr.archive= arcs.join(' ') ;
  2932. _proxy_jslib_set_base_vars(doc, old_base_url) ;
  2933. rebuild= 1 ;
  2934.  
  2935. } else if (tag_name=='base') {
  2936. (doc.defaultView||doc.parentWindow)._proxy_jslib_base_unframes= attr.target && attr.target.match(/^_(top|blank)$/i) ;
  2937. }
  2938.  
  2939.  
  2940. if ('style' in attr) {
  2941. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['style-src'], "'unsafe-inline'"))
  2942. _proxy_jslib_throw_csp_error('style-src violation with <'+tag_name+' style> attribute') ;
  2943. if (attr.style.match(/(expression|function)\s*\(/i ))
  2944. attr.style= _proxy_jslib_global_replace(attr.style, /\b((expression|function)\s*\()([^\)]*)/i,
  2945. function (p) { return p[1]+_proxy_jslib_proxify_js(p[3], void 0, void 0, void 0, reverse) } ) ;
  2946.  
  2947. attr.style= _proxy_jslib_proxify_block(attr.style, _proxy_jslib_default_style_type, _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, reverse) ;
  2948. rebuild= 1 ;
  2949. }
  2950.  
  2951. // huge simplification of tag-specific block
  2952. if (('href' in attr) && tag_name.match(/^(a|base|area|link)$/)) {
  2953. if ((tag_name=='link') && (attr.rel && attr.rel.toLowerCase()=='icon')
  2954. && !_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['img-src'], _proxy_jslib_absolute_url(attr.href)))
  2955. {
  2956. _proxy_jslib_throw_csp_error("img-src violation in <link rel=icon href> attribute") ;
  2957. } else if (tag_name=='base') {
  2958. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['base-uri'], _proxy_jslib_absolute_url(attr.href)))
  2959. _proxy_jslib_throw_csp_error("CSP base-uri error: " + val) ;
  2960. _proxy_jslib_set_base_vars(doc, attr.href) ;
  2961. }
  2962.  
  2963. if ( ((doc.defaultView||doc.parentWindow)._proxy_jslib_base_unframes && attr.target==void 0) ||
  2964. (attr.target && attr.target.match(/^_(top|blank)$/i)) )
  2965. attr.href= _proxy_jslib_full_url_by_frame(attr.href, doc, 0, reverse) ;
  2966. else
  2967. attr.href= _proxy_jslib_full_url(attr.href, doc, reverse)
  2968. rebuild= 1 ;
  2969. }
  2970.  
  2971. if ('src' in attr) {
  2972. if (tag_name=='frame' || tag_name=='iframe') {
  2973. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['frame-src'], _proxy_jslib_absolute_url(attr.src)))
  2974. _proxy_jslib_throw_csp_error("CSP frame-src inline error") ;
  2975. attr.src= _proxy_jslib_full_url_by_frame(attr.src, doc, 1, reverse, 1) ; rebuild= 1 ;
  2976. } else if (tag_name=='script') { // messy :P
  2977. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['script-src'], _proxy_jslib_absolute_url(attr.src))) {
  2978. _proxy_jslib_throw_csp_error("CSP script-src inline error") ;
  2979. } else {
  2980. var old_url_start= _proxy_jslib_url_start ;
  2981. var flags_6= _proxy_jslib_flags[6] ;
  2982. _proxy_jslib_flags[6]= (attr.type!==void 0) ? attr.type : _proxy_jslib_default_script_type ;
  2983. try {
  2984. _proxy_jslib_url_start= _proxy_jslib_url_start_by_flags(_proxy_jslib_flags) ;
  2985. attr.src= _proxy_jslib_full_url(attr.src, doc, reverse) ; rebuild= 1 ;
  2986. } finally {
  2987. _proxy_jslib_url_start= old_url_start ;
  2988. _proxy_jslib_flags[6]= flags_6 ;
  2989. }
  2990. }
  2991. } else if (tag_name=='embed') {
  2992. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['object-src'], _proxy_jslib_absolute_url(attr.src)))
  2993. _proxy_jslib_throw_csp_error("object-src violation in <embed src> attribute") ;
  2994. { attr.src= _proxy_jslib_full_url(attr.src, doc, reverse, (attr.type && attr.type.toLowerCase()=='application/x-shockwave-flash')) ; rebuild= 1 }
  2995. } else if (tag_name=='img') {
  2996. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['img-src'], _proxy_jslib_absolute_url(attr.src)))
  2997. _proxy_jslib_throw_csp_error("img-src violation in <img src> attribute") ;
  2998. attr.src= _proxy_jslib_full_url(attr.src, doc, reverse) ; rebuild= 1 ;
  2999. } else if (tag_name=='video' || tag_name=='audio' || tag_name=='source' || tag_name=='track') {
  3000. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['media-src'], _proxy_jslib_absolute_url(attr.src)))
  3001. _proxy_jslib_throw_csp_error("media-src violation in <"+tag_name+" src> attribute") ;
  3002. attr.src= _proxy_jslib_full_url(attr.src, doc, reverse) ; rebuild= 1 ;
  3003. } else {
  3004. attr.src= _proxy_jslib_full_url(attr.src, doc, reverse) ; rebuild= 1 ;
  3005. }
  3006. }
  3007.  
  3008. if ('srcdoc' in attr) {
  3009. if (tag_name=='iframe') attr.srcdoc= _proxy_jslib_proxify_html(attr.srcdoc, doc, 1, reverse)[0] ; rebuild= 1 }
  3010. if ('lowsrc' in attr) {
  3011. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['img-src'], _proxy_jslib_absolute_url(attr.lowsrc)))
  3012. _proxy_jslib_throw_csp_error("img-src violation in <img lowsrc> attribute") ;
  3013. attr.lowsrc= _proxy_jslib_full_url(attr.lowsrc, doc, reverse) ; rebuild= 1 ;
  3014. }
  3015. if ('action' in attr) {
  3016. if ( ((doc.defaultView||doc.parentWindow)._proxy_jslib_base_unframes && attr.target==void 0) ||
  3017. (attr.target && attr.target.match(/^_(top|blank)$/i)) )
  3018. attr.action= _proxy_jslib_full_url_by_frame(attr.action, doc, 0, reverse) ;
  3019. else
  3020. attr.action= _proxy_jslib_full_url(attr.action, doc, reverse) ;
  3021. rebuild= 1 ;
  3022. }
  3023. if ('dynsrc' in attr) { attr.dynsrc= _proxy_jslib_full_url(attr.dynsrc, doc, reverse) ; rebuild= 1 }
  3024. if ('formaction' in attr) { attr.formaction= _proxy_jslib_full_url(attr.formaction, doc, reverse) ; rebuild= 1 }
  3025. if ('background' in attr) { attr.background= _proxy_jslib_full_url(attr.background, doc, reverse) ; rebuild= 1 }
  3026. if ('usemap' in attr) { attr.usemap= _proxy_jslib_full_url(attr.usemap, doc, reverse) ; rebuild= 1 }
  3027. if ('cite' in attr) { attr.cite= _proxy_jslib_full_url(attr.cite, doc, reverse) ; rebuild= 1 }
  3028. if ('longdesc' in attr) { attr.longdesc= _proxy_jslib_full_url(attr.longdesc, doc, reverse) ; rebuild= 1 }
  3029. if ('codebase' in attr) { attr.codebase= _proxy_jslib_full_url(attr.codebase, doc, reverse) ; rebuild= 1 }
  3030. if ('poster' in attr) { attr.poster= _proxy_jslib_full_url(attr.poster, doc, reverse) ; rebuild= 1 }
  3031. if ('pluginspage' in attr) { attr.pluginspage= _proxy_jslib_full_url(attr.pluginspage, doc, reverse) ; rebuild= 1 }
  3032.  
  3033. if ((tag_name=='meta') && attr['http-equiv'] && attr['http-equiv'].match(/^\s*refresh\b/i)) {
  3034. attr.content= _proxy_jslib_global_replace(
  3035. attr.content,
  3036. /(\;\s*URL\=)\s*(\S*)/i,
  3037. function (a) { return a[1] + _proxy_jslib_full_url(a[2], doc, reverse) } ) ;
  3038. rebuild= 1 ;
  3039. }
  3040.  
  3041.  
  3042. // Now attr[] has been modified correctly.
  3043.  
  3044.  
  3045.  
  3046.  
  3047. if (!rebuild) return element ;
  3048.  
  3049. attrs= '' ;
  3050. for (i= 0 ; i<names.length ; i++) {
  3051. name= names[i] ;
  3052. if (attr[name]==null) continue ;
  3053. if (attr[name]=='') { attrs+= ' '+name ; continue }
  3054. if (!attr[name].match(/\"/) || attr[name].match(/\'/)) {
  3055. attrs+= ' '+name+'="'+_proxy_jslib_html_escape(attr[name])+'"' ;
  3056. } else {
  3057. attrs+= ' '+name+"='"+_proxy_jslib_html_escape(attr[name])+"'" ;
  3058. }
  3059. }
  3060.  
  3061. end_slash= element.match(/\/\s*>?$/) ? ' /' : '' ;
  3062. return '<'+tag_name+attrs+end_slash+'>' ;
  3063. }
  3064.  
  3065.  
  3066.  
  3067. function _proxy_jslib_element2tag (e) {
  3068. var ret= '', i ;
  3069. if (e.nodeType!=1) alert('in element2tag; nodeType=['+e.nodeType+']') ;
  3070. for (i= 0 ; i<e.attributes.length ; i++)
  3071. ret+= ' '+e.attributes[i].nodeName+'="'+e.attributes[i].nodeValue+'"' ;
  3072. ret= '<'+e.tagName+ret+'>' ;
  3073. for (i=0 ; i<e.childNodes.length ; i++)
  3074. if (e.childNodes[i].nodeType==1) ret+= '\n'+_proxy_jslib_element2tag(e.childNodes[i]) ;
  3075. else if (e.childNodes[i].nodeType==3) ret+= '\n'+e.childNodes[i].nodeValue ;
  3076. return ret ;
  3077. }
  3078.  
  3079.  
  3080.  
  3081. // this mimics much of _proxy_jslib_proxify_element(), above
  3082. // sometimes we have element, sometimes we have attr
  3083. function _proxy_jslib_proxify_attribute(element, attr, name, value, reverse) {
  3084. if (/\&\{.*\}\;/.test(value)) return ;
  3085.  
  3086. name= name.toLowerCase() ;
  3087. element= element || (attr && attr.ownerElement) ;
  3088. var element_name= element ? element.nodeName.toLowerCase() : '' ;
  3089.  
  3090. // when proxifying URL, assume it's in a frame, since most of the time this
  3091. // routine is called it will be in a frame... not perfect....
  3092. if (/^(href|src|lowsrc|dynsrc|action|background|usemap|cite|longdesc|codebase|poster)$/i.test(name)) {
  3093. // don't convert href if it's not one of these four elements... hacky....
  3094. if ((name=='href') && !element_name.match(/^(a|area|base|link)$/i))
  3095. return value ;
  3096. return _proxy_jslib_full_url_by_frame(value, null, true, reverse,
  3097. name.toLowerCase()=='src' && element_name.match(/^i?frame$/i) ) ;
  3098. } else if (/^on/i.test(name)) {
  3099. return _proxy_jslib_proxify_block(value, _proxy_jslib_default_script_type,
  3100. _proxy_jslib_ALLOW_UNPROXIFIED_SCRIPTS, reverse) ;
  3101. } else if (/^style$/i.test(name)) {
  3102. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['style-src'], "'unsafe-inline'"))
  3103. _proxy_jslib_throw_csp_error('style-src violation with style attribute') ;
  3104. if (/\b(expression|function)\s*\(/i.test(value)) return ;
  3105. else return value ;
  3106. } else if (/^data$/i.test(name) && element_name.match(/^object$/i)) {
  3107. return _proxy_jslib_full_url_by_frame(value, null, true, reverse) ;
  3108. } else {
  3109. return value ;
  3110. }
  3111. }
  3112.  
  3113.  
  3114.  
  3115. function _proxy_jslib_proxify_block(s, type, unknown_type_ok, reverse) {
  3116. if (type) type= type.toLowerCase() ;
  3117.  
  3118. if (type=='text/css') {
  3119. return _proxy_jslib_proxify_css(s, reverse) ;
  3120.  
  3121. } else if (type && type.match(/^(application\/x\-javascript|application\/x\-ecmascript|application\/javascript|application\/ecmascript|text\/javascript|text\/ecmascript|text\/livescript|text\/jscript)$/)) {
  3122. return _proxy_jslib_proxify_js(s, 1, void 0, void 0, reverse) ;
  3123.  
  3124. } else {
  3125. return unknown_type_ok ? s : '' ;
  3126. }
  3127. }
  3128.  
  3129.  
  3130.  
  3131. function _proxy_jslib_proxify_css(css, reverse) {
  3132. // false in, false out
  3133. if (!css || (typeof css!='string')) return css ;
  3134.  
  3135. var out= '', m1, q, out2 ;
  3136. while (m1= css.match(/(\@font\-face\s*\{([^}]*)\})|\burl\s*\(\s*(([^\)]*\\\))*[^\)]*)(\)|$)/i)) {
  3137. if (m1[1]) {
  3138. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['img-src'], _proxy_jslib_absolute_url(m1[3])))
  3139. _proxy_jslib_throw_csp_error('img-src violation in url()') ;
  3140. out+= css.substr(0,m1.index) + '@font-face {' + _proxy_jslib_proxify_font_face(m1[1], null, reverse) + '}' ;
  3141. } else {
  3142. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['img-src'], _proxy_jslib_absolute_url(m1[3])))
  3143. _proxy_jslib_throw_csp_error('img-src violation in url()') ;
  3144. out+= css.substr(0,m1.index) + 'url(' + _proxy_jslib_css_full_url(m1[3], null, reverse) + ')' ;
  3145. }
  3146. css= css.substr(m1.index+m1[0].length) ;
  3147. }
  3148. out+= css ;
  3149.  
  3150. css= out ;
  3151. out= '' ;
  3152. while (m1= css.match(/\@import\s*(\"[^"]*\"|\'[^']*\'|[^\;\s\<]*)/i)) {
  3153. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['style-src'], _proxy_jslib_absolute_url(m1[1])))
  3154. _proxy_jslib_throw_csp_error('style-src violation in @import') ;
  3155. if (!m1[1].match(/^url\s*\(/i)) { // to avoid use of "(?!...)"
  3156. out+= css.substr(0,m1.index) + '@import ' + _proxy_jslib_css_full_url(m1[1], null, reverse) ;
  3157. } else {
  3158. out+= css.substr(0,m1.index) + m1[0] ;
  3159. }
  3160. css= css.substr(m1.index+m1[0].length) ;
  3161. }
  3162. out+= css ;
  3163.  
  3164. // this is imperfect, but should work for virtually all cases
  3165. css= out ;
  3166. out= '' ;
  3167. while (m1= css.match(/\bimage\s*\((\"[^"]*\"|\'[^']*\'|\#?\w+(\([^\)]*\))\))/i)) {
  3168. out2= [] ;
  3169. var items= m1[1].split(/\s*,\s*/) ;
  3170. for (var i= 0 ; i<items.length ; i++) {
  3171. if (items[i].match(/^['"]/)) {
  3172. q= items[i].slice(0, 1) ;
  3173. items[i]= items[i].slice(1, -1) ;
  3174. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['img-src'], _proxy_jslib_absolute_url(items[i])))
  3175. _proxy_jslib_throw_csp_error('img-src violation in image()') ;
  3176. out2.push(q + _proxy_jslib_full_url(items[i], null, reverse) + q) ;
  3177. } else {
  3178. out2.push(items[i]) ;
  3179. }
  3180. }
  3181. out+= 'image(' + out2.join(',') + ')' ;
  3182. css= css.substr(m1.index+m1[0].length) ;
  3183. }
  3184. out+= css ;
  3185.  
  3186. css= out ;
  3187. out= '' ;
  3188. while (m1= css.match(/((expression|function)\s*\()([^)]*)/i)) {
  3189. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['script-src'], _proxy_jslib_absolute_url(m1[3])))
  3190. _proxy_jslib_throw_csp_error('script-src violation') ;
  3191. out+= css.substr(0,m1.index) + m1[1] + _proxy_jslib_proxify_js(m1[3], void 0, void 0, void 0, reverse) ;
  3192. css= css.substr(m1.index+m1[0].length) ;
  3193. }
  3194. out+= css ;
  3195.  
  3196. return out ;
  3197. }
  3198.  
  3199.  
  3200. function _proxy_jslib_css_full_url(url, doc, reverse) {
  3201. var q= '' ;
  3202. url= url.replace(/\s+$/, '') ;
  3203. if (url.match(/^\"/)) { q= '"' ; url= url.replace(/^\"|\"$/g, '') }
  3204. else if (url.match(/^\'/)) { q= "'" ; url= url.replace(/^\'|\'$/g, '') }
  3205. url= url.replace(/\\(.)/g, "$1").replace(/^\s+|\s+$/g, '') ;
  3206. url= _proxy_jslib_full_url(url, doc, reverse) ;
  3207. url= url.replace(/([\(\)\,\s\'\"\\])/g, function (p) { return '\\'+p } ) ;
  3208. return q+url+q ;
  3209. }
  3210.  
  3211.  
  3212. function _proxy_jslib_proxify_font_face(css, doc, reverse) {
  3213. var out= '' ;
  3214. while (m1= css.match(/\burl\s*\(\s*(([^\)]*\\\))*[^\)]*)(\)|$)/i)) {
  3215. if (!_proxy_jslib_match_csp_source_list(_proxy_jslib_csp['font-src'], _proxy_jslib_absolute_url(m1[1])))
  3216. _proxy_jslib_throw_csp_error('font-src violation in url()') ;
  3217. out+= css.substr(0,m1.index) + 'url(' + _proxy_jslib_css_full_url(m1[1], doc, reverse) + ')' ;
  3218. css= css.substr(m1.index+m1[0].length) ;
  3219. }
  3220. out+= css ;
  3221. return out ;
  3222. }
  3223.  
  3224.  
  3225.  
  3226. function _proxy_jslib_return_frame_doc(enc_URL, doc) {
  3227. var top_URL= _proxy_jslib_html_escape(_proxy_jslib_url_start_inframe
  3228. + _proxy_jslib_wrap_proxy_encode('x-proxy://frames/topframe?URL='
  3229. + encodeURIComponent(enc_URL) ) ) ;
  3230. var page_URL= _proxy_jslib_html_escape(_proxy_jslib_url_start_inframe + enc_URL) ;
  3231. doc.open();
  3232. doc.write('<html>\n<frameset rows="80,*">\n'
  3233. + '<frame src="'+top_URL+'">\n<frame src="'+page_URL+'" name="_proxy_jslib_main_frame">\n'
  3234. + '<\/frameset>\n</html>') ;
  3235. doc.close() ;
  3236. //alert('in return_frame_doc, after writing doc; top_URL, page_URL=\n['+top_URL+']\n['+page_URL+']') ;
  3237. }
  3238.  
  3239.  
  3240.  
  3241. function _proxy_jslib_match_csp_source_list(directives, uri) {
  3242. var match, pr_uri, i, j, m1, uscheme, uhost, uport, upath,
  3243. sscheme, shost, sport, spath, pscheme, phost, pport ;
  3244.  
  3245. if (!_proxy_jslib_csp_is_supported) return true ;
  3246.  
  3247. if ((uri==void 0) || (directives==void 0)) return true ;
  3248.  
  3249. pr_uri= _proxy_jslib_URL ; // may add as parameter later
  3250.  
  3251. if (uri=="'unsafe-inline'" || uri=="'unsafe-eval'") {
  3252. for (i= 0 ; i<directives.length ; i++) {
  3253. match= false ;
  3254. for (j= 0 ; j<directives[i].length ; j++) {
  3255. if (directives[i][j]==uri) {
  3256. match= true ;
  3257. break ;
  3258. }
  3259. }
  3260. if (!match) return false ;
  3261. }
  3262. return true ;
  3263. }
  3264.  
  3265. uri= _proxy_jslib_absolute_url(uri) ;
  3266.  
  3267. m1= _proxy_jslib_parse_url(uri) ;
  3268. uscheme= m1[1] ;
  3269. uhost= m1[4] ;
  3270. uport= m1[5] || ((uscheme=='http:') ? 80 : (uscheme=='https:') ? 443 : void 0) ;
  3271. upath= decodeURIComponent(m1[6]) ;
  3272. if (!upath.match(/^\//)) upath= '/' + upath ;
  3273.  
  3274. for (i= 0 ; i<directives.length ; i++) {
  3275. match= false ;
  3276. for (j= 0 ; j<directives[i].length ; j++) {
  3277. if (directives[i][j]=="'none'") return false ;
  3278. if (directives[i][j]=="*") {
  3279. match= true ;
  3280. break ;
  3281. }
  3282.  
  3283. if (directives[i][j].match(/^[\w+\.\-]+\:$/)) {
  3284. if (directives[i][j]==uscheme) {
  3285. match= true ;
  3286. break ;
  3287. }
  3288. continue ;
  3289.  
  3290. } else if (!directives[i][j].match(/^\'/)) {
  3291. if (!uhost) continue ;
  3292.  
  3293. // can't parse as normal URL because of possibility of "*"
  3294. m1= directives[i][j].match(/^(([\w\+\.\-]+:)\/\/)?([^\/\?\:]*)(:([^\/\?]*))?([^\?]*)/) ;
  3295. sscheme= m1[2] ;
  3296. shost= m1[3] ;
  3297. sport= m1[5] || ((sscheme=='http:') ? 80 : (sscheme=='https:') ? 443 : void 0) ;
  3298. spath= decodeURIComponent(m1[6]) ;
  3299.  
  3300. if (sscheme && (sscheme!=uscheme)) continue ;
  3301. if (!sscheme) {
  3302. if (pr_uri.match(/^http\:/) && (uscheme!='http:') && (uscheme!='https:')) continue ;
  3303. if (!pr_uri.match(/^http\:/) && (pr_uri.slice(0, uscheme.length)!=uscheme)) continue ;
  3304. }
  3305.  
  3306. if ((m1= shost.match(/^\*(\..*)/)) && (uhost.slice(-m1[1].length)!=m1[1])) continue ;
  3307. if (!shost.match(/^\*\..*/) && (uhost!=shost)) continue ; // corrected rule 4.6
  3308. if (!sport && (uport!= ((uscheme=='http:') ? 80 : (uscheme=='https:') ? 443 : -1)) ) continue ;
  3309. if (sport && (sport!='*') && (sport!=uport)) continue ;
  3310. if (spath && spath.match(/^\/$/) && (upath.slice(0, spath.length)!=spath)) continue ;
  3311. if (spath && !spath.match(/^\/$/) && (spath!=upath)) continue ;
  3312. match= true ;
  3313. break ;
  3314.  
  3315. } else if (directives[i][j]=="'self'") {
  3316. m1= pr_uri.match(/^(([\w\+\.\-]+:)\/\/)?([^\/\?\:]*)(:([^\/\?]*))?([^\?]*)/) ;
  3317. pscheme= m1[2] ;
  3318. phost= m1[3] ;
  3319. pport= m1[5] || ((pscheme=='http:') ? 80 : (pscheme=='https:') ? 443 : void 0) ;
  3320.  
  3321. if ((uscheme==pscheme) && (uhost==phost) && (uport==pport)) {
  3322. match= true ;
  3323. break ;
  3324. }
  3325. }
  3326. }
  3327. if (!match) false ;
  3328. }
  3329. return true ;
  3330. }
  3331.  
  3332.  
  3333. function _proxy_jslib_throw_csp_error(msg) {
  3334. if (_proxy_jslib_ALERT_ON_CSP_VIOLATION) alert("CSP violation: " + msg) ;
  3335. throw new Error("CSP violation: " + msg) ;
  3336. }
  3337.  
  3338.  
  3339. function _proxy_jslib_csp_is_supported_test() {
  3340. var ua= navigator.userAgent ;
  3341. var match ;
  3342. if (match= ua.match(/\bChrome\/(\d+)/)) return match[1]>=25 ;
  3343. if (match= ua.match(/\bFirefox\/(\d+)/)) return match[1]>=23 ;
  3344.  
  3345. return false ;
  3346. }
  3347.  
  3348.  
  3349.  
  3350. //---- everything needed to handle proxify_js() ------------------------
  3351.  
  3352. // This takes a string as input, and returns a string as output. It calls
  3353. // _proxy_jslib_proxify_js_tokens() to do the real work.
  3354. // Currently this only returns the proxified string, not the remainder.
  3355. // It turns out that Array.shift() and Array.unshift() are implemented
  3356. // inefficiently in both Firefox and MSIE, such that it seems to require
  3357. // the whole Array to shift down in memory; thus, shifting the whole array
  3358. // goes as O(n^2). Additionally, Array.pop() is implemented equally
  3359. // inefficiently in MSIE, i.e. the time for one pop() is proportional to
  3360. // the length of the array. Thus, this routine is written to maintain a
  3361. // single unchanging token array with pointers into it, which is probably
  3362. // a good approach anyway.
  3363. function _proxy_jslib_proxify_js(s, top_level, with_level, in_new_statement, reverse) {
  3364. if ((s==void 0) || (s=='')) return s ;
  3365. if (with_level==void 0) with_level= 0 ;
  3366. if (in_new_statement==void 0) in_new_statement= 0 ;
  3367.  
  3368. // ... until _proxy_jslib_proxify_js_tokens_reverse() is complete
  3369. // if (reverse) return s ;
  3370.  
  3371. // hack for eval()-- return unchanged if it's not a string or String object
  3372. if (!((typeof s=='string') || (s instanceof String)))
  3373. return s ;
  3374.  
  3375. var jsin= _proxy_jslib_tokenize_js(s) ;
  3376.  
  3377. // jsm-- next routine really needs completion and more testing....
  3378. if (reverse) return _proxy_jslib_proxify_js_tokens_reverse(jsin, 0, jsin.length) ;
  3379.  
  3380. return _proxy_jslib_proxify_js_tokens(jsin, 0, jsin.length, top_level, with_level, in_new_statement, reverse) ;
  3381. }
  3382.  
  3383.  
  3384.  
  3385. function _proxy_jslib_proxify_js_tokens_reverse(jsin, start, end)
  3386. {
  3387. var RE= _proxy_jslib_RE ;
  3388.  
  3389. var i, i_jsin, out, element, token, match, p, op, estart, eend, tstart, tend ;
  3390.  
  3391. out= [] ;
  3392. out.push= _proxy_jslib_ORIGINAL_ARRAY_push ; // hack to use original ARRAY.push()
  3393.  
  3394. i_jsin= start ;
  3395.  
  3396. while (i_jsin<end) {
  3397. element= jsin[i_jsin++] ;
  3398. token= element.skip ? void 0 : element ;
  3399.  
  3400. if (token=='_proxy_jslib_handle') {
  3401. if (jsin[i_jsin+1]=='null') {
  3402. out.push(jsin[i_jsin+7]) ;
  3403. i_jsin+= 15 ;
  3404. } else {
  3405. estart= i_jsin+1 ;
  3406. i_jsin= eend= _proxy_jslib_get_next_js_expr(jsin, estart, end, 0) ;
  3407. out.push(_proxy_jslib_proxify_js_tokens_reverse(jsin, estart, eend)) ;
  3408. if (match= jsin[i_jsin+2].match(/^'(\w+)'$/)) {
  3409. out.push('.', match[1]) ;
  3410. i_jsin+= 13 ;
  3411. } else if (jsin[i_jsin+2]=='(') {
  3412. out.push('[') ;
  3413. estart= i_jsin+3 ;
  3414. eend= _proxy_jslib_get_next_js_expr(jsin, estart, end, 1) ;
  3415. out.push(_proxy_jslib_proxify_js_tokens_reverse(jsin, estart, eend)) ;
  3416. out.push(']') ;
  3417. if (jsin[eend]!= ')')
  3418. alert('error parsing _proxy_jslib_handle; next token is ['+jsin[eend]+']') ;
  3419. i_jsin= eend+11 ;
  3420. } else {
  3421. alert('error parsing _proxy_jslib_handle; next token is ['+jsin[i_jsin+2]+']') ;
  3422. break ;
  3423. }
  3424. }
  3425.  
  3426. } else if (token=='_proxy_jslib_assign') {
  3427. if (jsin[i_jsin+1]=="''") {
  3428. tstart= i_jsin+4 ;
  3429. tend= _proxy_jslib_get_next_js_expr(jsin, tstart, end, 0) ;
  3430. out.push(_proxy_jslib_proxify_js_tokens_reverse(jsin, tstart, tend)) ;
  3431. if (match= jsin[tend+2].match(/^'(\w+)'$/)) {
  3432. out.push('.', match[1]) ;
  3433. op= jsin[tend+5].match(/^'([^']*)'$/)[1] ;
  3434. out.push(op) ;
  3435. if (jsin[tend+8]=="''") {
  3436. i_jsin= tend+10 ;
  3437. } else if (jsin[tend+8]=='(') {
  3438. estart= tend+9 ;
  3439. eend= _proxy_jslib_get_next_js_expr(jsin, estart, end, 1) ;
  3440. out.push(_proxy_jslib_proxify_js_tokens_reverse(jsin, estart, eend)) ;
  3441. i_jsin= eend+2 ;
  3442. } else {
  3443. alert('error parsing _p_j_assign; next token is ['+jsin[tend+8]+']') ;
  3444. }
  3445. } else if (jsin[tend+2]=='(') {
  3446. out.push('[') ;
  3447. estart= tend+3 ;
  3448. eend= _proxy_jslib_get_next_js_expr(jsin, estart, end, 1) ;
  3449. out.push(_proxy_jslib_proxify_js_tokens_reverse(jsin, estart, eend)) ;
  3450. out.push(']') ;
  3451. op= jsin[eend+3].match(/^'([^']*)'$/)[1] ;
  3452. out.push(op) ;
  3453. if (jsin[eend+6]=="''") {
  3454. i_jsin= eend+8 ;
  3455. } else if (jsin[eend+6]=='(') {
  3456. estart= eend+7 ;
  3457. eend= _proxy_jslib_get_next_js_expr(jsin, estart, end, 1) ;
  3458. out.push(_proxy_jslib_proxify_js_tokens_reverse(jsin, estart, eend)) ;
  3459. i_jsin= eend+2 ;
  3460. } else {
  3461. alert('error parsing _p_j_assign; next token is ['+jsin[eend+6]+']') ;
  3462. }
  3463. } else {
  3464. alert('error parsing _p_j_assign; next token is ['+jsin[tend+2]+']') ;
  3465. }
  3466. } else if (match= jsin[i_jsin+1].match(/^'(\+\+|--|delete)'$/)) {
  3467. op= match[1] ;
  3468. out.push(op) ;
  3469. tstart= i_jsin+4 ;
  3470. tend= _proxy_jslib_get_next_js_expr(jsin, tstart, end, 0) ;
  3471. out.push(_proxy_jslib_proxify_js_tokens_reverse(jsin, tstart, tend)) ;
  3472. if (match= jsin[tend+2].match(/^'(\w+)'$/)) {
  3473. out.push('.', match[1]) ;
  3474. i_jsin= tend+10 ;
  3475. } else if (jsin[tend+2]=='(') {
  3476. out.push('[') ;
  3477. estart= tend+3 ;
  3478. eend= _proxy_jslib_get_next_js_expr(jsin, estart, end, 1) ;
  3479. out.push(_proxy_jslib_proxify_js_tokens_reverse(jsin, estart, eend)) ;
  3480. out.push(']') ;
  3481. i_jsin= _proxy_jslib_get_next_js_expr(jsin, eend+2, end, 1) + 1 ;
  3482. } else {
  3483. alert('error parsing _p_j_assign; next token is ['+jsin[tend+2]+']') ;
  3484. }
  3485. } else {
  3486. alert('error parsing _p_j_assign; next token is ['+jsin[i_jsin+1]+']') ;
  3487. }
  3488.  
  3489. } else if (token=='_proxy_jslib_assign_rval') {
  3490. out.pop() ; out.pop() ;
  3491. p= out.pop() ;
  3492. if (jsin[i_jsin+1]=="''") {
  3493. if (match= jsin[i_jsin+4].match(/^'(\w+)'$/)) {
  3494. if (p!=match[1])
  3495. alert('error parsing _proxy_jslib_assign_rval; p doesn\'t match') ;
  3496. out.push(p) ;
  3497. if (match= jsin[i_jsin+7].match(/^'(\+\+|--)'$/)) {
  3498. out.push(match[1]) ;
  3499. i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin+13, end, 1) + 1 ;
  3500. } else if (match= jsin[i_jsin+7].match(/^'([^']+)'$/)) {
  3501. out.push(match[1]) ;
  3502. if (jsin[i_jsin+10]=='(') {
  3503. estart= i_jsin+11 ;
  3504. eend= _proxy_jslib_get_next_js_expr(jsin, estart, end, 1) ;
  3505. out.push(_proxy_jslib_proxify_js_tokens_reverse(jsin, estart, eend)) ;
  3506. i_jsin= _proxy_jslib_get_next_js_expr(jsin, eend+2, end, 1) + 1 ;
  3507. } else {
  3508. alert('error parsing _proxy_jslib_assign_rval; next token is ['+jsin[i_jsin+10]+']') ;
  3509. }
  3510. } else {
  3511. alert('error parsing _proxy_jslib_assign_rval; next token is ['+jsin[i_jsin+7]+']') ;
  3512. }
  3513. } else {
  3514. alert('error parsing _proxy_jslib_assign_rval; missing prop') ;
  3515. }
  3516. } else if (match= jsin[i_jsin+1].match(/^'(\+\+|--|delete)'$/)) {
  3517. out.push(match[1]) ;
  3518. if (match= jsin[i_jsin+4].match(/^'(\w+)'$/)) {
  3519. out.push(match[1]) ;
  3520. i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin+13, end, 1) ;
  3521. } else {
  3522. alert('error parsing _proxy_jslib_assign_rval; missing prop') ;
  3523. }
  3524. } else {
  3525. alert('error parsing _proxy_jslib_assign_rval; bad prefix') ;
  3526. }
  3527.  
  3528. } else if (token=='_proxy_jslib_with_handle') {
  3529. out.push(jsin[i_jsin+7]) ;
  3530. jsin+= 15 ;
  3531.  
  3532. } else if (token=='_proxy_jslib_with_assign_rval') {
  3533. out.pop() ; out.pop() ;
  3534. p= out.pop() ;
  3535. match= jsin[i_jsin+7].match(/^'(\w+)'$/) ;
  3536. if (p!=match[1])
  3537. alert('error parsing _proxy_jslib_with_assign_rval; p doesn\'t match') ;
  3538. if (jsin[i_jsin+4]=="''") {
  3539. out.push(p) ;
  3540. if (match= jsin[i_jsin+10].match(/^'(\+\+|--)'$/)) {
  3541. out.push(match[1]) ;
  3542. i_jsin+= 18 ;
  3543. } else if (match= jsin[i_jsin+10].match(/^'([^']+)'$/)) {
  3544. out.push(match[1]) ;
  3545. estart= i_jsin+14 ;
  3546. eend= _proxy_jslib_get_next_js_expr(jsin, estart, end, 1) ;
  3547. out.push(_proxy_jslib_proxify_js_tokens_reverse(jsin, estart, eend)) ;
  3548. i_jsin= eend+5 ;
  3549. } else {
  3550. alert('error parsing _proxy_jslib_with_assign_rval; next token is ['+jsin[i_jsin+10]+']') ;
  3551. }
  3552. } else if (match= jsin[i_jsin+4].match(/^'(\+\+|--|delete)'$/)) {
  3553. out.push(match[1], p) ;
  3554. i_jsin+= 18 ;
  3555. } else {
  3556. alert('error parsing _proxy_jslib_with_assign_rval; prefix is ['+jsin[i_jsin+4]+']') ;
  3557. }
  3558.  
  3559. } else if (token=='_proxy_jslib_eval_ok') {
  3560. estart= i_jsin+3 ;
  3561. while ((jsin[estart]!='eval') && (estart<end)) estart++ ; // find 'eval' token, not perfect
  3562. estart+= 5 ;
  3563. eend= _proxy_jslib_get_next_js_expr(jsin, estart, end, 0) ;
  3564. out.push('eval(', _proxy_jslib_proxify_js_tokens_reverse(jsin, estart, eend), ')') ;
  3565. i_jsin= eend+18 ;
  3566.  
  3567. } else if (token=='_proxy_jslib_increments') {
  3568. if (jsin[i_jsin]==')') {
  3569. out.length-= 5 ;
  3570. i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin+6, end, 1) + 1 ;
  3571. } else {
  3572. i_jsin+= 5 ;
  3573. }
  3574.  
  3575. } else if (token=='_proxy_jslib_with_objs') {
  3576. if (jsin[i_jsin]=='=') {
  3577. out.pop(); out.pop(); out.pop() ;
  3578. i_jsin+= 6 ;
  3579. } else if (jsin[i_jsin]=='[') {
  3580. i_jsin+= 7 ;
  3581. } else if (jsin[i_jsin]=='.') {
  3582. i_jsin+= 6 ;
  3583. }
  3584.  
  3585. } else if (token=='_proxy_jslib_flush_write_buffers') {
  3586. i_jsin+= 3 ;
  3587.  
  3588. } else if (match= element.match(/^_proxy(\d+)_/)) {
  3589. out.push(element.replace(/^_proxy\d+/, '_proxy'+(match[1]>1 ? match[1]-1 : '') )) ;
  3590.  
  3591.  
  3592. } else {
  3593. out.push(element) ;
  3594. }
  3595. }
  3596.  
  3597. //_proxy_jslib_ORIGINAL_WINDOW_alert.call(window, 'in _proxy_jslib_proxify_js_tokens_reverse(), \nbefore:\n ['+jsin.slice(start, end).join('')+']\nafter:\n ['+out.join('')+']') ;
  3598.  
  3599. return out.join('') ;
  3600. }
  3601.  
  3602.  
  3603.  
  3604. // This takes an array range of tokens as input, and returns a string.
  3605. // Note that the jsin array never changes; rather, we manipulate pointers
  3606. // into it. This includes when it is called recursively.
  3607. function _proxy_jslib_proxify_js_tokens(jsin, start, end, top_level, with_level, in_new_statement, reverse)
  3608. {
  3609. var RE= _proxy_jslib_RE ;
  3610.  
  3611. var i_jsin, i_jsin_start, out, element, token, last_token, new_last_token, newline_since_last_token,
  3612. term_so_far= '', sub_expr, op, new_val, cur_val_str, inc_by,
  3613. in_braces= 0, in_func= false, expr, new_expr,
  3614. var_decl, varname, eq, value, skip1, skip2, funcname, with_obj, code,
  3615. match, m2, o_p, ostart, oend, pstart, pend, p, estart, eend,
  3616. skipped, i, i_next_token, i_lt, next_token, next_expr, next_expr_st, skipped, args, fn_body, t ;
  3617.  
  3618.  
  3619. out= [] ;
  3620. out.push= _proxy_jslib_ORIGINAL_ARRAY_push ; // hack to use original ARRAY.push()
  3621.  
  3622. if (top_level) _proxy_jslib_does_write= false ;
  3623.  
  3624. i_jsin= start ;
  3625.  
  3626. OUTER:
  3627. while (i_jsin<end) {
  3628. i_jsin_start= i_jsin;
  3629. element= jsin[i_jsin++] ;
  3630. token= element.skip ? void 0 : element ;
  3631.  
  3632. if (RE.LINETERMINATOR.test(element)) newline_since_last_token= true ;
  3633. new_last_token= '' ;
  3634.  
  3635. if (token=='{') {
  3636. in_braces++ ;
  3637. } else if (token=='}') {
  3638. if (--in_braces==0) in_func= false ;
  3639. }
  3640.  
  3641.  
  3642. // locate next token in jsin, and whether we skip a line terminator
  3643. i_next_token= i_lt= i_jsin ;
  3644. while (i_next_token<end && jsin[i_next_token].skip) i_next_token++ ;
  3645. next_token= (i_next_token<end) ? jsin[i_next_token] : void 0 ;
  3646. while (i_lt<i_next_token && !RE.LINETERMINATOR.test(jsin[i_lt])) i_lt++ ;
  3647. if (i_lt==i_next_token) i_lt= void 0 ;
  3648.  
  3649.  
  3650. // start of the main switch block
  3651.  
  3652. if (!token) {
  3653. if (term_so_far) term_so_far+= element ;
  3654. else out.push(element) ;
  3655.  
  3656.  
  3657. } else if (RE.N_S_RE.test(token)) {
  3658. out.push(term_so_far) ;
  3659. term_so_far= token ;
  3660.  
  3661.  
  3662. } else if (/^(\+\+|\-\-|delete)$/.test(token)) {
  3663. // peek ahead to see if we're in "-->"
  3664. if (token=='--' && (next_token=='>')) {
  3665. i_jsin= i_next_token+1 ;
  3666. out.push(term_so_far, '-->') ;
  3667. term_so_far= '' ;
  3668. } else if (term_so_far!='' && !newline_since_last_token) {
  3669. out.push(term_so_far, token) ;
  3670. term_so_far= '' ;
  3671. } else {
  3672. out.push(term_so_far) ;
  3673. term_so_far= '' ;
  3674.  
  3675. var start_parens= 0;
  3676. while (jsin[i_next_token]=='(') {
  3677. start_parens++;
  3678. i_jsin= i_next_token+1;
  3679. while (jsin[i_jsin].skip) i_jsin++;
  3680. i_next_token= i_jsin;
  3681. }
  3682.  
  3683. o_p= _proxy_jslib_get_next_js_term(jsin, i_jsin, end) ;
  3684. if (o_p==void 0) break ;
  3685. ostart= o_p[0] ;
  3686. oend= o_p[1] ;
  3687. pstart= o_p[2] ;
  3688. pend= o_p[3] ;
  3689.  
  3690. i_next_token= pend ;
  3691. while (jsin[i_next_token].skip) i_next_token++ ;
  3692. while (start_parens) {
  3693. if (jsin[i_next_token]!=')') break OUTER ;
  3694. new_last_token= ')' ;
  3695. start_parens-- ;
  3696. i_next_token++ ;
  3697. while (jsin[i_next_token].skip) i_next_token++ ;
  3698. }
  3699.  
  3700. if (oend>ostart) {
  3701. if (pstart>=pend) {
  3702. p= '' ;
  3703. out.concat(token, jsin.slice(i_jsin_start, i_next_token));
  3704. } else if (jsin[pstart]=='[') {
  3705. p= _proxy_jslib_proxify_js_tokens(jsin, pstart+1, pend-1, 0, with_level) ;
  3706. out.push(" _proxy_jslib_assign('" + token + "', ("
  3707. + _proxy_jslib_proxify_js_tokens(jsin, ostart, oend, 0, with_level) + "), ("
  3708. + p + "), '')" ) ;
  3709. } else {
  3710. out.push(" _proxy_jslib_assign('" + token + "', ("
  3711. + _proxy_jslib_proxify_js_tokens(jsin, ostart, oend, 0, with_level)
  3712. + "), '" + jsin[pstart] + "', '')" ) ; // should be single identifier
  3713. }
  3714. } else {
  3715. if (jsin[pstart]=='[') {
  3716. p= _proxy_jslib_proxify_js_tokens(jsin, pstart+1, pend-1, 0, with_level) ;
  3717. out.push(" _proxy_jslib_assign('" + token + "', ("
  3718. + _proxy_jslib_proxify_js_tokens(jsin, ostart, oend, 0, with_level) + "), ("
  3719. + p + "), '')" ) ;
  3720. } else {
  3721. p= jsin[pstart] ; // should be single identifier
  3722. if (token=='delete')
  3723. out.push('delete ' + p);
  3724. else if (p!='location')
  3725. out.push(token, p) ;
  3726. else
  3727. out.push("(" + p + "= _proxy_jslib_assign_rval('"
  3728. + token + "', '" + p + "', '', '', "
  3729. + "(typeof " + p + "=='undefined' ? void 0 : " + p + ")))") ;
  3730. }
  3731. }
  3732. i_jsin= i_next_token ;
  3733. }
  3734.  
  3735.  
  3736. } else if (token=='eval' && (next_token=='(')) {
  3737. estart= i_jsin= i_next_token+1 ;
  3738. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  3739. if (i_jsin==void 0 || i_jsin>=end || jsin[i_jsin++]!=')') break ;
  3740. term_so_far= term_so_far.match(RE.DOTSKIPEND)
  3741. ? '(_proxy_jslib_eval_ok ? ' + term_so_far + 'eval(_proxy_jslib_proxify_js(('
  3742. + _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level)
  3743. + '), 0, ' + with_level + ') ) : _proxy_jslib_throw_csp_error("bad eval") )'
  3744. : term_so_far + '(_proxy_jslib_eval_ok ? eval(_proxy_jslib_proxify_js(('
  3745. + _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level)
  3746. + '), 0, ' + with_level + ') ) : _proxy_jslib_throw_csp_error("bad eval") )' ;
  3747.  
  3748.  
  3749. // Testing a hash of booleans here doesn't seem to be any faster than
  3750. // using this long regex, unfortunately. For example:
  3751. // } else if (RE.SET_TRAPPED_PROPERTIES[token]) {
  3752. } else if (/^(open|write|writeln|load|eval|setInterval|setTimeout|toString|String|src|currentSrc|href|background|lowsrc|action|formAction|location|poster|URL|url|newURL|oldURL|referrer|baseURI|useMap|longDesc|cite|codeBase|profile|cssText|insertRule|setStringValue|setProperty|backgroundImage|content|cursor|listStyleImage|host|hostname|pathname|port|protocol|search|setNamedItem|innerHTML|outerHTML|outerText|body|parentNode|insertAdjacentHTML|setAttribute|setAttributeNode|getAttribute|nodeValue|value|cookie|domain|frames|parent|top|opener|execScript|execCommand|navigate|showModalDialog|showModelessDialog|addImport|LoadMovie|close|getElementById|getElementsByTagName|appendChild|replaceChild|insertBefore|removeChild|createElement|text|textContent|origin|postMessage|pushState|replaceState|localStorage|sessionStorage|querySelector|querySelectorAll|send|setRequestHeader|withCredentials)$/.test(token)) {
  3753. _proxy_jslib_does_write= _proxy_jslib_does_write || (token=='write') || (token=='writeln') || (token=='eval') ;
  3754. if ( newline_since_last_token
  3755. && /^(\)|\]|\+\+|\-\-)$|^([a-zA-Z\$\_\\\d'"]|\.\d|\/..)/.test(last_token)
  3756. && ! /^(case|delete|do|else|in|instanceof|new|typeof|void|function|var)$/.test(last_token) )
  3757. {
  3758. out.push(term_so_far) ;
  3759. term_so_far= '' ;
  3760. }
  3761. var has_dot= term_so_far.match(RE.DOTSKIPEND) ;
  3762. term_so_far= term_so_far.replace(RE.DOTSKIPEND, '') ;
  3763.  
  3764. var next_is_paren= (next_token=='(') ? 1 : 0 ;
  3765.  
  3766. if (/^[\{\,]/.test(last_token) && (next_token==':')) {
  3767. out.push(term_so_far, token) ;
  3768. for (i= i_jsin ; i<=i_next_token ; i++) out.push(jsin[i]) ;
  3769. i_jsin= i_next_token+1 ;
  3770.  
  3771. term_so_far= '' ;
  3772. new_last_token= ':' ;
  3773.  
  3774. } else if (token=='String' && !next_is_paren) {
  3775. if (has_dot) term_so_far+= '.' ;
  3776. term_so_far+= token;
  3777. div_ok= 1;
  3778.  
  3779. } else if ((i_lt==void 0) && (next_token=='++' || next_token=='--')) {
  3780. op= next_token ;
  3781. i_jsin= i_next_token+1 ;
  3782. if (term_so_far=='') {
  3783. out.push(' ', (with_level
  3784. ? (token+"= _proxy_jslib_with_assign_rval(_proxy_jslib_with_objs, '', '"+token+"', '"+op+"', '', "+token+")")
  3785. : (token+"= _proxy_jslib_assign_rval('', '"+token+"', '"+op+"', '', (typeof "+token+"=='undefined' ? void 0 : " + token+"))") )
  3786. ) ;
  3787. } else {
  3788. term_so_far= " _proxy_jslib_assign('', "+term_so_far+", '"+token+"', '"+op+"', '')" ;
  3789. }
  3790. new_last_token= ')' ;
  3791.  
  3792. } else if (next_token && next_token.match(RE.ASSIGNOP)) {
  3793. op= next_token ;
  3794. estart= i_jsin= i_next_token+1 ;
  3795. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 0) ;
  3796. if (i_jsin==void 0) break ;
  3797. new_val= _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level) ;
  3798. if (term_so_far=='') {
  3799. out.push(' ', (with_level
  3800. ? (token+"= _proxy_jslib_with_assign_rval(_proxy_jslib_with_objs, '', '"+token+"', '"+op+"', ("+new_val+"), "+token+")")
  3801. : (token+"= _proxy_jslib_assign_rval('', '"+token+"', '"+op+"', ("+new_val+"), (typeof "+token+"=='undefined' ? void 0 : " + token+"))") )
  3802. )
  3803. } else {
  3804. term_so_far= " _proxy_jslib_assign('', "+term_so_far+", '"+token+"', '"+op+"', ("+new_val+"))" ;
  3805. }
  3806. new_last_token= ')' ;
  3807.  
  3808. } else {
  3809. if (term_so_far=='') {
  3810. term_so_far= (with_level
  3811. ? (" _proxy_jslib_with_handle(_proxy_jslib_with_objs, '"+token+"', "+token+", "+next_is_paren+", "+in_new_statement+")")
  3812. : (" _proxy_jslib_handle(null, '"+token+"', "+token+", "+next_is_paren+", "+in_new_statement+")") ) ;
  3813. } else {
  3814. term_so_far= " _proxy_jslib_handle("+term_so_far+", '"+token+"', '', "+next_is_paren+", "+in_new_statement+")" ;
  3815. }
  3816. new_last_token= ')' ;
  3817. }
  3818.  
  3819.  
  3820. // Skip these for the JS version-- they require %IN_CUSTOM_INSERTION
  3821. // etc. and would be rare anyway. Revisit later if needed.
  3822. //} else if (/^(applets|embeds|forms|ids|layers|anchors|images|links)$/.test(token)) {
  3823.  
  3824.  
  3825. } else if (/^(if|while|for|switch)$/.test(token)) {
  3826. if (next_token!='(') break ;
  3827. out.push(term_so_far, token, '(') ;
  3828. term_so_far= '' ;
  3829. estart= i_jsin= ++i_next_token ;
  3830.  
  3831. if (token!='for') {
  3832. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  3833. if (i_jsin==void 0 || i_jsin>=end || jsin[i_jsin++]!=')') break ;
  3834. out.push(_proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level), ')') ;
  3835.  
  3836. // Must handle e.g. "for (a[b] in c)..." -- very messy.
  3837. } else {
  3838. while (jsin[i_next_token].skip) i_next_token++ ;
  3839. if (jsin[i_next_token].match(RE.IdentifierName)) {
  3840. while (jsin[++i_next_token].skip) ;
  3841. if (jsin[i_next_token]=='in') {
  3842. // normal for(a in b)
  3843. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  3844. if (i_jsin==void 0 || i_jsin>=end || jsin[i_jsin++]!=')') break ;
  3845. out.push(_proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level), ')') ;
  3846. } else {
  3847. // possible for(expr in b), or for(;;)
  3848. o_p= _proxy_jslib_get_next_js_term(jsin, i_jsin, end) ;
  3849. if (o_p!=void 0) {
  3850. i_next_token= o_p[3] ;
  3851. while (jsin[i_next_token].skip) i_next_token++ ;
  3852. }
  3853. if (o_p!=void 0 && jsin[i_next_token]=='in') {
  3854. // for(expr in b)
  3855. eend= _proxy_jslib_get_next_js_expr(jsin, ++i_next_token, end, 0) ;
  3856. if (jsin[eend]!=')') break ;
  3857. var rval= _proxy_jslib_proxify_js_tokens(jsin, i_next_token, eend, 0, with_level) ;
  3858. var temp_varname= '_proxy_jslib_temp' + _proxy_jslib_temp_counter++ ;
  3859. var p_param= jsin[o_p[2]]=='['
  3860. ? _proxy_jslib_proxify_js_tokens(jsin, o_p[2]+1, o_p[3]-1, 0, with_level)
  3861. : "'" + jsin[o_p[2]] + "'" ;
  3862. out.push('var ', temp_varname, ' in ', rval, ') {',
  3863. '_proxy_jslib_assign("", (',
  3864. _proxy_jslib_proxify_js_tokens(jsin, o_p[0], o_p[1], 0, with_level),
  3865. '), (', p_param, '), "=", ', temp_varname, ') ;') ;
  3866. i_jsin= eend+1 ; // past ')'
  3867. while (jsin[i_jsin].skip) i_jsin++ ;
  3868. if (jsin[i_jsin]!='{') {
  3869. var stmt_start= i_jsin ;
  3870. var stmt_end= _proxy_jslib_get_next_js_expr(jsin, stmt_start, end, 0) ;
  3871. while (jsin[stmt_end]==',')
  3872. stmt_end= _proxy_jslib_get_next_js_expr(jsin, stmt_end+1, end, 0) ;
  3873. out.push(_proxy_jslib_proxify_js_tokens(jsin, stmt_start, stmt_end, 0, with_level),
  3874. '; }') ;
  3875. i_jsin= stmt_end ;
  3876. } else
  3877. i_jsin++ ;
  3878. } else {
  3879. // for(;;)
  3880. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  3881. if (i_jsin==void 0 || i_jsin>=end || jsin[i_jsin++]!=')') break ;
  3882. out.push(_proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level), ')') ;
  3883. }
  3884. }
  3885. } else {
  3886. // another for(;;), not starting with identifier
  3887. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  3888. if (i_jsin==void 0 || i_jsin>=end || jsin[i_jsin++]!=')') break ;
  3889. out.push(_proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level), ')') ;
  3890. }
  3891. }
  3892.  
  3893.  
  3894. } else if (token=='catch') {
  3895. out.push(term_so_far, token) ;
  3896. term_so_far= '' ;
  3897. if (next_token!='(') break ;
  3898. estart= i_jsin= i_next_token+1 ;
  3899. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  3900. if (i_jsin==void 0 || i_jsin>=end || jsin[i_jsin++]!=')') break ;
  3901. out.push('(') ;
  3902. for (i= estart ; i<eend ; i++) out.push(jsin[i]) ;
  3903. out.push(')') ;
  3904.  
  3905.  
  3906. } else if (token=='function') {
  3907. out.push(term_so_far, token) ;
  3908. term_so_far= '' ;
  3909. if (next_token && next_token.match(RE.IdentifierName)) {
  3910. for (i= i_jsin ; i<i_next_token ; i++) out.push(jsin[i]) ;
  3911. funcname= next_token ;
  3912. i_jsin= i_next_token+1 ;
  3913. while (i_jsin<end-1
  3914. && jsin[i_jsin]=='.' && jsin[i_jsin+1].match(RE.IdentifierName)) {
  3915. funcname+= jsin[i_jsin] + jsin[i_jsin+1] ;
  3916. i_jsin+= 2 ;
  3917. }
  3918. } else {
  3919. funcname= '' ;
  3920. }
  3921. if (m2= funcname.match(/^_proxy(\d*)_/))
  3922. funcname= '_proxy' + (m2[1]-0+1) + funcname.replace(/^_proxy(\d*)/, '') ;
  3923. out.push(funcname) ;
  3924. i_next_token= i_jsin ;
  3925. while (i_next_token<end && jsin[i_next_token].skip) i_next_token++ ;
  3926. for (i= i_jsin+1 ; i<i_next_token ; i++) out.push(jsin[i]) ;
  3927. if (jsin[i_next_token]!='(') break ;
  3928. estart= i_jsin= i_next_token+1 ;
  3929. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  3930. if (i_jsin==void 0 || i_jsin>=end || jsin[i_jsin++]!=')') break ;
  3931. out.push('(') ;
  3932. for (i= estart ; i<eend ; i++) out.push(jsin[i]) ;
  3933. out.push(') {') ;
  3934. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  3935. if (i_jsin>=end || jsin[i_jsin++]!='{') break ;
  3936.  
  3937. in_braces++ ;
  3938. in_func= true ;
  3939.  
  3940.  
  3941. } else if (token=='with') {
  3942. out.push(term_so_far) ;
  3943. term_so_far= '' ;
  3944. skip1= '' ;
  3945. for (i= i_jsin ; i<i_next_token ; i++) skip1+= jsin[i] ;
  3946. if (next_token!='(') break ;
  3947. estart= i_jsin= i_next_token+1 ;
  3948. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  3949. with_obj= _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level) ;
  3950. if (i_jsin>=end || jsin[i_jsin++]!=')') break ;
  3951. skip2= '' ;
  3952. while (i_jsin<end && jsin[i_jsin].skip) skip2+= jsin[i_jsin++] ;
  3953. if (jsin[i_jsin]=='{') {
  3954. estart= ++i_jsin ;
  3955. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  3956. code= '{' + _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level+1) + '}' ;
  3957. if (i_jsin>=end || jsin[i_jsin++]!='}') break ;
  3958. } else {
  3959. estart= i_jsin ;
  3960. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 0) ;
  3961. code= _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level+1) ;
  3962. while (jsin[i_jsin]==',') {
  3963. estart= ++i_jsin ;
  3964. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 0) ;
  3965. code+= ',' + _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level+1) ;
  3966. }
  3967. }
  3968. out.push('{', with_level ? '' : 'var _proxy_jslib_with_objs= [] ;') ;
  3969. out.push('with', skip1, '(_proxy_jslib_with_objs[_proxy_jslib_with_objs.length]= (', with_obj, '))', skip2, code) ;
  3970. out.push('; _proxy_jslib_with_objs.length-- ;}') ;
  3971. new_last_token= ';' ;
  3972.  
  3973.  
  3974. } else if (token=='var' || token=='let') {
  3975. out.push(term_so_far, token) ;
  3976. term_so_far= '' ;
  3977. while (1) {
  3978. estart= i_jsin ;
  3979. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 0) ;
  3980. i= estart ;
  3981. while (i<eend && jsin[i].skip) out.push(jsin[i++]) ;
  3982. varname= (i<eend) ? jsin[i] : void 0 ;
  3983. if (!varname || !varname.match(RE.IdentifierName)) break OUTER ;
  3984. if (varname && (match= varname.match(/^_proxy(\d*)_/)))
  3985. varname= '_proxy' + (match[1]-0+1) + varname.replace(/^_proxy(\d*)/, '') ;
  3986. out.push(varname) ;
  3987. i++ ;
  3988. while (i<eend && jsin[i].skip) out.push(jsin[i++]) ;
  3989. eq= (i<eend) ? jsin[i] : void 0 ;
  3990. if (eq && !(eq=='=' || eq=='in')) break OUTER ;
  3991.  
  3992. if (eq) out.push(eq, _proxy_jslib_proxify_js_tokens(jsin, i+1, eend, 0, with_level)) ;
  3993. if (i_jsin>=end || jsin[i_jsin]!=',') break ;
  3994. i_jsin++ ;
  3995. out.push(',') ;
  3996. }
  3997.  
  3998.  
  3999. } else if (token=='new') {
  4000. out.push(term_so_far) ;
  4001. term_so_far= '' ;
  4002. var test_jsin ;
  4003.  
  4004. if (next_token=='function') {
  4005. term_so_far= 'new function' ;
  4006. i_jsin= i_next_token+1 ;
  4007. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4008. if (i_jsin>=end || jsin[i_jsin++]!='(') break ;
  4009. estart= i_jsin ;
  4010. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  4011. if (i_jsin>=end || jsin[i_jsin++]!=')') break ;
  4012. term_so_far+= '(' ;
  4013. for (i= estart ; i<eend ; i++) term_so_far+= jsin[i] ;
  4014. term_so_far+= ')' ;
  4015. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4016. if (i_jsin>=end || jsin[i_jsin++]!='{') break ;
  4017. estart= i_jsin ;
  4018. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  4019. if (i_jsin>=end || jsin[i_jsin++]!='}') break ;
  4020. fn_body= _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level, 0) ;
  4021. term_so_far+= '{'+fn_body+'}' ;
  4022. new_last_token= '}' ;
  4023.  
  4024. } else {
  4025. if (next_token=='(') {
  4026. estart= i_jsin= i_next_token+1 ;
  4027. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  4028. if (i_jsin>=end || jsin[i_jsin++]!=')') break ;
  4029. } else {
  4030. estart= i_jsin ;
  4031. eend= i_jsin= _proxy_jslib_get_next_js_constructor(jsin, i_jsin, end) ;
  4032. }
  4033. new_expr= _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level, 1) ;
  4034. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4035. test_jsin= i_jsin+1 ;
  4036. while (test_jsin<end && jsin[test_jsin].skip) test_jsin++ ;
  4037. if (jsin[i_jsin]=='(' && jsin[test_jsin]!=')') {
  4038. i_jsin++ ;
  4039. out.push('_proxy_jslib_new(('+new_expr+'), ') ;
  4040. new_last_token= ',' ;
  4041. } else {
  4042. if (jsin[i_jsin]=='(' && jsin[test_jsin]==')') i_jsin= test_jsin+1 ;
  4043. out.push('_proxy_jslib_new('+new_expr+')') ;
  4044. new_last_token= ')' ;
  4045. }
  4046. }
  4047.  
  4048.  
  4049. } else if ((token=='return') && !in_func && top_level) {
  4050. out.push(term_so_far) ;
  4051. term_so_far= '' ;
  4052. estart= i_jsin= i_next_token ;
  4053. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 0) ;
  4054. while (jsin[i_jsin]==',') {
  4055. estart= ++i_jsin ;
  4056. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 0) ;
  4057. }
  4058. new_expr= estart==eend ? 'void 0' : _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level) ;
  4059. out.push('return ((_proxy_jslib_ret= (', new_expr, ')), _proxy_jslib_flush_write_buffers(), _proxy_jslib_ret)') ;
  4060.  
  4061.  
  4062. } else if ((token=='break') || (token=='continue')) {
  4063. out.push(term_so_far, token) ;
  4064. term_so_far= '' ;
  4065. if (next_token.match(RE.IdentifierName)) {
  4066. for (i= i_jsin ; i<=i_next_token ; i++) out.push(jsin[i]) ;
  4067. i_jsin= i_next_token+1 ;
  4068. new_last_token= next_token ;
  4069. }
  4070.  
  4071.  
  4072. } else if (/^(abstract|boolean|byte|case|char|class|const|debugger|default|delete|do|else|enum|export|extends|final|finally|float|goto|implements|in|instanceof|int|interface|long|native|package|private|protected|return|short|static|synchronized|throw|throws|transient|try|typeof|void|volatile)$/.test(token)) {
  4073. out.push(term_so_far, token) ;
  4074. term_so_far= '' ;
  4075.  
  4076.  
  4077. } else if (token.match(RE.IDENTIFIER)) {
  4078. if (match= token.match(/^\_proxy(\d*)(\_.*)/))
  4079. // the "-0" is to typecast match[1] to a number
  4080. token= '_proxy'+(match[1]-0+1)+match[2] ;
  4081.  
  4082. if ( newline_since_last_token
  4083. && /^(\)|\]|\+\+|\-\-)$|^([a-zA-Z\$\_\\\d'"]|\.\d|\/..)/.test(last_token)
  4084. && ! /^(case|delete|do|else|in|instanceof|new|typeof|void|function|var)$/.test(last_token) )
  4085. {
  4086. out.push(term_so_far) ;
  4087. term_so_far= token ;
  4088. } else {
  4089. term_so_far+= token ;
  4090. }
  4091.  
  4092.  
  4093. } else if (token=='.') {
  4094. term_so_far+= '.' ;
  4095.  
  4096.  
  4097. } else if (token=='(') {
  4098. _proxy_jslib_does_write= true ;
  4099. estart= i_jsin ;
  4100. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  4101. if (i_jsin>=end || jsin[i_jsin++]!=')') break ;
  4102. term_so_far+= '(' + _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level) + ')' ;
  4103. new_last_token= ')' ;
  4104.  
  4105.  
  4106. } else if (token=='[') {
  4107. estart= i_jsin ;
  4108. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  4109. if (i_jsin>=end || jsin[i_jsin++]!=']') break ;
  4110. if (eend-estart<=1 && ! /\D/.test(jsin[estart])) {
  4111. term_so_far+= '['+(eend!=estart ?jsin[estart] :'')+']' ;
  4112. new_last_token= ']' ;
  4113.  
  4114.  
  4115. } else {
  4116. sub_expr= _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level) ;
  4117. if (term_so_far) {
  4118. new_last_token= ')' ;
  4119.  
  4120. // locate next token in jsin, and whether we skip a line terminator
  4121. i_next_token= i_lt= i_jsin ;
  4122. while (i_next_token<end && jsin[i_next_token].skip) i_next_token++ ;
  4123. next_token= (i_next_token<end) ? jsin[i_next_token] : void 0 ;
  4124. while (i_lt<i_next_token && !RE.LINETERMINATOR.test(jsin[i_lt])) i_lt++ ;
  4125. if (i_lt==i_next_token) i_lt= void 0 ;
  4126.  
  4127. var next_is_paren= (jsin[i_next_token]=='(') ? 1 : 0 ;
  4128.  
  4129. if ((i_lt==void 0) && (next_token=='++' || next_token=='--')) {
  4130. op= next_token ;
  4131. i_jsin= i_next_token+1 ;
  4132. term_so_far= " _proxy_jslib_assign('', "+term_so_far+", ("+sub_expr+"), '"+op+"', '')" ;
  4133. } else if (next_token && next_token.match(RE.ASSIGNOP)) {
  4134. op= next_token ;
  4135. estart= i_jsin= i_next_token+1 ;
  4136. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 0) ;
  4137. new_val= _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level) ;
  4138. term_so_far= " _proxy_jslib_assign('', "+term_so_far+", ("+sub_expr+"), '"+op+"', ("+new_val+"))" ;
  4139. } else {
  4140. term_so_far= " _proxy_jslib_handle("+term_so_far+", ("+sub_expr+"), '', "+next_is_paren+", "+in_new_statement+")" ;
  4141. }
  4142. } else {
  4143. term_so_far= '['+sub_expr+']' ;
  4144. new_last_token= ']' ;
  4145. }
  4146. }
  4147.  
  4148.  
  4149. // distinguishing between an object literal and a block is messy
  4150. } else if (token=='{' && term_so_far=='' && last_token!=')'
  4151. && ((last_token==void 0) || last_token.match(RE.PUNCDIVPUNC)
  4152. || last_token.match(/^(?:case|delete|in|instanceof|new|return|throw|typeof)$/))
  4153. && (!next_token.match(/^(?:break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|this|throw|try|typeof|var|void|while|with)/))
  4154. && (next_token.match(RE.IDENTIFIER) || next_token.match(RE.STRINGLITERAL) || next_token.match(RE.NUMERICLITERAL) || (next_token=='}') ) ) {
  4155. term_so_far= '{' ;
  4156. if (next_token!='}') {
  4157. i_jsin= i_next_token+1 ;
  4158. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4159. if (jsin[i_jsin]==':') {
  4160. term_so_far+= next_token + ':' ;
  4161. estart= i_jsin+1 ;
  4162. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, estart, end, 0) ;
  4163. term_so_far+= _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level) ;
  4164. while (jsin[i_jsin]==',') {
  4165. i_jsin++ ;
  4166. term_so_far+= ',' ;
  4167. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4168. if (jsin[i_jsin]=='}') break ;
  4169. if (!(jsin[i_jsin].match(RE.IDENTIFIER) || jsin[i_jsin].match(RE.STRINGLITERAL) || jsin[i_jsin].match(RE.NUMERICLITERAL)))
  4170. break OUTER ;
  4171. var prop_name= jsin[i_jsin++] ;
  4172. if (match= prop_name.match(/^\_proxy(\d*)(\_.*)/))
  4173. prop_name= '_proxy'+(match[1]-0+1)+match[2] ;
  4174. term_so_far+= prop_name ;
  4175. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4176. if (jsin[i_jsin++]!=':') break OUTER ;
  4177. term_so_far+= ':' ;
  4178. estart= i_jsin ;
  4179. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, estart, end, 0) ;
  4180. term_so_far+= _proxy_jslib_proxify_js_tokens(jsin, estart, eend, 0, with_level) ;
  4181. }
  4182. if (jsin[i_jsin++]!='}') break OUTER;
  4183. term_so_far+= new_last_token= '}' ;
  4184.  
  4185. } else {
  4186. out.push(term_so_far, next_token) ;
  4187. term_so_far= '' ;
  4188. }
  4189.  
  4190. } else {
  4191. i_jsin= i_next_token+1 ;
  4192. term_so_far+= new_last_token= '}' ;
  4193. }
  4194.  
  4195.  
  4196.  
  4197. } else if (RE.PUNCDIVPUNC.test(token)) {
  4198. out.push(term_so_far, token) ;
  4199. term_so_far= '' ;
  4200.  
  4201. } else {
  4202. // shouldn't get here
  4203. }
  4204.  
  4205. if (token) {
  4206. last_token= new_last_token ? new_last_token : token ;
  4207. newline_since_last_token= false ;
  4208. }
  4209.  
  4210. }
  4211.  
  4212. out.push(term_so_far) ;
  4213.  
  4214. if (top_level && _proxy_jslib_does_write) {
  4215. out.push(' ;\n_proxy_jslib_flush_write_buffers() ;') ;
  4216. }
  4217.  
  4218.  
  4219. return out.join('') ;
  4220.  
  4221.  
  4222.  
  4223. // This takes a token array segment as input, and returns the start and
  4224. // end index of the object and final property of the next JS term. The
  4225. // property includes "[]" if that's what it's surrounded with.
  4226. function _proxy_jslib_get_next_js_term(jsin, start, end) {
  4227. var oend, pstart, pend ;
  4228. var i_jsin= start ;
  4229.  
  4230. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4231. if (i_jsin>=end || ( !jsin[i_jsin].match(RE.IDENTIFIER)
  4232. && !jsin[i_jsin].match(/^[\[\{\(]$/) ) )
  4233. return void 0 ;
  4234. if (jsin[i_jsin]=='[') {
  4235. i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin+1, end, 1) ;
  4236. if (jsin[i_jsin]!=']') return void 0 ;
  4237. oend= pstart= pend= ++i_jsin ;
  4238. } else if (jsin[i_jsin]=='{') {
  4239. i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin+1, end, 1) ;
  4240. if (jsin[i_jsin]!='}') return void 0 ;
  4241. oend= pstart= pend= ++i_jsin ;
  4242. } else if (jsin[i_jsin]=='(') {
  4243. i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin+1, end, 1) ;
  4244. if (jsin[i_jsin]!=')') return void 0 ;
  4245. oend= pstart= pend= ++i_jsin ;
  4246. } else {
  4247. oend= pstart= i_jsin ;
  4248. pend= ++i_jsin ;
  4249. }
  4250.  
  4251. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4252. while (i_jsin<end && (jsin[i_jsin]=='.' || jsin[i_jsin]=='(' || jsin[i_jsin]=='[')) {
  4253.  
  4254. if (jsin[i_jsin]=='.') {
  4255. oend= i_jsin++ ;
  4256. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4257. if (i_jsin>=end || !jsin[i_jsin].match(RE.IDENTIFIER)) return void 0 ;
  4258. pstart= i_jsin++ ;
  4259. pend= i_jsin ;
  4260.  
  4261. } else if (jsin[i_jsin]=='[') {
  4262. oend= pstart= i_jsin ;
  4263. i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin+1, end, 1) ;
  4264. if (i_jsin==void 0 || i_jsin>=end || jsin[i_jsin++]!=']') return void 0 ;
  4265. pend= i_jsin ;
  4266.  
  4267. } else if (jsin[i_jsin]=='(') {
  4268. i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin+1, end, 1) ;
  4269. if (i_jsin==void 0 || i_jsin>=end || jsin[i_jsin++]!=')') return void 0 ;
  4270. oend= pstart= pend= i_jsin ;
  4271. }
  4272. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4273. }
  4274. return [start, oend, pstart, pend] ;
  4275. }
  4276.  
  4277.  
  4278.  
  4279. // Similar to _proxy_jslib_get_next_js_term(), but for "new" statements.
  4280. function _proxy_jslib_get_next_js_constructor(jsin, start, end) {
  4281. var c= [], t, skip= [], op, estart, eend ;
  4282. var i_jsin= start ;
  4283.  
  4284. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4285. if (i_jsin>=end || !jsin[i_jsin].match(RE.IDENTIFIER)) return void 0 ;
  4286. i_jsin++ ;
  4287.  
  4288. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4289. while (i_jsin<end && (jsin[i_jsin]=='.' || jsin[i_jsin]=='[')) {
  4290. if (jsin[i_jsin]=='.') {
  4291. i_jsin++ ;
  4292. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4293. if (i_jsin>=end || !jsin[i_jsin].match(RE.IDENTIFIER)) return void 0 ;
  4294. i_jsin++ ;
  4295. } else if (jsin[i_jsin]=='[') {
  4296. estart= ++i_jsin ;
  4297. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, end, 1) ;
  4298. if (i_jsin==void 0 || i_jsin>=end || jsin[i_jsin++]!=']') return void 0 ;
  4299. }
  4300. while (i_jsin<end && jsin[i_jsin].skip) i_jsin++ ;
  4301. }
  4302. return i_jsin ;
  4303. }
  4304.  
  4305. }
  4306.  
  4307.  
  4308. // This takes a token array segment as input, and returns an index
  4309. // to the token following the end of the next expression in the input.
  4310. // We can't nest this because it's called from outside _proxy_jslib_proxify_js() .
  4311. function _proxy_jslib_get_next_js_expr(jsin, start, end, allow_multiple, is_new) {
  4312. var p= [], element, last_token, i, expr_block_state ;
  4313.  
  4314. var i_jsin= start ;
  4315. while (i_jsin<end) {
  4316. element= jsin[i_jsin] ;
  4317.  
  4318. if (!allow_multiple && p.length==0 && element=='function') expr_block_state= 1 ;
  4319.  
  4320. switch(element) {
  4321.  
  4322. case ';':
  4323. case ',':
  4324. if (!allow_multiple && p.length==0) return i_jsin ;
  4325. break ;
  4326.  
  4327. case '\x0a':
  4328. case '\x0d':
  4329. if (!allow_multiple && p.length==0) {
  4330. i= i_jsin+1 ;
  4331. while (i<end && jsin[i].skip) i++ ;
  4332. if ( /^(\)|\]|\+\+|\-\-)$|^([a-zA-Z\$\_\\\d'"]|\.\d|\/..)/.test(last_token)
  4333. && ! /^(case|delete|do|else|in|instanceof|new|typeof|void|function|var)$/.test(last_token)
  4334. && _proxy_jslib_RE.IDENTIFIER.test(jsin[i]) )
  4335. {
  4336. return i_jsin ;
  4337. }
  4338. if (expr_block_state==3
  4339. && (jsin[i]=='{'
  4340. || !(jsin[i].match(_proxy_jslib_RE.PUNCDIVPUNC) || jsin[i]=='instanceof') ) )
  4341. {
  4342. return i_jsin ;
  4343. }
  4344. }
  4345. break ;
  4346.  
  4347. case '{':
  4348. i= i_jsin+1 ;
  4349. while (i<end && jsin[i].skip) i++ ;
  4350. if (!allow_multiple && p.length==0
  4351. && (expr_block_state==1
  4352. || jsin[i].match(_proxy_jslib_RE.IDENTIFIER)
  4353. || jsin[i].match(_proxy_jslib_RE.STRINGLITERAL)
  4354. || jsin[i].match(_proxy_jslib_RE.NUMERICLITERAL)
  4355. || jsin[i]=='}' ) )
  4356. {
  4357. expr_block_state= 2 ;
  4358. }
  4359. case '(':
  4360. case '[':
  4361. case '?':
  4362. if (is_new && (p.length==0) && element=='(') return i_jsin ;
  4363. p.push(element) ;
  4364. break ;
  4365.  
  4366. case ')':
  4367. case ']':
  4368. case '}':
  4369. case ':':
  4370. if (p.length==0) return i_jsin ;
  4371. if (p.length>0 && !(element==':' && p[p.length-1]!='?')) p.length-- ;
  4372. //if (element=='}' && p.length==0 && !allow_multiple) return i_jsin+1 ;
  4373. if (!allow_multiple && p.length==0 && element=='}' && expr_block_state==2)
  4374. expr_block_state= 3 ;
  4375. break ;
  4376. }
  4377.  
  4378. if (!element.skip) {
  4379. last_token= element ;
  4380. }
  4381.  
  4382. i_jsin++ ;
  4383. }
  4384.  
  4385. return p.length==0 ? i_jsin : void 0 ;
  4386. }
  4387.  
  4388.  
  4389.  
  4390. // This takes a string as input, and returns two strings as output.
  4391. function _proxy_jslib_separate_last_js_statement(s) {
  4392. var rest, last, jsin, i, i_jsin, estart, eend, rest_end= 0 ;
  4393. var RE= _proxy_jslib_RE ;
  4394.  
  4395. jsin= _proxy_jslib_tokenize_js(s) ;
  4396.  
  4397. estart= i_jsin= 0 ;
  4398. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, jsin.length, 0) ;
  4399. while (eend>estart || eend<jsin.length) {
  4400. while (i_jsin<jsin.length && jsin[i_jsin].skip) i_jsin++ ;
  4401.  
  4402. // peek ahead to see if we got the last statement in jsin
  4403. i= i_jsin ;
  4404. while (i<jsin.length && (jsin[i]==';' || jsin[i].skip)) i++ ;
  4405. if (i==jsin.length) break ;
  4406.  
  4407. if ((jsin[i_jsin]).match(RE.STATEMENTTERMINATOR)) {
  4408. rest_end= ++i_jsin ;
  4409. } else {
  4410. if (jsin[i_jsin]==',') i_jsin++ ;
  4411. }
  4412.  
  4413. estart= i_jsin ;
  4414. eend= i_jsin= _proxy_jslib_get_next_js_expr(jsin, i_jsin, jsin.length, 0) ;
  4415. }
  4416.  
  4417. rest= jsin.slice(0, rest_end).join('') ;
  4418. last= jsin.slice(rest_end, jsin.length).join('') ;
  4419. return [rest, last] ;
  4420. }
  4421.  
  4422.  
  4423.  
  4424. // This takes a string as input, and returns a token array as output.
  4425. // If not for the "/" problem and the lack of \G in JavaScript, this whole
  4426. // thing could be done in one blazing statement, if the regex below was
  4427. // global and started with "\G":
  4428. // out= s.match(_proxy_jslib_RE.InputElementG) ;
  4429. function _proxy_jslib_tokenize_js(s) {
  4430. var out= [], match, element, token, div_ok, last_lastIndex= 0, conditional_state, conditional_stack_size, p_count ;
  4431. var RE_InputElementDivG= _proxy_jslib_RE.InputElementDivG ;
  4432. var RE_InputElementRegExpG= _proxy_jslib_RE.InputElementRegExpG ;
  4433.  
  4434. while (1) {
  4435. if (div_ok) {
  4436. if (!(match= RE_InputElementDivG.exec(s))) break ;
  4437. if (match.index!= last_lastIndex) break ;
  4438. last_lastIndex= RE_InputElementRegExpG.lastIndex= RE_InputElementDivG.lastIndex ;
  4439. } else {
  4440. if (!(match= RE_InputElementRegExpG.exec(s))) break ;
  4441. if (match.index!= last_lastIndex) break ;
  4442. last_lastIndex= RE_InputElementDivG.lastIndex= RE_InputElementRegExpG.lastIndex ;
  4443. }
  4444. element= match[0] ;
  4445. token= match[1] ;
  4446.  
  4447. // if it's not a token, flag it as skippable
  4448. if (!token) {
  4449. element= new String(element) ;
  4450. element.skip= true ;
  4451.  
  4452.  
  4453. // pain setting div_ok to false after "if ()", etc.
  4454. // without that requirement, half of this routine would go away.
  4455. } else if ((token=='if') || (token=='while') || (token=='for') || (token=='switch')) {
  4456. conditional_state= 1 ;
  4457. conditional_stack_size= p_count ;
  4458.  
  4459. } else if (token=='(') {
  4460. p_count++ ;
  4461. if (conditional_state==1) conditional_state= 2 ;
  4462.  
  4463. } else if (token==')') {
  4464. p_count-- ;
  4465. if ((conditional_state==2) && (p_count==conditional_stack_size))
  4466. conditional_state= 3 ;
  4467. }
  4468.  
  4469.  
  4470. out.push(element) ;
  4471.  
  4472. if (token) {
  4473. if (conditional_state==3) {
  4474. div_ok= 0 ;
  4475. conditional_state= 0 ;
  4476. } else {
  4477. div_ok= /^(\)|\]|\+\+|\-\-)$|^([a-zA-Z\$\_\\\d'"]|\.\d|\/..)/.test(token)
  4478. && !/^(case|delete|do|else|in|instanceof|new|return|throw|typeof|void)$/.test(token) ;
  4479. }
  4480. }
  4481. }
  4482.  
  4483. RE_InputElementDivG.lastIndex= RE_InputElementRegExpG.lastIndex= 0 ;
  4484. return out ;
  4485. }
  4486.  
  4487.  
  4488.  
  4489. function _proxy_jslib_set_RE() {
  4490. if (!_proxy_jslib_RE) { // saves time for multiple calls
  4491. var RE= {} ;
  4492.  
  4493. // count embedded parentheses carefully when using all these in matches!
  4494. RE.WhiteSpace= '[\\x09\\x0b\\x0c \\xa0]' ;
  4495. RE.LineTerminator= '[\\x0a\\x0d]' ;
  4496.  
  4497. // messy without non-greedy matching
  4498. //RE.Comment= '\\/\\*\\/*([^\\*]\\/|[^\\*\\/]*|\\**[^\\/])*\\*\\/|\\/\\/[^\\x0a\\x0d]*|\\<\\!\\-\\-[^\\x0a\\x0d]*' ;
  4499. RE.Comment= '\\/\\*[\\s\\S]*?\\*\\/|\\/\\/[^\\x0a\\x0d]*|\\<\\!\\-\\-[^\\x0a\\x0d]*' ;
  4500.  
  4501. RE.IdentifierStart= '[a-zA-Z\\$\\_]|\\\\u[\\da-fA-F]{4}' ;
  4502. RE.IdentifierPart= RE.IdentifierStart+'|\\d' ;
  4503. RE.IdentifierName= '(?:'+RE.IdentifierStart+')(?:'+RE.IdentifierPart+')*' ;
  4504.  
  4505. RE.Punctuator= '\\>\\>\\>\\=?|\\=\\=\\=|\\!\\=\\=|\\<\\<\\=|\\>\\>\\=|[\\<\\>\\=\\!\\+\\*\\%\\&\\|\\^\\-]\\=|\\+\\+|\\-\\-|\\<\\<|\\>\\>|\\&\\&|\\|\\||[\\{\\}\\(\\)\\[\\]\\.\\;\\,\\<\\>\\+\\*\\%\\&\\|\\^\\!\\~\\?\\:\\=\\-]' ;
  4506. RE.DivPunctuator= '\\/\\=?' ;
  4507.  
  4508. RE.NumericLiteral= '0[xX][\\da-fA-F]+|(?:0|[1-9]\\d*)(?:\\.\\d*)?(?:[eE][\\+\\-]?\\d+)?|\\.\\d+(?:[eE][\\+\\-]?\\d+)?' ;
  4509. RE.EscapeSequence= 'x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|0|[0-3]?[0-7]\\D|[4-7][0-7]|[0-3][0-7][0-7]|[^\\dxu]' ;
  4510. RE.StringLiteral= '"(?:[^\\"\\\\\\x0a\\x0d]|\\\\(?:'+RE.EscapeSequence+'))*"|'
  4511. + "'(?:[^\\'\\\\\\x0a\\x0d]|\\\\(?:"+RE.EscapeSequence+"))*'" ;
  4512. RE.RegularExpressionLiteral= '\\/(?:[^\\x0a\\x0d\\*\\\\\\/\\[]|\\[(?:[^\\\\\\]\\x0a\\x0d]|\\\\[^\\x0a\\x0d])*\\]|\\\\[^\\x0a\\x0d])(?:[^\\x0a\\x0d\\\\\\/\\[]|\\[(?:[^\\\\\\]\\x0a\\x0d]|\\\\[^\\x0a\\x0d])*\\]|\\\\[^\\x0a\\x0d])*\\/(?:'+RE.IdentifierPart+')*' ;
  4513.  
  4514. RE.Token= RE.IdentifierName+'|'+RE.NumericLiteral+'|'+RE.Punctuator+'|'+RE.StringLiteral ;
  4515.  
  4516. RE.InputElementDivG= RE.WhiteSpace+'+|'+RE.LineTerminator+'|'+RE.Comment+
  4517. '|('+RE.Token+'|'+RE.DivPunctuator+'|'+RE.RegularExpressionLiteral+')' ;
  4518. RE.InputElementRegExpG= RE.WhiteSpace+'+|'+RE.LineTerminator+'|'+RE.Comment+
  4519. '|('+RE.Token+'|'+RE.RegularExpressionLiteral+'|'+RE.DivPunctuator+')' ;
  4520.  
  4521. RE.SKIP= RE.WhiteSpace+'+|'+RE.LineTerminator+'|'+RE.Comment ;
  4522. RE.SKIP_NO_LT= RE.WhiteSpace+'+|'+RE.Comment ;
  4523.  
  4524. // make RegExp objects out of the ones we'll use
  4525. RE.InputElementDivG= new RegExp(RE.InputElementDivG, 'g') ;
  4526. RE.InputElementRegExpG= new RegExp(RE.InputElementRegExpG, 'g') ;
  4527.  
  4528. RE.LINETERMINATOR= new RegExp('^'+RE.LineTerminator+'$') ;
  4529. RE.N_S_RE= new RegExp('^(?:'+RE.NumericLiteral+'|'+RE.StringLiteral+'|'+RE.RegularExpressionLiteral+')$') ;
  4530. RE.DOTSKIPEND= new RegExp('\\.('+RE.WhiteSpace+'+|'+RE.LineTerminator+')*$') ;
  4531. RE.ASSIGNOP= new RegExp('^(\\>\\>\\>\\=|\\<\\<\\=|\\>\\>\\=|[\\+\\*\\/\\%\\&\\|\\^\\-]?\\=)$') ;
  4532. RE.NEXTISINCDEC= new RegExp('^('+RE.SKIP_NO_LT+')*(\\+\\+|\\-\\-)') ;
  4533. RE.SKIPTOPAREN= new RegExp('^(('+RE.SKIP+')*\\()') ;
  4534. RE.SKIPTOCOLON= new RegExp('^(('+RE.SKIP+')*\\:)') ;
  4535. RE.SKIPTOCOMMASKIP= new RegExp('^(('+RE.SKIP+')*\\,('+RE.SKIP+')*)') ;
  4536. RE.PUNCDIVPUNC= new RegExp('^('+RE.Punctuator+'|'+RE.DivPunctuator+')$') ;
  4537. RE.IDENTIFIER= new RegExp('^'+RE.IdentifierName+'$') ;
  4538. RE.STRINGLITERAL= new RegExp('^'+RE.StringLiteral+'$') ;
  4539. RE.NUMERICLITERAL= new RegExp('^(?:'+RE.NumericLiteral+')$') ;
  4540. RE.SKIPTOOFRAG= new RegExp('^('+RE.SKIP+')*([\\.\\[\\(])') ;
  4541. RE.STATEMENTTERMINATOR= new RegExp('^(;|'+RE.LineTerminator+')') ;
  4542.  
  4543.  
  4544. _proxy_jslib_RE= RE ;
  4545. }
  4546. }
  4547.  
  4548.  
  4549.  
  4550. //---- utilities -------------------------------------------------------
  4551.  
  4552.  
  4553.  
  4554. // A replacement for instanceof, since instanceof doesn't always work in all browsers.
  4555. // Use instanceof when possible; otherwise, take a heuristic guess at the type
  4556. // based on existing properties of the object.
  4557. // Properties are carefully selected to test correctly in both Mozilla and MSIE;
  4558. // objects and properties vary slightly by browser.
  4559. // Unfortunately, Mozilla can't use instanceof with Link, Layer, or Form objects,
  4560. // so the catch block will usually be called for that reason when using Mozilla.
  4561. // Note that Mozilla has a bug such that it dies when HTMLAreaElement.pathname
  4562. // is accessed. Thus, we avoid checking for the pathname property.
  4563. function _proxy_jslib_instanceof(o, classname) {
  4564. if ((o==null) || ((typeof(o)!='object') && (typeof(o)!='function')))
  4565. return false ;
  4566. try {
  4567. switch(classname) {
  4568. case 'Document':
  4569. return ("elementFromPoint" in o) && ("createElement" in o) && ("getElementById" in o) ;
  4570. case 'DocumentFragment':
  4571. return ("querySelector" in o) && ("querySelectorAll") && ("childNodes" in o) ;
  4572. case 'HTMLElement':
  4573. return ("insertAdjacentHTML" in o) && ("outerHTML" in o) ;
  4574. case 'Element':
  4575. return ("childElementCount" in o) && ("firstElementChild" in o) && ("nextElementSibling" in o) ;
  4576. case 'Node':
  4577. return ("nodeName" in o) && ("nodeType" in o) && ("nodeValue" in o) ;
  4578. case 'MessageEvent':
  4579. return ("stopImmediatePropagation" in o) && ("origin" in o) && ("ports" in o) ;
  4580. case 'Location':
  4581. return ("reload" in o) && ("protocol" in o) && ("search" in o) ;
  4582. case 'Link':
  4583. return ("protocol" in o) && ("target" in o) && ("blur" in o) ;
  4584. case 'Window':
  4585. return ("navigator" in o) && ("clearInterval" in o) && ("moveBy" in o) && (o.self===o.window) ;
  4586. case 'CSS2Properties':
  4587. return ("azimuth" in o) && ("backgroundAttachment" in o) && ("pageBreakInside" in o) ;
  4588. case 'CSSStyleDeclaration':
  4589. return (("getPropertyCSSValue" in o) || ("getPropertyValue" in o)) // MSIE uses getPropertyValue :P
  4590. && ("getPropertyPriority" in o) && ("removeProperty" in o) ;
  4591. case 'CSSStyleSheet':
  4592. return ('cssRules' in o) && ('ownerRule' in o) && ('deleteRule' in o) ;
  4593. case 'Layer':
  4594. return ("background" in o) && ("parentLayer" in o) && ("moveAbove" in o) ;
  4595. case 'History':
  4596. return ("pushState" in o) && ("replaceState" in o) && ("forward" in o) ;
  4597. case 'AnonXMLHttpRequest':
  4598. return ("withCredentials" in o) && ("getAllResponseHeaders" in o) ; // may need to improve
  4599.  
  4600. default:
  4601. if (!eval(classname)) return false ;
  4602. return eval('o instanceof ' + classname) ;
  4603. }
  4604. } catch(e) {
  4605.  
  4606. // These are all the classes that have trouble with instanceof for some reason.
  4607. switch(classname) {
  4608. case 'Form':
  4609. return ("action" in o) && ("encoding" in o) && ("submit" in o) ;
  4610. case 'CSSPrimitiveValue':
  4611. return ("primitiveType" in o) && ("getRectValue" in o) && ("getCounterValue" in o) ;
  4612. case 'FlashPlayer':
  4613. return ("GotoFrame" in o) && ("LoadMovie" in o) && ("SetZoomRect" in o) ;
  4614. case 'NamedNodeMap':
  4615. return ("getNamedItem" in o) && ("removeNamedItem" in o) && ("setNamedItem" in o) ;
  4616. case 'Range':
  4617. return ("cloneRange" in o) && ("compareBoundaryPoints" in o) && ("surroundContents" in o) ;
  4618. case 'Attr':
  4619. return ("ownerElement" in o) && ("specified" in o) ;
  4620. case 'EventSource':
  4621. // EventSource only has two properties, and they are also in WebSocket. So
  4622. // test those two, and verify o is not a WebSocket.
  4623. return ("readyState" in o) && ("url" in o) && !("bufferedAmount" in o) ;
  4624. case 'HashChangeEvent':
  4625. return ("oldURL" in o) && ("newURL" in o) ;
  4626. case 'MediaElement':
  4627. return ("autoplay" in o) && ("defaultPlaybackRate" in o) && ("initialTime" in o) ;
  4628. default:
  4629. alert('error in _proxy_jslib_instanceof(): classname=[' + classname + ']; error=[' + e + ']') ;
  4630. }
  4631. }
  4632. }
  4633.  
  4634.  
  4635.  
  4636. function _proxy_jslib_same_origin(u1, u2) {
  4637. var pu1= _proxy_jslib_parse_url(_proxy_jslib_absolute_url(u1)) ;
  4638. var pu2= _proxy_jslib_parse_url(_proxy_jslib_absolute_url(u2)) ;
  4639. pu1[5]= pu1[5] || (pu1[1]=='http:' ? 80 : pu1[1]=='https:' ? 443 : '') ;
  4640. pu2[5]= pu2[5] || (pu2[1]=='http:' ? 80 : pu2[1]=='https:' ? 443 : '') ;
  4641. return pu1[1]==pu2[1] && pu1[4]==pu2[4] && pu1[5]==pu2[5] ;
  4642. }
  4643.  
  4644.  
  4645. // using JS (not RFC) terminology, this returns:
  4646. // full_match, protocol (with colon), authentication, host, hostname, port, pathname, search, hash
  4647. // for IPv6, host includes "[]", while hostname has them removed
  4648. function _proxy_jslib_parse_url(in_URL) {
  4649. var u ;
  4650.  
  4651. // Some sites use non-String objects for URLs.
  4652. in_URL= in_URL.toString() ;
  4653.  
  4654. if (u= in_URL.match(/^(javascript\:|livescript\:)([\s\S]*)$/i))
  4655. return [ in_URL, u[1].toLowerCase(), u[2] ] ;
  4656. if (in_URL.match(/^\s*\#/))
  4657. return [ in_URL, '', '', '' ,'', '', '', '', in_URL ] ;
  4658.  
  4659. u= in_URL.match(/^([\w\+\.\-]+\:)?\/\/([^\/\?\#\@]*\@)?((\[[^\]]*\]|[^\:\/\?\#]*)(\:[^\/\?\#]*)?)([^\?\#]*)([^#]*)(.*)$/) ;
  4660. if (u==null) return ; // if pattern doesn't match
  4661. for (var i= 0 ; i<u.length ; i++) if (u[i]==void 0) u[i]= '' ;
  4662. u[1]= u[1].toLowerCase() ;
  4663. u[2]= u[2].replace(/\@$/, '') ;
  4664. u[3]= u[3].toLowerCase() ;
  4665. u[3]= u[3].replace(/\.+(:|$)/, '$1') ; // close potential exploit
  4666. u[4]= u[4].toLowerCase().replace(/^\[|\]$/g, '') ; // handle IPv6
  4667. u[4]= u[4].replace(/\.+$/, '') ; // close potential exploit
  4668. u[5]= u[5].replace(/^\:/, '') ;
  4669. return u ;
  4670. }
  4671.  
  4672.  
  4673. // returns url_start (NOT including packed flags), language, packed flags, and decoded target URL.
  4674. // if in_URL is not a proxified URL, return undefined (and is legitimately used this way).
  4675. // jsm-- should clear up "return void 0" from "return [void 0, void 0, void 0, void 0]",
  4676. // as this is called from elsewhere
  4677. function _proxy_jslib_parse_full_url(in_URL) {
  4678. if (typeof(in_URL)=='number') in_URL= in_URL.toString() ;
  4679. if (in_URL==void 0) return [void 0, void 0, void 0, void 0] ;
  4680. if (in_URL=='about:blank') return ['', '', '', 'about:blank'] ;
  4681. if (in_URL.match(/^(javascript|livescript|blob)\:/i)) return ['', '', '', in_URL] ;
  4682. if (in_URL.match(/^\s*\#/)) return ['', '', '', in_URL] ;
  4683. if (in_URL=='') return ['', '', '', ''] ;
  4684.  
  4685. var cmp, path_cmp ;
  4686.  
  4687. if (_proxy_jslib_PROXY_GROUP.length) {
  4688. for (var i in _proxy_jslib_PROXY_GROUP) {
  4689. if (in_URL.substring(0,_proxy_jslib_PROXY_GROUP[i].length)==_proxy_jslib_PROXY_GROUP[i]) {
  4690. path_cmp= in_URL.substring(_proxy_jslib_PROXY_GROUP[i].length).match(/\/([^\/\?]*)\/?([^\/\?]*)\/?([^\?]*)(\??.*)/) ;
  4691. // if (path_cmp==null) alert("CGIProxy Error: Can't parse URL <"+in_URL+"> with PROXY_GROUP; not setting all variables correctly.") ;
  4692. if (path_cmp==null) return void 0 ;
  4693. return [_proxy_jslib_PROXY_GROUP[i],
  4694. path_cmp[1],
  4695. path_cmp[2],
  4696. _proxy_jslib_wrap_proxy_decode(path_cmp[3])+path_cmp[4]] ;
  4697. }
  4698. }
  4699. return void 0 ;
  4700. }
  4701.  
  4702. var m1, m2, data_type, data_clauses, data_content, data_charset, data_base64 ;
  4703. if (m1= in_URL.match(/^data:([\w\.\+\$\-]+\/[\w\.\+\$\-]+)?;?([^\,]*)\,?(.*)/i)) {
  4704. data_type= m1[1].toLowerCase() ;
  4705. if (data_type=='text/html' || data_type=='text/css' || data_type.match(/script/i)) {
  4706. data_clauses= m1[2].split(/;/) ;
  4707. data_content= m1[3] ;
  4708. for (var i= 0 ; i<data_clauses.length ; i++) {
  4709. if (m2= data_clauses[i].match(/^charset=(\S+)/i)) {
  4710. data_charset= m2[1] ;
  4711. } else if (data_clauses[i].toLowerCase()=='base64') {
  4712. data_base64= 1 ;
  4713. }
  4714. }
  4715. data_content= data_base64
  4716. ? atob(data_content)
  4717. : data_content.replace(/%([\da-fA-F]{2})/g,
  4718. function (s,p1) { return String.fromCharCode(eval('0x'+p1)) } ) ; // probably slow
  4719. data_content= (data_type=='text/html') ? _proxy_jslib_proxify_html(data_content, void 0, void 0, 1)[0]
  4720. : _proxy_jslib_proxify_block(data_content, data_type, 1, 1) ;
  4721. data_content= btoa(data_content) ;
  4722. return ['', '', '', data_charset ? 'data:' + data_type + ';charset=' + data_charset + ';base64,' + data_content
  4723. : 'data:' + data_type + ';base64,' + data_content ] ;
  4724. } else {
  4725. return ['', '', '', in_URL] ;
  4726. }
  4727. }
  4728.  
  4729. // this could be simplified....
  4730. cmp= in_URL.match(/^([\w\+\.\-]+)\:\/\/([^\/\?]*)([^\?]*)(\??.*)$/) ;
  4731. if (cmp==null) return void 0 ;
  4732.  
  4733. // hack to canonicalize "%7e" to "~"; should do other encoded chars too
  4734. // as long as replacing doesn't change semantics
  4735. cmp[3]=cmp[3].replace(/\%7e/gi, '~') ;
  4736.  
  4737. path_cmp= cmp[3].match(_proxy_jslib_RE_FULL_PATH) ;
  4738. // if (cmp==null || path_cmp==null) alert("CGIProxy Error: Can't parse URL <"+in_URL+">; not setting all variables correctly.") ;
  4739. if (cmp==null || path_cmp==null) return void 0 ;
  4740.  
  4741. return [cmp[1]+"://"+cmp[2]+path_cmp[1],
  4742. path_cmp[2],
  4743. path_cmp[3],
  4744. _proxy_jslib_wrap_proxy_decode(path_cmp[4])+cmp[4]] ;
  4745. }
  4746.  
  4747.  
  4748. function _proxy_jslib_pack_flags(flags) {
  4749. var total= 0 ;
  4750. for (var i= 0 ; i<6 ; i++) { total= (total<<1) + !!flags[i] }
  4751. return ''+_proxy_jslib_ARRAY64[total]+_proxy_jslib_ARRAY64[_proxy_jslib_MIME_TYPE_ID[flags[6]]] ;
  4752. }
  4753.  
  4754. function _proxy_jslib_unpack_flags(flagst) {
  4755. var ret= [] ;
  4756. var chars= flagst.split('') ;
  4757. var total= _proxy_jslib_UNARRAY64[chars[0]] ;
  4758. for (var i= 0 ; i<6 ; i++) { ret[5-i]= (total>>i) & 1 }
  4759. ret[6]= _proxy_jslib_ALL_TYPES[_proxy_jslib_UNARRAY64[chars[1]]] ;
  4760. return ret ;
  4761. }
  4762.  
  4763. function _proxy_jslib_url_start_by_flags(flags) {
  4764. return _proxy_jslib_SCRIPT_URL + '/' + _proxy_jslib_lang + '/' + _proxy_jslib_pack_flags(flags) + '/' ;
  4765. }
  4766.  
  4767.  
  4768. function _proxy_jslib_html_escape(s) {
  4769. if (s==void 0) return '' ;
  4770. s= s.replace(/\&/g, '&amp;') ;
  4771. s= s.replace(/([^\x00-\x7f])/g,
  4772. function (a) {
  4773. return '&#' + a.charCodeAt(0) + ';' ;
  4774. } ) ;
  4775. return s.replace(/\"/g, '&quot;')
  4776. .replace(/\</g, '&lt;')
  4777. .replace(/\>/g, '&gt;') ;
  4778. }
  4779.  
  4780. function _proxy_jslib_html_unescape(s) {
  4781. if (s==void 0) return '' ;
  4782. s= s.replace(/\&\#(x)?(\w+);?/g,
  4783. function (a, p1, p2) { return p1
  4784. ? String.fromCharCode(eval('0x'+p2))
  4785. : String.fromCharCode(p2)
  4786. } ) ;
  4787. return s.replace(/\&quot\b\;?/g, '"')
  4788. .replace(/\&lt\b\;?/g, '<')
  4789. .replace(/\&gt\b\;?/g, '>')
  4790. .replace(/\&amp\b\;?/g, '&') ;
  4791. }
  4792.  
  4793.  
  4794.  
  4795. // The replace() method in Netscape is broken, :( :( so we have to implement
  4796. // our own. The bug is that if a function is used as the replacement pattern
  4797. // (needed for anything complex), then *any* replace() or match() (and others?)
  4798. // within that function (or in called functions) will cause its $' to
  4799. // be used in place of the calling replace()'s $' . :P
  4800. // Call this function with a string, a NON-GLOBAL (!) pattern with possible
  4801. // parentheses, and a callback function that takes one argument that is the
  4802. // array resulting from s.match(pattern), and returns a replacement string.
  4803. // Because of how this is implemented, ^ in pattern works much like Perl's \G.
  4804. // Because this is slower than String.replace(), avoid using this when not
  4805. // needed, e.g. when the replacement function has no replace() or match().
  4806. function _proxy_jslib_global_replace(s, pattern, replace_function) {
  4807. if (s==null) return s ;
  4808. var out= '' ;
  4809. var m1 ;
  4810. while ((m1=s.match(pattern))!=null) {
  4811. out+= s.substr(0,m1.index) + replace_function(m1) ;
  4812. s= s.substr(m1.index+m1[0].length) ;
  4813. }
  4814. return out+s ;
  4815. }
  4816.  
  4817.  
  4818.  
  4819. //----------------------------------------------------------------------
Add Comment
Please, Sign In to add comment