CValidator.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /****************************************************************
  2. ** Licensed Materials - Property of IBM
  3. **
  4. ** IBM Cognos Products: Validator
  5. **
  6. ** © Copyright IBM Corp. 2005, 2013
  7. ** US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  8. *****************************************************************/
  9. // Copyright (C) 2008 IBM Cognos Incorporated. All Rights Reserved.
  10. // IBM Cognos and the IBM Cognos logo are trademarks of IBM Cognos Incorporated.
  11. /*
  12. * Public API
  13. */
  14. /*
  15. * Returns 0 on success, a negative integer on fatal code failures, or
  16. * a positive integer on a verify failure. See CValidator.RES_* for detailed
  17. * failure codes.
  18. */
  19. CValidator.prototype = {
  20. verify: function(name, value) {
  21. var res = CValidator.RES_VALID;
  22. var found = false;
  23. if (typeof this[name] == "function") {
  24. res = this[name](value);
  25. found = true;
  26. }
  27. for (i = 0; !found && typeof this["npFunc" + i] == "function"; ++i) {
  28. if (this["npFunc" + i](name)) {
  29. found = true;
  30. res = this["npvFunc" + i](value);
  31. }
  32. }
  33. if (!found && this["_mandatoryRules"]) {
  34. res = CValidator.RES_PARAMETER_NOT_FOUND;
  35. }
  36. return res
  37. }
  38. }
  39. CValidator.RES_VALID = 0;
  40. CValidator.RES_PARAMETER_NOT_FOUND = 1;
  41. CValidator.RES_TYPE_BOOLEAN = 100;
  42. CValidator.RES_TYPE_STRING_MIN_LEN = 200;
  43. CValidator.RES_TYPE_STRING_MAX_LEN = 201;
  44. CValidator.RES_NUMERIC_MIN = 300;
  45. CValidator.RES_NUMERIC_MAX = 301;
  46. CValidator.RES_NUMERIC_NAN = 302;
  47. CValidator.RES_INTEGRAL = 400;
  48. CValidator.RES_TYPE_INT = 500;
  49. CValidator.RES_TYPE_LONG = 600;
  50. CValidator.RES_TYPE_UNSIGNED_INT = 700;
  51. CValidator.RES_TYPE_FLOAT = 550;
  52. CValidator.RES_TYPE_DOUBLE = 650;
  53. CValidator.RES_ENUM_EMPTY = 800;
  54. CValidator.RES_ENUM_NOT_FOUND = 901;
  55. CValidator.RES_PATTERN = 1001;
  56. CValidator.RES_INVALID_URL = 2001;
  57. CValidator.REGEXP_URL =
  58. "^(\/|\\.\/|\\.\\.\/|#.+|[^.]([^:]+\/?))(([^\/]+|([^\/]+\/)+[^\/]+))$" + // relative path
  59. "|" +
  60. "^http(s)?:\/\/" + // protocol
  61. "([\\w-]+)([\\w.-]+)([\\w-]+)" + // domain
  62. "(:(\\d|[1-9]\\d|[1-9]\\d\\d|[1-9]" + // valid ports
  63. "\\d\\d\\d|[1-5]\\d\\d\\d\\d|6[0-4]\\d" + // 1-65535
  64. "\\d\\d|65[0-4]\\d\\d|655[0-2]\\d|6553[0-5]))?" +
  65. "((\/?)|" + // optional if no path
  66. "((\/[0-9a-z_!~*'().;?<>:@&=+$,%#-]+)+\/?))$"; // path
  67. /*
  68. * Private Functions
  69. *
  70. * CValidator and methods prefixed by '_' are private and should not be called by components
  71. */
  72. function CValidator(verifiers) {
  73. for (var v in verifiers) {
  74. this[v] = verifiers[v];
  75. }
  76. }
  77. CValidator.prototype._enumeration =
  78. function(v, emptyValid, caseSensitive, items) {
  79. var strV = v + "";
  80. var res = CValidator.RES_ENUM_NOT_FOUND;
  81. if (v.length == 0) {
  82. if (emptyValid) {
  83. res = CValidator.RES_VALID;
  84. } else {
  85. res = CValidator.RES_ENUM_EMPTY;
  86. }
  87. } else {
  88. if (!caseSensitive) {
  89. strV = strV.toLowerCase();
  90. }
  91. for (i = 0; i < items.length; ++i) {
  92. if (strV == items[i]) {
  93. res = CValidator.RES_VALID;
  94. }
  95. }
  96. }
  97. return res;
  98. }
  99. CValidator.prototype._typeString =
  100. function(v, minLen, maxLen, urlType) {
  101. var strV = v + "";
  102. var res = CValidator.RES_VALID;
  103. if (minLen != null && strV.length < minLen) {
  104. res = CValidator.RES_TYPE_STRING_MIN_LEN;
  105. } else if (maxLen != null && strV.length > maxLen) {
  106. res = CValidator.RES_TYPE_STRING_MAX_LEN;
  107. }
  108. if (urlType == "true" && res == CValidator.RES_VALID) {
  109. //Only perform these checks IFF the string is of type urlType.
  110. //Case insensitive regular expression.
  111. var r = new RegExp(CValidator.REGEXP_URL, "i");
  112. if (!r.test(strV)) {
  113. res = CValidator.RES_INVALID_URL;
  114. }
  115. }
  116. return res;
  117. }
  118. CValidator.prototype._typeBoolean =
  119. function(v) {
  120. var strV = v + "";
  121. return (strV == "true" || strV == "false" || strV == "0" || strV == "1")?
  122. CValidator.RES_VALID : CValidator.RES_TYPE_BOOLEAN;
  123. }
  124. CValidator._getNumber =
  125. function(v) {
  126. var n = v;
  127. switch ( typeof(v) ) {
  128. case "number":
  129. break;
  130. case "string":
  131. if (v == "") {
  132. n = NaN;
  133. } else if (v == "-0") {
  134. n = 0;
  135. } else {
  136. n = (+v);
  137. if (!isNaN(n) && ("a" + n) != ("a" + v)) {
  138. n = NaN;
  139. }
  140. }
  141. break;
  142. default:
  143. n = NaN;
  144. break;
  145. }
  146. return n;
  147. }
  148. CValidator.prototype._checkInteger =
  149. function(v, n) {
  150. var res = CValidator.RES_VALID;
  151. var f = Math.floor(n);
  152. if (v != "-0" && f + "" != v) {
  153. res = CValidator.RES_INTEGRAL;
  154. }
  155. return res;
  156. }
  157. CValidator.prototype._checkNumber =
  158. function(n, min, max) {
  159. var res = CValidator.RES_VALID;
  160. if (isNaN(n)) {
  161. res = CValidator.RES_NUMERIC_NAN;
  162. } else if (min != null && n < min) {
  163. res = CValidator.RES_NUMERIC_MIN;
  164. } else if (max != null && n > max) {
  165. res = CValidator.RES_NUMERIC_MAX;
  166. }
  167. return res;
  168. }
  169. CValidator.prototype._typeInt =
  170. function (v, min, max, emptyValid) {
  171. var res = CValidator.RES_VALID;
  172. var s = v + "";
  173. if (s != "" || !emptyValid) {
  174. var n = CValidator._getNumber(v);
  175. res = this._checkNumber(n, min, max);
  176. if (res == CValidator.RES_VALID) {
  177. res = this._checkInteger(v, n);
  178. if (res == CValidator.RES_VALID) {
  179. if (n < -2147483648 || n > 2147483647) {
  180. res = CValidator.RES_TYPE_INT;
  181. }
  182. }
  183. }
  184. }
  185. return res;
  186. }
  187. CValidator.prototype._typeFloat =
  188. function (v, min, max, emptyValid) {
  189. var res = CValidator.RES_VALID;
  190. var s = v + "";
  191. if (s != "" || !emptyValid) {
  192. var n = CValidator._getNumber(v);
  193. res = this._checkNumber(n, min, max);
  194. }
  195. return res;
  196. }
  197. //
  198. CValidator._CLong64 =
  199. // s as to be passed as a string
  200. function(s) {
  201. this.NaN = true;
  202. var p = /^[-]?[0-9]{1,19}$/;
  203. if (p.test(s)) {
  204. this.NaN = false;
  205. if (s == "-0") {
  206. s = "0";
  207. }
  208. if (s.charAt(0) == "-") {
  209. this.negative = true;
  210. s = s.substring(1);
  211. } else {
  212. this.negative = false;
  213. }
  214. // check for Java long boundaries -9223372036854775808 and 9223372036854775807
  215. if (s.length == 19) {
  216. p = /^([1-8])(9[0-1])|(92[0-1])|(922[0-2])|(9223[0-2])|(92233[0-6])|(922337[0-1])|(92233720[0-2])/;
  217. if (!p.test(s)) {
  218. p = /^(922337203[0-5])|(9223372036[0-7])|(92233720368[0-4])|(922337203685[0-3])|(9223372036854[0-6])/;
  219. if (!p.test(s)) {
  220. p = /^(92233720368547[0-6])|(922337203685477[0-4])|(9223372036854775[0-7])|(922337203685477580[0-7])/;
  221. if (!p.test(s)) {
  222. if (!(this.negative && s.charAt(18) == '8')) {
  223. this.NaN = true;
  224. }
  225. }
  226. }
  227. }
  228. }
  229. if (!this.NaN) {
  230. this.high = null;
  231. if (s.length > 10) {
  232. this.high = s.substring(0, 10);
  233. if (this.high == NaN) {
  234. this.NaN = true;
  235. }
  236. this.low = CValidator._getNumber(s.substring(10));
  237. } else {
  238. this.low = CValidator._getNumber(s);
  239. }
  240. if (this.low == NaN) {
  241. this.NaN = true;
  242. }
  243. }
  244. }
  245. }
  246. CValidator._CLong64.prototype = {
  247. "smallerThan": function(min) {
  248. var res = false;
  249. var min64 = new CValidator._CLong64(min);
  250. if (min64 != null) {
  251. if (this.negative && !min64.negative) {
  252. res = true;
  253. } else if (!this.negative && min64.negative) {
  254. res = false;
  255. } else if (this.high == null && min64.high == null) {
  256. res = this.negative? this.low > min64.low : this.low < min64.low;
  257. } else if (this.high != null && min64.high == null) {
  258. res = this.negative;
  259. } else if (this.high == null && min64.high != null) {
  260. res = !this.negative;
  261. } else { // this.high != null && this.min64 != null
  262. if (this.high == min64.high) {
  263. res = this.negative? this.low > min64.low : this.low < min64.low;
  264. } else {
  265. res = this.negative? this.high > min64.high : this.high < min64.high;
  266. }
  267. }
  268. }
  269. return res;
  270. },
  271. "greaterThan": function(max) {
  272. var res = false;
  273. var max64 = new CValidator._CLong64(max);
  274. if (max64 != null) {
  275. if (!this.negative && max64.negative) {
  276. res = true;
  277. } else if (this.negative && !max64.negative) {
  278. res = false;
  279. } else if (this.high == null && max64.high == null) {
  280. res = this.negative? this.low < max64.low : this.low > max64.low;
  281. } else if (this.high != null && max64.high == null) {
  282. res = !this.negative;
  283. } else if (this.high == null && max64.high != null) {
  284. res = this.negative;
  285. } else { // this.high != null && this.min64 != null
  286. if (this.high == max64.high) {
  287. res = this.negative? this.low < max64.low : this.low > max64.low;
  288. } else {
  289. res = this.negative? this.high < max64.low : this.high > max64.low;
  290. }
  291. }
  292. }
  293. return res;
  294. }
  295. }
  296. CValidator._CDouble64 =
  297. // s as to be passed as a string
  298. function (s) {
  299. this.NaN = true;
  300. var p = /^[-]?\d+.?\d*$/;
  301. if (p.test(s)) {
  302. this.NaN = false;
  303. if (s == "-0") {
  304. s = "0";
  305. }
  306. if (s.charAt(0) == "-") {
  307. this.negative = true;
  308. s = s.substring(1);
  309. } else {
  310. this.negative = false;
  311. }
  312. var indexOfDecimal = s.indexOf(".");
  313. if (indexOfDecimal != -1) {
  314. this.fractional = CValidator._getNumber(s.substring(indexOfDecimal + 1));
  315. if (this.fractional == NaN) {
  316. this.fractional = null;
  317. }
  318. s = s.substring(0, indexOfDecimal - 1);
  319. } else {
  320. this.fractional = null;
  321. }
  322. if (!this.NaN) {
  323. this.high = null;
  324. if (s.length > 10) {
  325. this.high = s.substring(0, 10);
  326. if (this.high == NaN) {
  327. this.NaN = true;
  328. }
  329. this.low = CValidator._getNumber(s.substring(10));
  330. } else {
  331. this.low = CValidator._getNumber(s);
  332. }
  333. if (this.low == NaN) {
  334. this.NaN = true;
  335. }
  336. }
  337. }
  338. }
  339. CValidator._CDouble64.prototype = {
  340. "smallerThan": function (min) {
  341. var res = false;
  342. var min64 = new CValidator._CDouble64(min);
  343. if (min64 != null) {
  344. if (this.negative && !min64.negative) {
  345. res = true;
  346. } else if (!this.negative && min64.negative) {
  347. res = false;
  348. } else if (this.high == null && min64.high == null) {
  349. if (this.low == min64.low) {
  350. if (this.fractional != null && min64.fractional != null) {
  351. res = this.negative ? this.fractional > min64.fractional : this.fractional < min64.fractional;
  352. } else if (this.fractional == null && min64.fractional == null) {
  353. res = true;
  354. } else if (this.fractional == null && min64.fractional != null) {
  355. res = !this.negative;
  356. } else if (this.fractional != null && min64.fractional == null) {
  357. res = this.negative;
  358. }
  359. } else {
  360. res = this.negative ? this.low > min64.low : this.low < min64.low;
  361. }
  362. } else if (this.high != null && min64.high == null) {
  363. res = this.negative;
  364. } else if (this.high == null && min64.high != null) {
  365. res = !this.negative;
  366. } else { // this.high != null && this.min64 != null
  367. if (this.high == min64.high) {
  368. if (this.low == min64.low) {
  369. if (this.fractional != null && min64.fractional != null) {
  370. res = this.negative ? this.fractional > min64.fractional : this.fractional < min64.fractional;
  371. } else if (this.fractional == null && min64.fractional == null) {
  372. res = true;
  373. } else if (this.fractional == null && min64.fractional != null) {
  374. res = !this.negative;
  375. } else if (this.fractional != null && min64.fractional == null) {
  376. res = this.negative;
  377. }
  378. } else {
  379. res = this.negative ? this.low > min64.low : this.low < min64.low;
  380. }
  381. } else {
  382. res = this.negative ? this.high > min64.high : this.high < min64.high;
  383. }
  384. }
  385. }
  386. return res;
  387. },
  388. "greaterThan": function (max) {
  389. var res = false;
  390. var max64 = new CValidator._CDouble64(max);
  391. if (max64 != null) {
  392. if (!this.negative && max64.negative) {
  393. res = true;
  394. } else if (this.negative && !max64.negative) {
  395. res = false;
  396. } else if (this.high == null && max64.high == null) {
  397. if (this.low == max64.low) {
  398. if (this.fractional != null && min64.fractional != null) {
  399. res = this.negative ? this.fractional < max64.fractional : this.fractional > max64.fractional;
  400. } else if (this.fractional == null && max64.fractional == null) {
  401. res = true;
  402. } else if (this.fractional == null && max64.fractional != null) {
  403. res = this.negative;
  404. } else if (this.fractional != null && max64.fractional == null) {
  405. res = !this.negative;
  406. }
  407. } else {
  408. res = this.negative ? this.low < max64.low : this.low > max64.low;
  409. }
  410. } else if (this.high != null && max64.high == null) {
  411. res = !this.negative;
  412. } else if (this.high == null && max64.high != null) {
  413. res = this.negative;
  414. } else { // this.high != null && this.min64 != null
  415. if (this.high == max64.high) {
  416. if (this.low == max64.low) {
  417. if (this.fractional != null && min64.fractional != null) {
  418. res = this.negative ? this.fractional < max64.fractional : this.fractional > max64.fractional;
  419. } else if (this.fractional == null && max64.fractional == null) {
  420. res = true;
  421. } else if (this.fractional == null && max64.fractional != null) {
  422. res = this.negative;
  423. } else if (this.fractional != null && max64.fractional == null) {
  424. res = !this.negative;
  425. }
  426. } else {
  427. res = this.negative ? this.low < max64.low : this.low > max64.low;
  428. }
  429. } else {
  430. res = this.negative ? this.high < max64.low : this.high > max64.low;
  431. }
  432. }
  433. }
  434. return res;
  435. }
  436. }
  437. CValidator.prototype._typeLong =
  438. function (v, min, max, emptyValid) {
  439. var res = CValidator.RES_VALID;
  440. var s = v + "";
  441. if (s != "" || !emptyValid) {
  442. var s64 = new CValidator._CLong64(s);
  443. if (s64.NaN) {
  444. res = CValidator.RES_NUMERIC_NAN;
  445. } else {
  446. if (min != null) {
  447. if (s64.smallerThan(min)) {
  448. res = CValidator.RES_NUMERIC_MIN;
  449. }
  450. }
  451. if (res == CValidator.RES_VALID && max != null) {
  452. if (s64.greaterThan(max)) {
  453. res = CValidator.RES_NUMERIC_MAX;
  454. }
  455. }
  456. }
  457. }
  458. return res;
  459. }
  460. CValidator.prototype._typeDouble =
  461. function (v, min, max, emptyValid) {
  462. var res = CValidator.RES_VALID;
  463. var s = v + "";
  464. if (s != "" || !emptyValid) {
  465. var s64 = new CValidator._CDouble64(s);
  466. if (s64.NaN) {
  467. res = CValidator.RES_NUMERIC_NAN;
  468. } else {
  469. if (min != null) {
  470. if (s64.smallerThan(min)) {
  471. res = CValidator.RES_NUMERIC_MIN;
  472. }
  473. }
  474. if (res == CValidator.RES_VALID && max != null) {
  475. if (s64.greaterThan(max)) {
  476. res = CValidator.RES_NUMERIC_MAX;
  477. }
  478. }
  479. }
  480. }
  481. return res;
  482. }
  483. CValidator.prototype._typeUnsignedInt =
  484. function(v, min, max, emptyValid) {
  485. var res = CValidator.RES_VALID;
  486. var s = v + "";
  487. if (s != "" || !emptyValid) {
  488. var n = CValidator._getNumber(v);
  489. res = this._checkNumber(n, min, max);
  490. if (res == CValidator.RES_VALID) {
  491. res = this._checkInteger(v, n);
  492. if (res == CValidator.RES_VALID) {
  493. if (n < 0 || n > 4294967295) {
  494. res = CValidator.RES_TYPE_UNSIGNED_INT;
  495. }
  496. }
  497. }
  498. }
  499. return res;
  500. }
  501. CValidator.prototype._pattern =
  502. function(v, caseSensitive, not, findMode, regex) {
  503. var res = CValidator.RES_VALID;
  504. var a = "";
  505. if (!caseSensitive) {
  506. a += "i";
  507. }
  508. if (!findMode) {
  509. regex = "^" + regex + "$";
  510. }
  511. var r = new RegExp(regex, a);
  512. if (r.test(v)) {
  513. if (not) {
  514. res = CValidator.RES_PATTERN;
  515. }
  516. } else {
  517. if (!not) {
  518. res = CValidator.RES_PATTERN;
  519. }
  520. }
  521. return res;
  522. }
  523. CValidator.prototype._checkGlobals =
  524. function(v) {
  525. var res = CValidator.RES_VALID;
  526. for (i = 0; res == CValidator.RES_VALID && typeof this["gFunc" + i] == "function"; ++i) {
  527. res = this["gFunc" + i](v) != CValidator.RES_VALID;
  528. }
  529. return res;
  530. }