8000 Quoting in subexpressions in string literals is quite confused · Issue #17887 · PowerShell/PowerShell · GitHub
[go: up one dir, main page]

Skip to content

Quoting in subexpressions in string literals is quite confused #17887

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
5 tasks done
jporkka opened this issue Aug 12, 2022 · 9 comments
Open
5 tasks done

Quoting in subexpressions in string literals is quite confused #17887

jporkka opened this issue Aug 12, 2022 · 9 comments
Labels
Issue-Bug Issue has been identified as a bug in the product Needs-Triage The issue is new and needs to be triaged by a work group. WG-Engine core PowerShell engine, interpreter, and runtime

Comments

@jporkka
Copy link
jporkka commented Aug 12, 2022

Prerequisites

Steps to reproduce

I was attempting to write a function to escape a string to correctly print a string for generated powershell code.
The rules for escaping double-quotes inside a double-quoted string are obscure at best, and quite broken depending on your point of view.

The coloring in the powershell console appears to mostly match the code behavior, but tools like VSCode do not match powershell behavior.

Here is a block of code demonstrating a number of issues
#1: Escaping isn't required, but sometimes it is allowed
#2: To have double-quotes inside an embedded string requires double backticks, yet only a single backtick is necessary for things like newline.
#3: Parans inside a nested string confuse powershell
#3: Doubling nested double-quotes seems to escape them, but there is a lot of wiggle room for how many double quotes is needed.

##########################################################################################
Write-Output "Begin Sample 1"
# Inside a "$()" subexpression it turns out you don't need to escape quotes
$b = "'$($a.replace("'", "''"))'"

# Oddly, PowerShell accepts the back-tick double-quote (`") though...
"...$("hello")..."     # OK - as expected, escaping inner quotes isn't necessary

# Yet, escaping is accepted by powershell, but confuses VSCode coloring.
"...$(`"hello")..."    # OK, VSCode miscolors "hello" as not a string and open "(" as mismatched
"...$(`"hello`")..."   # OK, VSCode miscolors "hello" as not a string

# Escaping here even produces a newline character
"...$(`"hello`n")..."  # Treats `n as newline.

Write-Output "End of test 1"

##########################################################################################
Write-Output "Begin Sample 2"
# To have embedded double-quotes inside the subexpression it is necessary to use Double-BackTick
# Weirdly, doubling the back-ticks appears to behave like a single back-tick outside of a subexpression by escaping the double-quote.
Write-Output "$(`"hello``"...``" ")" # Prints hello"...". Also confuses VSCode.

# Write-Output "$("hello`"...`" ")" # Fails: You must provide a value expression following the '..' operator.

Write-Output $("hello`"...`" ") # Prints hello"..."


##########################################################################################
Write-Output "Begin Sample 3"
# Here, Powershell interprets the closing paran, inside quotes, as being not quoted.
# this does not compile - even though the error message appears to correctly color the "hello)" portion as a string.
# Also, back-ticks don't seem to be able to escape nested parans.
Write-Output "$( Write-Output "hello)" )"  # Does not run: The string is missing the terminator: ".
Write-Output "$( Write-Output "(hello)" )" # Prints  (hello)

##########################################################################################
Write-Output "Begin Sample 4"
# Funky handling of multiple double-quotes.
# 0 to 2 double quotes: Not output
# 3 to 6 double quotes: Single double-quote
# 7 to 10 double quotes: Two double-quotes
# 11 to 14 double quotes: Three double-quotes
# For 2, 5, 10 and 14 the closing ")" doesn't print either.
Write-Output "$( Write-Output " 2 hell(o"" 5+5)")"             # Prints:  2 hell(o 5+5      
Write-Output "$( Write-Output " 3 hell(o""" 5+5)")"            # Prints:  3 hell(o" 5+5)    
Write-Output "$( Write-Output " 4 hell(o"""" 5+5)")"           # Prints:  4 hell(o" 5+5)    
Write-Output "$( Write-Output " 5 hell(o""""" 5+5)")"          # Prints:  5 hell(o" 5+5     
Write-Output "$( Write-Output " 7 hell(o""""""" 5+5)")"        # Prints:  7 hell(o"" 5+5)   
Write-Output "$( Write-Output "10 hell(o"""""""""" 5+5)")"     # Prints: 10 hell(o"" 5+5    
Write-Output "$( Write-Output "11 hell(o""""""""""" 5+5)")"    # Prints: 11 hell(o""" 5+5)  -- Also, this confuses VSCode coloring.
Write-Output "$( Write-Output "12 hell(o"""""""""""" 5+5)")"   # Prints: 12 hell(o""" 5+5)  
Write-Output "$( Write-Output "14 hell(o"""""""""""""" 5+5)")" # Prints: 14 hell(o""" 5+5   

# More samples of bad handling of nested parans.
# In both cases there are no errors, but the text after the close ")" is dropped.
Write-Output "$(Write-Output "he(llo" )after )"                        # Prints: he(llo
Write-Output "$(Write-Output "he(llo" ) after$(Write-Output more)"string)"     # Prints: he(llo -- And VSCode color is confused: " Extra quote to fix VSCode coloring

Write-Output "End"

Expected behavior

Inside a "$()" subexpression, I would expect to have to escape double quotes
"$(`"hello`")"
But, there appears to be some special case so that isn't necessary.

The problem is that this special case only works as expected in trivial cases like the above.

Actual behavior

it is difficult to determine how to properly escape a string in a nested expression.
Sometimes backticks are not needed, but accepted.
Sometimes they are required.

Also, parans inside a nested string are interpreted as not inside a string - they interfere with paran outside of the subexpression.

Error details

Various, including:
You must provide a value expression following the '..' operator.
The string is missing the terminator: ".

Environment data

Name                           Value
----                           -----
PSVersion                      7.2.6
PSEdition                      Core
GitCommitId                    7.2.6
OS                             Microsoft Windows 10.0.19044
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

image

image

image

VSCode
image

image
image

@jporkka jporkka added the Needs-Triage The issue is new and needs to be triaged by a work group. label Aug 12, 2022
@237dmitry
Copy link
237dmitry commented Aug 12, 2022
Write-Output '$( Write-Output "hello)" hello) ''hello)'' )'
Write-Output $( Write-Output '"hello)" hello) ''hello)''' )

@StevenBucher98
Copy link
Collaborator
StevenBucher98 commented Aug 15, 2022

Thanks for the issue @jporkka! When you say VSCode can you be more specific? Are you using the PowerShell Extension terminal or the pwsh terminal? After testing seems the miscoloring happens on both.

cc @andschwa

@StevenBucher98
Copy link
Collaborator

Also is related to: #4543

@StevenBucher98 StevenBucher98 added Issue-Bug Issue has been identified as a bug in the product WG-Engine core PowerShell engine, interpreter, and runtime labels Aug 15, 2022
@jporkka
Copy link
Author
jporkka commented Oct 11, 2022 via email

Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

1 similar comment
Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

@microsoft-github-policy-service microsoft-github-policy-service bot added Resolution-No Activity Issue has had no activity for 6 months or more labels Nov 15, 2023
Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

Copy link
Contributor

This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

@cow1337killer3
Copy link

Yea this is definitely a bug.

$s = "    `"    "
$s2 = "   $("    `"    ")   " // Doesn't parse

The escapes are being parsed before the sub expression. A sub expression should be completely independent of the string it's contained in.

@StevenBucher98 StevenBucher98 reopened this May 2, 2024
@StevenBucher98 StevenBucher98 removed the Resolution-No Activity Issue has had no activity for 6 months or more label May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Bug Issue has been identified as a bug in the product Needs-Triage The issue is new and needs to be triaged by a work group. WG-Engine core PowerShell engine, interpreter, and runtime
Projects
None yet
Development

No branches or pull requests

4 participants
0