@@ -449,6 +449,60 @@ define(function (require, exports, module) {
449449 }
450450 }
451451
452+ /**
453+ * to validate whether a lorem abbreviation is safe to expand without crashing the app
454+ * so there are many problematic patters like lorem1000000, li*10>lorem50000 etc
455+ * we put a max constraint of 100000, above which we don't show the code hint at all
456+ *
457+ * @param {String } word - the abbreviation to validate
458+ * @returns {Boolean } - true if safe to expand otherwise false
459+ */
460+ function isLoremSafeToExpand ( word ) {
461+ const MAX_LOREM_WORDS = 100000 ;
462+
463+ // extract all lorem word counts (handles lorem123, loremru123, lorem10-200, etc.)
464+ const loremPattern = / l o r e m [ a - z ] * ( \d + ) (?: - ( \d + ) ) ? / gi;
465+ const loremMatches = [ ...word . matchAll ( loremPattern ) ] ;
466+ // if no lorem is there, it means its safe
467+ if ( loremMatches . length === 0 ) {
468+ return true ;
469+ }
470+
471+ // find the maximum lorem word count
472+ let maxLoremCount = 0 ;
473+ for ( const match of loremMatches ) {
474+ const count1 = parseInt ( match [ 1 ] ) || 0 ;
475+ // for ranges like lorem10-200, take the second (max) number
476+ const count2 = match [ 2 ] ? parseInt ( match [ 2 ] ) : count1 ;
477+ const maxCount = Math . max ( count1 , count2 ) ;
478+ maxLoremCount = Math . max ( maxLoremCount , maxCount ) ;
479+ }
480+
481+ // if any single lorem exceeds the limit, for ex: `lorem1000000` or `lorem5000000`
482+ if ( maxLoremCount > MAX_LOREM_WORDS ) {
483+ return false ;
484+ }
485+
486+ // handle the multiplication cases, for ex: `li*10>lorem500000`
487+ const multiplierPattern = / \* ( \d + ) / g;
488+ const multipliers = [ ...word . matchAll ( multiplierPattern ) ] . map ( m => parseInt ( m [ 1 ] ) ) ;
489+
490+ // if no multipliers, just check the max lorem count
491+ if ( multipliers . length === 0 ) {
492+ return true ;
493+ }
494+
495+ // calc total multiplication factor (capped at 400 due to maxRepeat)
496+ const totalMultiplier = Math . min (
497+ multipliers . reduce ( ( product , num ) => product * num , 1 ) ,
498+ 400
499+ ) ;
500+
501+ // worst case: max lorem count × total multiplier
502+ const estimatedTotal = maxLoremCount * totalMultiplier ;
503+
504+ return estimatedTotal <= MAX_LOREM_WORDS ;
505+ }
452506
453507 /**
454508 * This function checks whether the abbreviation can be expanded or not.
@@ -496,6 +550,12 @@ define(function (require, exports, module) {
496550 positiveSymbols . some ( symbol => word . includes ( symbol ) ) ||
497551 word . toLowerCase ( ) . includes ( 'lorem' )
498552 ) {
553+ // we need to check if this is safe to expand because cases like
554+ // `lorem100000000` will crash phoenix
555+ // read functions jsdoc for more details
556+ if ( word . toLowerCase ( ) . includes ( 'lorem' ) && ! isLoremSafeToExpand ( word ) ) {
557+ return null ;
558+ }
499559
500560 try {
501561 return expandAbbr ( word , { syntax : "html" , type : "markup" , maxRepeat : 400 } ) ; // expanded
0 commit comments