@@ -59,6 +59,36 @@ function safeSelf() {
5959 if ( `${ args [ 0 ] } ` === '' ) { return ; }
6060 this . log ( '[uBO]' , ...args ) ;
6161 } ,
62+ 'initPattern' : function ( pattern , options = { } ) {
63+ if ( pattern === '' ) {
64+ return { matchAll : true } ;
65+ }
66+ const expect = ( options . canNegate && pattern . startsWith ( '!' ) === false ) ;
67+ if ( expect === false ) {
68+ pattern = pattern . slice ( 1 ) ;
69+ }
70+ const match = / ^ \/ ( .+ ) \/ ( [ g i m s u ] * ) $ / . exec ( pattern ) ;
71+ if ( match !== null ) {
72+ return {
73+ re : new this . RegExp (
74+ match [ 1 ] ,
75+ match [ 2 ] || options . flags
76+ ) ,
77+ expect,
78+ } ;
79+ }
80+ return {
81+ re : new this . RegExp ( pattern . replace (
82+ / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ,
83+ options . flags
84+ ) ,
85+ expect,
86+ } ;
87+ } ,
88+ 'testPattern' : function ( details , haystack ) {
89+ if ( details . matchAll ) { return true ; }
90+ return this . RegExp_test . call ( details . re , haystack ) === details . expect ;
91+ } ,
6292 } ;
6393 scriptletGlobals . set ( 'safeSelf' , safe ) ;
6494 return safe ;
@@ -636,7 +666,7 @@ function objectPrune(
636666 obj ,
637667 rawPrunePaths ,
638668 rawNeedlePaths ,
639- stackNeedle = ''
669+ stackNeedleDetails = { matchAll : true }
640670) {
641671 if ( typeof rawPrunePaths !== 'string' ) { return obj ; }
642672 const prunePaths = rawPrunePaths !== ''
@@ -657,9 +687,8 @@ function objectPrune(
657687 log = console . log . bind ( console ) ;
658688 reLogNeedle = patternToRegex ( rawNeedlePaths ) ;
659689 }
660- if ( stackNeedle !== '' ) {
661- const reStackNeedle = patternToRegex ( stackNeedle ) ;
662- if ( matchesStackTrace ( reStackNeedle , extraArgs . logstack ) === false ) {
690+ if ( stackNeedleDetails . matchAll !== true ) {
691+ if ( matchesStackTrace ( stackNeedleDetails , extraArgs . logstack ) === false ) {
663692 return obj ;
664693 }
665694 }
@@ -828,10 +857,9 @@ builtinScriptlets.push({
828857 ] ,
829858} ) ;
830859function matchesStackTrace (
831- reNeedle ,
860+ needleDetails ,
832861 logLevel = 0
833862) {
834- if ( reNeedle === undefined ) { return false ; }
835863 const safe = safeSelf ( ) ;
836864 const exceptionToken = getExceptionToken ( ) ;
837865 const error = new safe . Error ( exceptionToken ) ;
@@ -861,7 +889,7 @@ function matchesStackTrace(
861889 }
862890 lines [ 0 ] = `stackDepth:${ lines . length - 1 } ` ;
863891 const stack = lines . join ( '\t' ) ;
864- const r = safe . RegExp_test . call ( reNeedle , stack ) ;
892+ const r = safe . testPattern ( needleDetails , stack ) ;
865893 if (
866894 logLevel === 1 ||
867895 logLevel === 2 && r ||
@@ -1004,29 +1032,30 @@ builtinScriptlets.push({
10041032 'get-extra-args.fn' ,
10051033 'matches-stack-trace.fn' ,
10061034 'pattern-to-regex.fn' ,
1035+ 'safe-self.fn' ,
10071036 ] ,
10081037} ) ;
1009- // Status is currently experimental
10101038function abortOnStackTrace (
10111039 chain = '' ,
10121040 needle = ''
10131041) {
10141042 if ( typeof chain !== 'string' ) { return ; }
1015- const reNeedle = patternToRegex ( needle ) ;
1043+ const safe = safeSelf ( ) ;
1044+ const needleDetails = safe . initPattern ( needle , { canNegate : true } ) ;
10161045 const extraArgs = getExtraArgs ( Array . from ( arguments ) , 2 ) ;
10171046 const makeProxy = function ( owner , chain ) {
10181047 const pos = chain . indexOf ( '.' ) ;
10191048 if ( pos === - 1 ) {
10201049 let v = owner [ chain ] ;
10211050 Object . defineProperty ( owner , chain , {
10221051 get : function ( ) {
1023- if ( matchesStackTrace ( reNeedle , extraArgs . log ) ) {
1052+ if ( matchesStackTrace ( needleDetails , extraArgs . log ) ) {
10241053 throw new ReferenceError ( getExceptionToken ( ) ) ;
10251054 }
10261055 return v ;
10271056 } ,
10281057 set : function ( a ) {
1029- if ( matchesStackTrace ( reNeedle , extraArgs . log ) ) {
1058+ if ( matchesStackTrace ( needleDetails , extraArgs . log ) ) {
10301059 throw new ReferenceError ( getExceptionToken ( ) ) ;
10311060 }
10321061 v = a ;
@@ -1132,6 +1161,7 @@ builtinScriptlets.push({
11321161 fn : jsonPrune ,
11331162 dependencies : [
11341163 'object-prune.fn' ,
1164+ 'safe-self.fn' ,
11351165 ] ,
11361166} ) ;
11371167// When no "prune paths" argument is provided, the scriptlet is
@@ -1145,14 +1175,16 @@ function jsonPrune(
11451175 rawNeedlePaths = '' ,
11461176 stackNeedle = ''
11471177) {
1178+ const safe = safeSelf ( ) ;
1179+ const stackNeedleDetails = safe . initPattern ( stackNeedle , { canNegate : true } ) ;
11481180 const extraArgs = Array . from ( arguments ) . slice ( 3 ) ;
11491181 JSON . parse = new Proxy ( JSON . parse , {
11501182 apply : function ( target , thisArg , args ) {
11511183 return objectPrune (
11521184 Reflect . apply ( target , thisArg , args ) ,
11531185 rawPrunePaths ,
11541186 rawNeedlePaths ,
1155- stackNeedle ,
1187+ stackNeedleDetails ,
11561188 ...extraArgs
11571189 ) ;
11581190 } ,
@@ -1164,7 +1196,7 @@ function jsonPrune(
11641196 o ,
11651197 rawPrunePaths ,
11661198 rawNeedlePaths ,
1167- stackNeedle ,
1199+ stackNeedleDetails ,
11681200 ...extraArgs
11691201 )
11701202 ) ;
0 commit comments