Skip to content

Conversation

czechboy0
Copy link
Contributor

@czechboy0 czechboy0 commented May 26, 2023

Motivation

When the content type text/plain is used, we had a bug where we were encoding the text using Codable into a JSON fragment, i.e. hello -> "hello" (note the added quotes), which is incorrect. We should be using LosslessStringConvertible for primitive types, so that hello is sent as hello (without the quotes).

Modifications

Fixed the body conversion methods to use the string conversion if possible, and only use the Codable implementation for complex types.

Result

When content type is text/plain (and other plain text variants), hello is sent as hello, not "hello".

Test Plan

Updated unit tests and added new ones to cover these cases.

@czechboy0 czechboy0 requested a review from simonjbeaumont May 26, 2023 12:03
Copy link
Collaborator

@simonjbeaumont simonjbeaumont left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find! I think we can remove some of the optional and force casting though.

@czechboy0 czechboy0 merged commit 4b964d4 into apple:main May 26, 2023
@czechboy0 czechboy0 deleted the hd-fix-encoding-plain-text-bodies branch May 26, 2023 16:17
let decoded: T
if let myType = T.self as? _StringParameterConvertible.Type {
guard
let stringValue = String(data: data, encoding: .utf8),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid String(data:encoding:), especially in networked software as it has 2 failure modes (return nil or insert replacement characters for invalid UTF8 -- which one it chooses depends on what's broken).
The correct and faster way is String(decoding: data, as: UTF8.self) which also doesn't require Foundation and is not fallible

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, broke out into apple/swift-openapi-generator#42

let body = transform(value)
headerFields.add(name: "content-type", value: body.contentType)
if let value = value as? _StringParameterConvertible {
guard let data = value.description.data(using: .utf8) else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, the correct and fast way is Data(value.utf8) which can't fail and is faster. You should audit your code to make sure String(data and data(using aren't present

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 semver/patch No public API change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants