@@ -46,6 +46,7 @@ function safeSelf() {
46
46
return scriptletGlobals . get ( 'safeSelf' ) ;
47
47
}
48
48
const safe = {
49
+ 'Error' : self . Error ,
49
50
'Object_defineProperty' : Object . defineProperty . bind ( Object ) ,
50
51
'RegExp' : self . RegExp ,
51
52
'RegExp_test' : self . RegExp . prototype . test ,
@@ -620,6 +621,7 @@ builtinScriptlets.push({
620
621
name : 'object-prune.fn' ,
621
622
fn : objectPrune ,
622
623
dependencies : [
624
+ 'matches-stack-trace.fn' ,
623
625
'pattern-to-regex.fn' ,
624
626
] ,
625
627
} ) ;
@@ -632,9 +634,10 @@ builtinScriptlets.push({
632
634
function objectPrune (
633
635
obj ,
634
636
rawPrunePaths ,
635
- rawNeedlePaths
637
+ rawNeedlePaths ,
638
+ stackNeedle = ''
636
639
) {
637
- if ( typeof rawPrunePaths !== 'string' ) { return ; }
640
+ if ( typeof rawPrunePaths !== 'string' ) { return obj ; }
638
641
const prunePaths = rawPrunePaths !== ''
639
642
? rawPrunePaths . split ( / + / )
640
643
: [ ] ;
@@ -648,6 +651,11 @@ function objectPrune(
648
651
log = console . log . bind ( console ) ;
649
652
reLogNeedle = patternToRegex ( rawNeedlePaths ) ;
650
653
}
654
+ if ( stackNeedle !== '' ) {
655
+ if ( matchesStackTrace ( patternToRegex ( stackNeedle ) , log ? '1' : 0 ) === false ) {
656
+ return obj ;
657
+ }
658
+ }
651
659
const findOwner = function ( root , path , prune = false ) {
652
660
let owner = root ;
653
661
let chain = path ;
@@ -802,6 +810,60 @@ function setLocalStorageItemCore(
802
810
}
803
811
}
804
812
813
+ /******************************************************************************/
814
+
815
+ builtinScriptlets . push ( {
816
+ name : 'matches-stack-trace.fn' ,
817
+ fn : matchesStackTrace ,
818
+ dependencies : [
819
+ 'safe-self.fn' ,
820
+ ] ,
821
+ } ) ;
822
+ function matchesStackTrace (
823
+ reNeedle ,
824
+ logLevel = 0
825
+ ) {
826
+ if ( reNeedle === undefined ) { return false ; }
827
+ const safe = safeSelf ( ) ;
828
+ const exceptionToken = getExceptionToken ( ) ;
829
+ const error = new safe . Error ( exceptionToken ) ;
830
+ const docURL = new URL ( self . location . href ) ;
831
+ docURL . hash = '' ;
832
+ // Normalize stack trace
833
+ const reLine = / ( .* ?@ ) ? ( \S + ) ( : \d + ) : \d + \) ? $ / ;
834
+ const lines = [ ] ;
835
+ for ( let line of error . stack . split ( / [ \n \r ] + / ) ) {
836
+ if ( line . includes ( exceptionToken ) ) { continue ; }
837
+ line = line . trim ( ) ;
838
+ const match = safe . RegExp_exec . call ( reLine , line ) ;
839
+ if ( match === null ) { continue ; }
840
+ let url = match [ 2 ] ;
841
+ if ( url . startsWith ( '(' ) ) { url = url . slice ( 1 ) ; }
842
+ if ( url === docURL . href ) {
843
+ url = 'inlineScript' ;
844
+ } else if ( url . startsWith ( '<anonymous>' ) ) {
845
+ url = 'injectedScript' ;
846
+ }
847
+ let fn = match [ 1 ] !== undefined
848
+ ? match [ 1 ] . slice ( 0 , - 1 )
849
+ : line . slice ( 0 , match . index ) . trim ( ) ;
850
+ if ( fn . startsWith ( 'at' ) ) { fn = fn . slice ( 2 ) . trim ( ) ; }
851
+ let rowcol = match [ 3 ] ;
852
+ lines . push ( ' ' + `${ fn } ${ url } ${ rowcol } :1` . trim ( ) ) ;
853
+ }
854
+ lines [ 0 ] = `stackDepth:${ lines . length - 1 } ` ;
855
+ const stack = lines . join ( '\t' ) ;
856
+ const r = safe . RegExp_test . call ( reNeedle , stack ) ;
857
+ if (
858
+ logLevel === '1' ||
859
+ logLevel === '2' && r ||
860
+ logLevel === '3' && ! r
861
+ ) {
862
+ safe . uboLog ( stack . replace ( / \t / g, '\n' ) ) ;
863
+ }
864
+ return r ;
865
+ }
866
+
805
867
/*******************************************************************************
806
868
807
869
Injectable scriptlets
@@ -931,8 +993,8 @@ builtinScriptlets.push({
931
993
fn : abortOnStackTrace ,
932
994
dependencies : [
933
995
'get-exception-token.fn' ,
996
+ 'matches-stack-trace.fn' ,
934
997
'pattern-to-regex.fn' ,
935
- 'safe-self.fn' ,
936
998
] ,
937
999
} ) ;
938
1000
// Status is currently experimental
@@ -942,64 +1004,21 @@ function abortOnStackTrace(
942
1004
logLevel = ''
943
1005
) {
944
1006
if ( typeof chain !== 'string' ) { return ; }
945
- const safe = safeSelf ( ) ;
946
1007
const reNeedle = patternToRegex ( needle ) ;
947
- const exceptionToken = getExceptionToken ( ) ;
948
- const ErrorCtor = self . Error ;
949
- const mustAbort = function ( err ) {
950
- let docURL = self . location . href ;
951
- const pos = docURL . indexOf ( '#' ) ;
952
- if ( pos !== - 1 ) {
953
- docURL = docURL . slice ( 0 , pos ) ;
954
- }
955
- // Normalize stack trace
956
- const reLine = / ( .* ?@ ) ? ( \S + ) ( : \d + ) : \d + \) ? $ / ;
957
- const lines = [ ] ;
958
- for ( let line of err . stack . split ( / [ \n \r ] + / ) ) {
959
- if ( line . includes ( exceptionToken ) ) { continue ; }
960
- line = line . trim ( ) ;
961
- const match = safe . RegExp_exec . call ( reLine , line ) ;
962
- if ( match === null ) { continue ; }
963
- let url = match [ 2 ] ;
964
- if ( url . startsWith ( '(' ) ) { url = url . slice ( 1 ) ; }
965
- if ( url === docURL ) {
966
- url = 'inlineScript' ;
967
- } else if ( url . startsWith ( '<anonymous>' ) ) {
968
- url = 'injectedScript' ;
969
- }
970
- let fn = match [ 1 ] !== undefined
971
- ? match [ 1 ] . slice ( 0 , - 1 )
972
- : line . slice ( 0 , match . index ) . trim ( ) ;
973
- if ( fn . startsWith ( 'at' ) ) { fn = fn . slice ( 2 ) . trim ( ) ; }
974
- let rowcol = match [ 3 ] ;
975
- lines . push ( ' ' + `${ fn } ${ url } ${ rowcol } :1` . trim ( ) ) ;
976
- }
977
- lines [ 0 ] = `stackDepth:${ lines . length - 1 } ` ;
978
- const stack = lines . join ( '\t' ) ;
979
- const r = safe . RegExp_test . call ( reNeedle , stack ) ;
980
- if (
981
- logLevel === '1' ||
982
- logLevel === '2' && r ||
983
- logLevel === '3' && ! r
984
- ) {
985
- safe . uboLog ( stack . replace ( / \t / g, '\n' ) ) ;
986
- }
987
- return r ;
988
- } ;
989
1008
const makeProxy = function ( owner , chain ) {
990
1009
const pos = chain . indexOf ( '.' ) ;
991
1010
if ( pos === - 1 ) {
992
1011
let v = owner [ chain ] ;
993
1012
Object . defineProperty ( owner , chain , {
994
1013
get : function ( ) {
995
- if ( mustAbort ( new ErrorCtor ( exceptionToken ) ) ) {
996
- throw new ReferenceError ( exceptionToken ) ;
1014
+ if ( matchesStackTrace ( reNeedle , logLevel ) ) {
1015
+ throw new ReferenceError ( getExceptionToken ( ) ) ;
997
1016
}
998
1017
return v ;
999
1018
} ,
1000
1019
set : function ( a ) {
1001
- if ( mustAbort ( new ErrorCtor ( exceptionToken ) ) ) {
1002
- throw new ReferenceError ( exceptionToken ) ;
1020
+ if ( matchesStackTrace ( reNeedle , logLevel ) ) {
1021
+ throw new ReferenceError ( getExceptionToken ( ) ) ;
1003
1022
}
1004
1023
v = a ;
1005
1024
} ,
@@ -1114,21 +1133,23 @@ builtinScriptlets.push({
1114
1133
// - Add support for "remove everything if needle matches" case
1115
1134
function jsonPrune (
1116
1135
rawPrunePaths = '' ,
1117
- rawNeedlePaths = ''
1136
+ rawNeedlePaths = '' ,
1137
+ stackNeedle = ''
1118
1138
) {
1119
1139
JSON . parse = new Proxy ( JSON . parse , {
1120
1140
apply : function ( target , thisArg , args ) {
1121
1141
return objectPrune (
1122
1142
Reflect . apply ( target , thisArg , args ) ,
1123
1143
rawPrunePaths ,
1124
- rawNeedlePaths
1144
+ rawNeedlePaths ,
1145
+ stackNeedle
1125
1146
) ;
1126
1147
} ,
1127
1148
} ) ;
1128
1149
Response . prototype . json = new Proxy ( Response . prototype . json , {
1129
1150
apply : function ( target , thisArg , args ) {
1130
1151
return Reflect . apply ( target , thisArg , args ) . then ( o =>
1131
- objectPrune ( o , rawPrunePaths , rawNeedlePaths )
1152
+ objectPrune ( o , rawPrunePaths , rawNeedlePaths , stackNeedle )
1132
1153
) ;
1133
1154
} ,
1134
1155
} ) ;
0 commit comments