@@ -571,19 +571,35 @@ function extractAuthType(blockContent: string): 'oauth' | 'api-key' | 'none' {
571571 return 'none'
572572}
573573
574+ /**
575+ * Length-preserving copy of `content` with string-literal and comment
576+ * interiors blanked out, so delimiter scans cannot be tripped by braces or
577+ * quotes inside them. Indices into the result line up with indices into
578+ * `content`.
579+ */
580+ function blankStringsAndComments ( content : string ) : string {
581+ return content . replace (
582+ / ( [ ' " ` ] ) (?: \\ [ \s \S ] | (? ! \1) [ ^ \\ ] ) * \1| \/ \/ [ ^ \n ] * | \/ \* [ \s \S ] * ?\* \/ / g,
583+ ( match ) => match [ 0 ] + match . slice ( 1 , - 1 ) . replace ( / [ ^ \n ] / g, ' ' ) + match [ match . length - 1 ]
584+ )
585+ }
586+
574587/**
575588 * Extract the OAuth service id from the block's `oauth-input` credential
576589 * subBlock. Scoped to that subBlock's object literal so `serviceId` fields on
577- * other subBlocks (e.g. file selectors) are never picked up.
590+ * other subBlocks (e.g. file selectors) are never picked up. Brace matching
591+ * runs on a blanked copy of the content so string literals and comments
592+ * containing braces cannot skew it.
578593 */
579594function extractOAuthServiceId ( blockContent : string ) : string | undefined {
580595 const typeMatch = / t y p e \s * : \s * [ ' " ] o a u t h - i n p u t [ ' " ] / . exec ( blockContent )
581596 if ( ! typeMatch ) return undefined
582597
598+ const scannable = blankStringsAndComments ( blockContent )
583599 let depth = 0
584600 let objectStart = - 1
585601 for ( let i = typeMatch . index ; i >= 0 ; i -- ) {
586- const char = blockContent [ i ]
602+ const char = scannable [ i ]
587603 if ( char === '}' ) depth ++
588604 else if ( char === '{' ) {
589605 if ( depth === 0 ) {
@@ -595,7 +611,7 @@ function extractOAuthServiceId(blockContent: string): string | undefined {
595611 }
596612 if ( objectStart === - 1 ) return undefined
597613
598- const objectEnd = findMatchingClose ( blockContent , objectStart )
614+ const objectEnd = findMatchingClose ( scannable , objectStart )
599615 if ( objectEnd === - 1 ) return undefined
600616 const subBlockContent = blockContent . substring ( objectStart , objectEnd )
601617 return / s e r v i c e I d \s * : \s * [ ' " ] ( [ ^ ' " ] + ) [ ' " ] / . exec ( subBlockContent ) ?. [ 1 ]
0 commit comments