You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

274 lines
7.9 KiB

  1. /**
  2. * Upgraded
  3. * !!Do not modify the above line!!
  4. */
  5. /**
  6. * SafeFN is a Javascript implementation of Christopher Smith's php
  7. * SafeFN class which was written for Dokuwiki
  8. *
  9. * @author Myron Turner <turnermm@shaw.ca>
  10. * @copyright Myron Turner (C) GPL 2 or greater
  11. */
  12. var SafeFN = {
  13. plain: '-./[_0123456789abcdefghijklmnopqrstuvwxyz', // these characters aren't converted
  14. pre_indicator: '%',
  15. post_indicator:']',
  16. /**
  17. * convert numbers from base 10 to base 36 and base 36 to base 10
  18. *
  19. * @param string representing an integer or integer num number to be converted
  20. * @param integer from base from which to convert
  21. * @param integer to base to which to convert
  22. *
  23. * @return array int an array of unicode codepoints
  24. *
  25. * @author Myron Turner <turnermm02@shaw.ca>
  26. */
  27. changeSafeBase: function(num, from, to) {
  28. if(isNaN(from) || from < 2 || from > 36 || isNaN(to) || to < 2 || to > 36) {
  29. throw (new RangeError("Illegal radix. Radices must be integers between 2 and 36, inclusive."));
  30. }
  31. num = parseInt(num, from);
  32. if(from == 36) return num;
  33. return num.toString(to);
  34. },
  35. /**
  36. * convert a UTF8 string into an array of unicode code points
  37. *
  38. * @param UTF8 string
  39. * @return array int an array of unicode codepoints
  40. *
  41. * @author Myron Turner <turnermm02@shaw.ca>
  42. */
  43. get_u_array: function(utf8str) {
  44. var unicode_array = new Array();
  45. for (var i=0; i<utf8str.length; i++) {
  46. unicode_array[i] = utf8str.charCodeAt(i);;
  47. }
  48. return unicode_array;
  49. },
  50. /**
  51. * convert a 'safe_filename' string into an array of unicode codepoints
  52. *
  53. * @param string safe a filename in 'safe_filename' format
  54. * @return array int an array of unicode codepoints
  55. * @author Christopher Smith <chris@jalakai.co.uk>
  56. * @author Myron Turner<turnermm02@shaw.ca>
  57. */
  58. safe_to_unicode: function(safe) {
  59. var unicode = new Array();
  60. var regex = new RegExp('(?=[' + this.pre_indicator + '\\' + this.post_indicator + '])');
  61. var split_array = safe.split(regex);
  62. var converted = false;
  63. for (var i = 0; i<split_array.length; i++ ) {
  64. var sub = split_array[i];
  65. if (sub.charAt(0) != this.pre_indicator) { // i.e. sub.charAt(0) != '%'
  66. var start = converted?1:0;
  67. for (j=start; j < sub.length; j++) {
  68. unicode.push(sub.charCodeAt(j));
  69. }
  70. converted = false;
  71. } else if (sub.length==1) {
  72. unicode.push(sub.charCodeAt(0));
  73. converted = true;
  74. } else {
  75. unicode.push(32 + this.changeSafeBase(sub.slice(1),36,10));
  76. converted = true;
  77. }
  78. }
  79. return unicode;
  80. },
  81. /**
  82. * convert an array of unicode codepoints into 'safe_filename' format
  83. *
  84. * @param array int $unicode an array of unicode codepoints
  85. * @return string the unicode represented in 'safe_filename' format
  86. *
  87. * @author Christopher Smith <chris@jalakai.co.uk>
  88. * @author Myron Turner <turnermm02@shaw.ca>
  89. */
  90. unicode_to_safe: function (unicode) {
  91. var safe = '';
  92. var converted = false;
  93. var plain_str = this.plain + this.post_indicator;
  94. for (var i=0; i< unicode.length; i++) {
  95. codepoint = unicode[i];
  96. var match = '';
  97. if(String.fromCharCode(codepoint) != '\\') {
  98. var regex = new RegExp(String.fromCharCode(codepoint));
  99. var match = plain_str.match(regex);
  100. }
  101. if (codepoint < 127 && match) {
  102. if (converted) {
  103. safe += this.post_indicator;
  104. converted = false;
  105. }
  106. safe += String.fromCharCode(codepoint);
  107. } else if (codepoint == this.pre_indicator.charCodeAt(0)) {
  108. safe += this.pre_indicator;
  109. converted = true;
  110. } else {
  111. safe += this.pre_indicator + this.changeSafeBase((codepoint-32), 10, 36);
  112. converted = true;
  113. }
  114. }
  115. if(converted) safe += this.post_indicator;
  116. return safe;
  117. },
  118. /**
  119. * Convert an UTF-8 string to a safe ASCII String
  120. *
  121. *
  122. * @param string filename a utf8 string, should only include printable characters - not 0x00-0x1f
  123. * @return string an encoded representation of filename using only 'safe' ASCII characters
  124. *
  125. * @author Myron Turner <turnermm02@shaw.ca>
  126. */
  127. encode: function(filename) {
  128. return this.unicode_to_safe(this.get_u_array(filename));
  129. },
  130. /**
  131. * decode a 'safe' encoded file name and return a UTF8 string
  132. *
  133. * @param string filename a 'safe' encoded ASCII string,
  134. * @return string decoded utf8 string
  135. *
  136. * @author Myron Turner <turnermm02@shaw.ca>
  137. */
  138. decode: function (filename) {
  139. var unic = this.safe_to_unicode(filename);
  140. // convert unicode code points to utf8
  141. var str = new Array();
  142. for (var i=0; i < unic.length; i++) {
  143. str[i] = this.code2utf(unic[i]);
  144. }
  145. // return the decoded string
  146. return this.utf8Decode(str.join(''));
  147. },
  148. /* UTF8 encoding/decoding functions
  149. * Copyright (c) 2006 by Ali Farhadi.
  150. * released under the terms of the Gnu Public License.
  151. * see the GPL for details.
  152. *
  153. * Email: ali[at]farhadi[dot]ir
  154. * Website: http://farhadi.ir/
  155. */
  156. //an alias of String.fromCharCode
  157. chr: function (code)
  158. {
  159. return String.fromCharCode(code);
  160. },
  161. //returns utf8 encoded charachter of a unicode value.
  162. //code must be a number indicating the Unicode value.
  163. //returned value is a string between 1 and 4 charachters.
  164. code2utf: function (code)
  165. {
  166. if (code < 128) return this.chr(code);
  167. if (code < 2048) return this.chr(192+(code>>6)) + this.chr(128+(code&63));
  168. if (code < 65536) return this.chr(224+(code>>12)) + this.chr(128+((code>>6)&63)) + this.chr(128+(code&63));
  169. if (code < 2097152) return this.chr(240+(code>>18)) + this.chr(128+((code>>12)&63)) + this.chr(128+((code>>6)&63)) + this.chr(128+(code&63));
  170. },
  171. //it is a private function for internal use in utf8Decode function
  172. _utf8Decode: function (utf8str)
  173. {
  174. var str = new Array();
  175. var code,code2,code3,code4,j = 0;
  176. for (var i=0; i<utf8str.length; ) {
  177. code = utf8str.charCodeAt(i++);
  178. if (code > 127) code2 = utf8str.charCodeAt(i++);
  179. if (code > 223) code3 = utf8str.charCodeAt(i++);
  180. if (code > 239) code4 = utf8str.charCodeAt(i++);
  181. if (code < 128) str[j++]= this.chr(code);
  182. else if (code < 224) str[j++] = this.chr(((code-192)<<6) + (code2-128));
  183. else if (code < 240) str[j++] = this.chr(((code-224)<<12) + ((code2-128)<<6) + (code3-128));
  184. else str[j++] = this.chr(((code-240)<<18) + ((code2-128)<<12) + ((code3-128)<<6) + (code4-128));
  185. }
  186. return str.join('');
  187. },
  188. //Decodes a UTF8 formated string
  189. utf8Decode: function (utf8str)
  190. {
  191. var str = new Array();
  192. var pos = 0;
  193. var tmpStr = '';
  194. var j=0;
  195. while ((pos = utf8str.search(/[^\x00-\x7F]/)) != -1) {
  196. tmpStr = utf8str.match(/([^\x00-\x7F]+[\x00-\x7F]{0,10})+/)[0];
  197. str[j++]= utf8str.substr(0, pos) + this._utf8Decode(tmpStr);
  198. utf8str = utf8str.substr(pos + tmpStr.length);
  199. }
  200. str[j++] = utf8str;
  201. return str.join('');
  202. }
  203. };
  204. function SafeFN_encode(filename) {
  205. return SafeFN.encode(filename);
  206. }
  207. function SafeFN_decode(filename) {
  208. return SafeFN.decode(filename);
  209. }
  210. function dwikiUTF8_encodeFN(file, encoding){
  211. if(encoding == 'utf-8') return file;
  212. if(file.match(/^[a-zA-Z0-9\/_\-\.%\]]+$/)){
  213. return file;
  214. }
  215. if(encoding == 'safe'){
  216. return SafeFN_encode(file);
  217. }
  218. file = encodeURIComponent(file);
  219. file = file.replace(/%2F/g,'/');
  220. return file;
  221. }
  222. function dwikiUTF8_decodeFN(file, encoding){
  223. if(encoding == 'utf-8') return file;
  224. if(encoding == 'safe'){
  225. return SafeFN_decode(file);
  226. }
  227. return decodeURIComponent(file);
  228. }