Browse Source

add support for regex unicode categories

Robin Herbots 3 years ago
parent
commit
7939fd9ef4
10 changed files with 121 additions and 88 deletions
  1. 2 0
      CHANGELOG.md
  2. 1 1
      bower.json
  3. 1 1
      composer.json
  4. 50 38
      dist/inputmask.js
  5. 2 2
      dist/inputmask.min.js
  6. 50 38
      dist/jquery.inputmask.js
  7. 2 2
      dist/jquery.inputmask.min.js
  8. 9 2
      lib/mask-lexer.js
  9. 3 3
      lib/validation-tests.js
  10. 1 1
      package.json

+ 2 - 0
CHANGELOG.md

@@ -3,6 +3,7 @@
 ## [5.0.8 - UNRELEASED]
 
 ### Addition
+- Regex unicode categories
 - Comma input turns to decimal #2577 => add substituteRadixPoint option to numeric alias
 
 ### Updates
@@ -14,6 +15,7 @@
 - fix value reversing with noValuePatching & numericInput - #2629
 
 ### Fixed
+- Regex unicode categories cause RangeError: Maximum call stack size exceeded #2639
 - error message: Cannot read properties of undefined (reading 'allowMinus') #2642
 - fix iphone\ios bug for cyrillic keyboard - #2637
 - getemptymask returns a reversed string in 5.x #2605

+ 1 - 1
bower.json

@@ -1,6 +1,6 @@
 {
   "name": "inputmask",
-  "version": "5.0.8-beta.38",
+  "version": "5.0.8-beta.41",
   "main": [
 	  "./index.js",
     "./css/inputmask.css"

+ 1 - 1
composer.json

@@ -1,7 +1,7 @@
 {
   "name": "robinherbots/inputmask",
   "description": "Inputmask is a javascript library which creates an input mask.  Inputmask can run against vanilla javascript, jQuery and jqlite.",
-  "version": "5.0.8-beta.38",
+  "version": "5.0.8-beta.41",
   "type": "library",
   "keywords": ["jquery", "plugins", "input", "form", "inputmask", "mask"],
   "homepage": "http://robinherbots.github.io/Inputmask",

+ 50 - 38
dist/inputmask.js

@@ -3,7 +3,7 @@
  * https://github.com/RobinHerbots/Inputmask
  * Copyright (c) 2010 - 2022 Robin Herbots
  * Licensed under the MIT license
- * Version: 5.0.8-beta.38
+ * Version: 5.0.8-beta.41
  */
 !function(e, t) {
     if ("object" == typeof exports && "object" == typeof module) module.exports = t(); else if ("function" == typeof define && define.amd) define([], t); else {
@@ -2016,41 +2016,47 @@
                     function k(e, a, n) {
                         n = void 0 !== n ? n : e.matches.length;
                         var o = e.matches[n - 1];
-                        if (t) 0 === a.indexOf("[") || d && /\\d|\\s|\\w/i.test(a) || "." === a ? e.matches.splice(n++, 0, {
-                            fn: new RegExp(a, i.casing ? "i" : ""),
-                            static: !1,
-                            optionality: !1,
-                            newBlockMarker: void 0 === o ? "master" : o.def !== a,
-                            casing: null,
-                            def: a,
-                            placeholder: void 0,
-                            nativeDef: a
-                        }) : (d && (a = a[a.length - 1]), a.split("").forEach((function(t, a) {
-                            o = e.matches[n - 1], e.matches.splice(n++, 0, {
-                                fn: /[a-z]/i.test(i.staticDefinitionSymbol || t) ? new RegExp("[" + (i.staticDefinitionSymbol || t) + "]", i.casing ? "i" : "") : null,
-                                static: !0,
-                                optionality: !1,
-                                newBlockMarker: void 0 === o ? "master" : o.def !== t && !0 !== o.static,
-                                casing: null,
-                                def: i.staticDefinitionSymbol || t,
-                                placeholder: void 0 !== i.staticDefinitionSymbol ? t : void 0,
-                                nativeDef: (d ? "'" : "") + t
-                            });
-                        }))), d = !1; else {
-                            var s = i.definitions && i.definitions[a] || i.usePrototypeDefinitions && r.default.prototype.definitions[a];
-                            s && !d ? e.matches.splice(n++, 0, {
-                                fn: s.validator ? "string" == typeof s.validator ? new RegExp(s.validator, i.casing ? "i" : "") : new function() {
-                                    this.test = s.validator;
+                        if (t) {
+                            if (0 === a.indexOf("[") || d && /\\d|\\s|\\w|\\p/i.test(a) || "." === a) {
+                                var s = i.casing ? "i" : "";
+                                /^\\p\{.*}$/i.test(a) && (s += "u"), e.matches.splice(n++, 0, {
+                                    fn: new RegExp(a, s),
+                                    static: !1,
+                                    optionality: !1,
+                                    newBlockMarker: void 0 === o ? "master" : o.def !== a,
+                                    casing: null,
+                                    def: a,
+                                    placeholder: void 0,
+                                    nativeDef: a
+                                });
+                            } else d && (a = a[a.length - 1]), a.split("").forEach((function(t, a) {
+                                o = e.matches[n - 1], e.matches.splice(n++, 0, {
+                                    fn: /[a-z]/i.test(i.staticDefinitionSymbol || t) ? new RegExp("[" + (i.staticDefinitionSymbol || t) + "]", i.casing ? "i" : "") : null,
+                                    static: !0,
+                                    optionality: !1,
+                                    newBlockMarker: void 0 === o ? "master" : o.def !== t && !0 !== o.static,
+                                    casing: null,
+                                    def: i.staticDefinitionSymbol || t,
+                                    placeholder: void 0 !== i.staticDefinitionSymbol ? t : void 0,
+                                    nativeDef: (d ? "'" : "") + t
+                                });
+                            }));
+                            d = !1;
+                        } else {
+                            var l = i.definitions && i.definitions[a] || i.usePrototypeDefinitions && r.default.prototype.definitions[a];
+                            l && !d ? e.matches.splice(n++, 0, {
+                                fn: l.validator ? "string" == typeof l.validator ? new RegExp(l.validator, i.casing ? "i" : "") : new function() {
+                                    this.test = l.validator;
                                 } : new RegExp("."),
-                                static: s.static || !1,
-                                optionality: s.optional || !1,
-                                defOptionality: s.optional || !1,
-                                newBlockMarker: void 0 === o || s.optional ? "master" : o.def !== (s.definitionSymbol || a),
-                                casing: s.casing,
-                                def: s.definitionSymbol || a,
-                                placeholder: s.placeholder,
+                                static: l.static || !1,
+                                optionality: l.optional || !1,
+                                defOptionality: l.optional || !1,
+                                newBlockMarker: void 0 === o || l.optional ? "master" : o.def !== (l.definitionSymbol || a),
+                                casing: l.casing,
+                                def: l.definitionSymbol || a,
+                                placeholder: l.placeholder,
                                 nativeDef: a,
-                                generated: s.generated
+                                generated: l.generated
                             }) : (e.matches.splice(n++, 0, {
                                 fn: /[a-z]/i.test(i.staticDefinitionSymbol || a) ? new RegExp("[" + (i.staticDefinitionSymbol || a) + "]", i.casing ? "i" : "") : null,
                                 static: !0,
@@ -2109,7 +2115,14 @@
                                     w.openGroup = !0, v.push(w), h.matches = [], g = !0;
                                 }
                             }
-                            if ("\\d" === o) o = "[0-9]";
+                            switch (o) {
+                              case "\\d":
+                                o = "[0-9]";
+                                break;
+
+                              case "\\p":
+                                o += p.exec(e)[0], o += p.exec(e)[0];
+                            }
                         }
                         if (d) y(); else switch (o.charAt(0)) {
                           case "$":
@@ -2605,7 +2618,7 @@
                     }(e, t);
                     e = e > 0 ? e - 1 : 0;
                     var o, s, l, c = r(u.call(this, e));
-                    i.greedy && t.length > 1 && "" === t[t.length - 1].match.def && a++;
+                    i.greedy && t.length > 1 && "" === t[t.length - 1].match.def && (a = 1);
                     for (var f = 0; f < t.length - a; f++) {
                         var p = t[f];
                         o = r(p, c.length);
@@ -2749,8 +2762,7 @@
                                     if (r = s(Q, [ z ].concat(o), Q)) {
                                         if ((a = m[m.length - 1].match).optionalQuantifier = z >= q.quantifier.min, a.jit = (z + 1) * (Q.matches.indexOf(a) + 1) > q.quantifier.jit, 
                                         a.optionalQuantifier && d(a, Q)) {
-                                            g = !0, h = e, u.greedy && null == l.validPositions[e - 1] && z > q.quantifier.min && (m.pop(), 
-                                            k = void 0);
+                                            g = !0, h = e, u.greedy && null == l.validPositions[e - 1] && q.quantifier.min;
                                             break;
                                         }
                                         return a.jit && (l.jitOffset[e] = Q.matches.length - Q.matches.indexOf(a)), !0;

File diff suppressed because it is too large
+ 2 - 2
dist/inputmask.min.js


+ 50 - 38
dist/jquery.inputmask.js

@@ -3,7 +3,7 @@
  * https://github.com/RobinHerbots/Inputmask
  * Copyright (c) 2010 - 2022 Robin Herbots
  * Licensed under the MIT license
- * Version: 5.0.8-beta.38
+ * Version: 5.0.8-beta.41
  */
 !function(e, t) {
     if ("object" == typeof exports && "object" == typeof module) module.exports = t(require("jquery")); else if ("function" == typeof define && define.amd) define([ "jquery" ], t); else {
@@ -1963,41 +1963,47 @@
                     function k(e, a, n) {
                         n = void 0 !== n ? n : e.matches.length;
                         var o = e.matches[n - 1];
-                        if (t) 0 === a.indexOf("[") || d && /\\d|\\s|\\w/i.test(a) || "." === a ? e.matches.splice(n++, 0, {
-                            fn: new RegExp(a, i.casing ? "i" : ""),
-                            static: !1,
-                            optionality: !1,
-                            newBlockMarker: void 0 === o ? "master" : o.def !== a,
-                            casing: null,
-                            def: a,
-                            placeholder: void 0,
-                            nativeDef: a
-                        }) : (d && (a = a[a.length - 1]), a.split("").forEach((function(t, a) {
-                            o = e.matches[n - 1], e.matches.splice(n++, 0, {
-                                fn: /[a-z]/i.test(i.staticDefinitionSymbol || t) ? new RegExp("[" + (i.staticDefinitionSymbol || t) + "]", i.casing ? "i" : "") : null,
-                                static: !0,
-                                optionality: !1,
-                                newBlockMarker: void 0 === o ? "master" : o.def !== t && !0 !== o.static,
-                                casing: null,
-                                def: i.staticDefinitionSymbol || t,
-                                placeholder: void 0 !== i.staticDefinitionSymbol ? t : void 0,
-                                nativeDef: (d ? "'" : "") + t
-                            });
-                        }))), d = !1; else {
-                            var s = i.definitions && i.definitions[a] || i.usePrototypeDefinitions && r.default.prototype.definitions[a];
-                            s && !d ? e.matches.splice(n++, 0, {
-                                fn: s.validator ? "string" == typeof s.validator ? new RegExp(s.validator, i.casing ? "i" : "") : new function() {
-                                    this.test = s.validator;
+                        if (t) {
+                            if (0 === a.indexOf("[") || d && /\\d|\\s|\\w|\\p/i.test(a) || "." === a) {
+                                var s = i.casing ? "i" : "";
+                                /^\\p\{.*}$/i.test(a) && (s += "u"), e.matches.splice(n++, 0, {
+                                    fn: new RegExp(a, s),
+                                    static: !1,
+                                    optionality: !1,
+                                    newBlockMarker: void 0 === o ? "master" : o.def !== a,
+                                    casing: null,
+                                    def: a,
+                                    placeholder: void 0,
+                                    nativeDef: a
+                                });
+                            } else d && (a = a[a.length - 1]), a.split("").forEach((function(t, a) {
+                                o = e.matches[n - 1], e.matches.splice(n++, 0, {
+                                    fn: /[a-z]/i.test(i.staticDefinitionSymbol || t) ? new RegExp("[" + (i.staticDefinitionSymbol || t) + "]", i.casing ? "i" : "") : null,
+                                    static: !0,
+                                    optionality: !1,
+                                    newBlockMarker: void 0 === o ? "master" : o.def !== t && !0 !== o.static,
+                                    casing: null,
+                                    def: i.staticDefinitionSymbol || t,
+                                    placeholder: void 0 !== i.staticDefinitionSymbol ? t : void 0,
+                                    nativeDef: (d ? "'" : "") + t
+                                });
+                            }));
+                            d = !1;
+                        } else {
+                            var l = i.definitions && i.definitions[a] || i.usePrototypeDefinitions && r.default.prototype.definitions[a];
+                            l && !d ? e.matches.splice(n++, 0, {
+                                fn: l.validator ? "string" == typeof l.validator ? new RegExp(l.validator, i.casing ? "i" : "") : new function() {
+                                    this.test = l.validator;
                                 } : new RegExp("."),
-                                static: s.static || !1,
-                                optionality: s.optional || !1,
-                                defOptionality: s.optional || !1,
-                                newBlockMarker: void 0 === o || s.optional ? "master" : o.def !== (s.definitionSymbol || a),
-                                casing: s.casing,
-                                def: s.definitionSymbol || a,
-                                placeholder: s.placeholder,
+                                static: l.static || !1,
+                                optionality: l.optional || !1,
+                                defOptionality: l.optional || !1,
+                                newBlockMarker: void 0 === o || l.optional ? "master" : o.def !== (l.definitionSymbol || a),
+                                casing: l.casing,
+                                def: l.definitionSymbol || a,
+                                placeholder: l.placeholder,
                                 nativeDef: a,
-                                generated: s.generated
+                                generated: l.generated
                             }) : (e.matches.splice(n++, 0, {
                                 fn: /[a-z]/i.test(i.staticDefinitionSymbol || a) ? new RegExp("[" + (i.staticDefinitionSymbol || a) + "]", i.casing ? "i" : "") : null,
                                 static: !0,
@@ -2056,7 +2062,14 @@
                                     w.openGroup = !0, m.push(w), h.matches = [], g = !0;
                                 }
                             }
-                            if ("\\d" === o) o = "[0-9]";
+                            switch (o) {
+                              case "\\d":
+                                o = "[0-9]";
+                                break;
+
+                              case "\\p":
+                                o += p.exec(e)[0], o += p.exec(e)[0];
+                            }
                         }
                         if (d) y(); else switch (o.charAt(0)) {
                           case "$":
@@ -2552,7 +2565,7 @@
                     }(e, t);
                     e = e > 0 ? e - 1 : 0;
                     var o, s, l, c = r(u.call(this, e));
-                    i.greedy && t.length > 1 && "" === t[t.length - 1].match.def && a++;
+                    i.greedy && t.length > 1 && "" === t[t.length - 1].match.def && (a = 1);
                     for (var f = 0; f < t.length - a; f++) {
                         var p = t[f];
                         o = r(p, c.length);
@@ -2696,8 +2709,7 @@
                                     if (r = s(Q, [ z ].concat(o), Q)) {
                                         if ((a = v[v.length - 1].match).optionalQuantifier = z >= q.quantifier.min, a.jit = (z + 1) * (Q.matches.indexOf(a) + 1) > q.quantifier.jit, 
                                         a.optionalQuantifier && d(a, Q)) {
-                                            g = !0, h = e, u.greedy && null == l.validPositions[e - 1] && z > q.quantifier.min && (v.pop(), 
-                                            k = void 0);
+                                            g = !0, h = e, u.greedy && null == l.validPositions[e - 1] && q.quantifier.min;
                                             break;
                                         }
                                         return a.jit && (l.jitOffset[e] = Q.matches.length - Q.matches.indexOf(a)), !0;

File diff suppressed because it is too large
+ 2 - 2
dist/jquery.inputmask.min.js


+ 9 - 2
lib/mask-lexer.js

@@ -133,9 +133,12 @@ function analyseMask(mask, regexMask, opts) {
         position = position !== undefined ? position : mtoken.matches.length;
         var prevMatch = mtoken.matches[position - 1];
         if (regexMask) {
-            if (element.indexOf("[") === 0 || (escaped && /\\d|\\s|\\w/i.test(element)) || element === ".") {
+            if (element.indexOf("[") === 0 || (escaped && /\\d|\\s|\\w|\\p/i.test(element)) || element === ".") {
+                let flag = opts.casing ? "i" : "";
+                if (/^\\p\{.*}$/i.test(element))
+                    flag += "u";
                 mtoken.matches.splice(position++, 0, {
-                    fn: new RegExp(element, opts.casing ? "i" : ""),
+                    fn: new RegExp(element, flag),
                     static: false,
                     optionality: false,
                     newBlockMarker: prevMatch === undefined ? "master" : prevMatch.def !== element,
@@ -347,6 +350,10 @@ function analyseMask(mask, regexMask, opts) {
                 case "\\d":
                     m = "[0-9]";
                     break;
+                case "\\p": //Unicode Categories
+                    m += regexTokenizer.exec(mask)[0]; // {
+                    m += regexTokenizer.exec(mask)[0]; // ?}
+                    break;
                 case "(?=": //lookahead
                     // openenings.push(new MaskToken(true));
                     break;

+ 3 - 3
lib/validation-tests.js

@@ -133,7 +133,7 @@ function determineTestTemplate(pos, tests) {
     pos = pos > 0 ? pos - 1 : 0;
     var altTest = getTest.call(inputmask, pos), targetLocator = getLocator(altTest), tstLocator, closest, bestMatch;
     if (opts.greedy && tests.length > 1 && tests[tests.length - 1].match.def === "")
-        lenghtOffset++;
+        lenghtOffset = 1;
     // console.log(" optionality = " + optionalityLevel);
     // console.log(" - " + JSON.stringify(tests));
     for (var ndx = 0; ndx < tests.length - lenghtOffset; ndx++) { //find best matching
@@ -486,8 +486,8 @@ function getTests(pos, ndxIntlzr, tstPs) {
                                 insertStop = true;
                                 testPos = pos; //match the position after the group
                                 if (opts.greedy && maskset.validPositions[pos - 1] == undefined && qndx > qt.quantifier.min) {
-                                    matches.pop();
-                                    cacheDependency = undefined;
+                                    // matches.pop();
+                                    // cacheDependency = undefined;
                                 }
                                 break; //stop quantifierloop && search for next possible match
                             }

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "inputmask",
-  "version": "5.0.8-beta.38",
+  "version": "5.0.8-beta.41",
   "description": "Inputmask is a javascript library which creates an input mask.  Inputmask can run against vanilla javascript, jQuery and jqlite.",
   "main": "dist/inputmask.js",
   "files": [