Skip to content
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

Atom values obtained from Write-Output are incorrectly encoded #157

Closed
SpecterShell opened this issue Dec 13, 2024 · 14 comments · Fixed by #158
Closed

Atom values obtained from Write-Output are incorrectly encoded #157

SpecterShell opened this issue Dec 13, 2024 · 14 comments · Fixed by #158

Comments

@SpecterShell
Copy link

ConvertTo-Yaml is broken in the latest version (v0.4.8) when serializing a hashtable with atom values obtained from Write-Output. It is critical as values may be obtained from the functions that use Write-Output rather than return to return values.

For example, when assigning with Write-Output:

[ordered]@{a = Write-Output 'string'; b = Write-Output 1; c = Write-Output @{nested = $true}} | ConvertTo-Yaml
a:
  Length: 6
b: {}
c:
  nested: true

the string and the number were incorrectly encoded.

while without Write-Output:

[ordered]@{a = 'string'; b = 1; c = @{nested = $true}} | ConvertTo-Yaml
a: string
b: 1
c:
  nested: true

the values were correctly encoded.

@gabriel-samfira
Copy link
Member

Interesting. Will have a look this evening and push a fix.

@gabriel-samfira
Copy link
Member

gabriel-samfira commented Dec 14, 2024

Will also add a test case for this. Does this happen if you generate a variable from write-output and use that variable inside the hashtable before sending it to ConvertTo-Yaml?

Does this happen if you pass the hashtable as an argument to ConvertTo-Yaml or does it happen only when piping?

@SpecterShell
Copy link
Author

Will also add a test case for this. Does this happen if you generate a variable from write-output and use that variable inside the hashtable before sending it to ConvertTo-Yaml?

Yes

$a = Write-Output 'test'
@{a = $a} | ConvertTo-Yaml
a:
  Length: 4

Does this happen if you pass the hashtable as an argument to ConvertTo-Yaml or does it happen only when piping?

Yes

ConvertTo-Yaml @{a = Write-Output 'test'}
a:
  Length: 4

@gabriel-samfira
Copy link
Member

One last test. What is the result of:

ConvertTo-Yaml @{a = (Write-Output 'test')}

Note the parentheses around the Write-Output command.

@SpecterShell
Copy link
Author

ConvertTo-Yaml @{a = (Write-Output 'test')}

The same

❯ ConvertTo-Yaml @{a = (Write-Output 'test')}
a:
  Length: 4

@gabriel-samfira
Copy link
Member

gabriel-samfira commented Dec 14, 2024

PowerShell is dark and full of terrors. I think I may know why this is happening.

This will most likely work if we do an explicit cast like so:

ConvertTo-Yaml @{a = [string](Write-Output 'test')}

Will have a look once I get to a PC and push a fix. Thanks for testing.

@gabriel-samfira
Copy link
Member

Would you mind giving :

a try?

@gabriel-samfira
Copy link
Member

For context, this issue happened because when we call Write-Output, it will wrap whatever we pass to it, in a PSCustomObject. The new PSCustomObject type converter we are using, will try to list the properties of PSCustomObjects and append them to the mapping.

But in this case, we have a primitive type and a string wrapped in a PSCustomObject. Strings for example have only one "property", which is the length:

PS /> $aString = "test"     
PS /> $aString.psobject.Properties

MemberType      : Property
Value           : 4
IsSettable      : False
IsGettable      : True
TypeNameOfValue : System.Int32
Name            : Length
IsInstance      : True

If we pass this simple string to ConvertTo-Yaml, then all would be well, but if we wrap it in a PSCustomObject like so:

$aString = [pscustomobject]"test"

then the PSCustomObject type converter would be called, and we failed to take into account that some primitives and/or strings may be wrapped. So we recursed through their properties and ended up with the unfortunate behavior you reported. The above PR will attempt to unwrap objects and then serialize them.

@SpecterShell
Copy link
Author

Would you mind giving :

* [Fix serialization of PSCustomObject wrapped object #158](https://github.com/cloudbase/powershell-yaml/pull/158)

a try?

Doesn't seem to be fixed. I have ensured it is the modified module has been loaded.

❯ @{a = Write-Output 'test'} | ConvertTo-Yaml
a:
  Length: 4

@gabriel-samfira
Copy link
Member

gah! I forgot to add a test case for IDictionary types and only fixed the pscustomobject type. Please pull the latest commit and try again. The test cases here I think should cover everything.

Let me know if it works.

@SpecterShell
Copy link
Author

gah! I forgot to add a test case for IDictionary types and only fixed the pscustomobject type. Please pull the latest commit and try again. The test cases here I think should cover everything.

Let me know if it works.

It works. Thanks for your explanation and fixes!

❯ [pscustomobject]@{a = Write-Output 'test'} | ConvertTo-Yaml
a: test

❯ [ordered]@{a = Write-Output 'test'} | ConvertTo-Yaml
a: test

❯ @{a = Write-Output 'test'} | ConvertTo-Yaml
a: test

@gabriel-samfira
Copy link
Member

Thank you for your patience and for testing! I will publish a new release on Monday.

@gabriel-samfira
Copy link
Member

A new version has been released: https://www.powershellgallery.com/packages/powershell-yaml/0.4.9

A new release has been generated on GitHub: https://github.com/cloudbase/powershell-yaml/releases/tag/v0.4.9

Please test it out and let me know if all is well.

@SpecterShell
Copy link
Author

A new version has been released: powershellgallery.com/packages/powershell-yaml/0.4.9

A new release has been generated on GitHub: v0.4.9 (release)

Please test it out and let me know if all is well.

Works well for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants