Skip to content

CF-3932 : Stop HTML-escaping <, >, & in -o json output#3398

Open
Paras Negi (paras-negi-flink) wants to merge 2 commits into
mainfrom
cf-3932-json-no-html-escape
Open

CF-3932 : Stop HTML-escaping <, >, & in -o json output#3398
Paras Negi (paras-negi-flink) wants to merge 2 commits into
mainfrom
cf-3932-json-no-html-escape

Conversation

@paras-negi-flink

@paras-negi-flink Paras Negi (paras-negi-flink) commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Release Notes

Breaking Changes

  • NONE

New Features

  • NONE

Bug Fixes

  • -o json output no longer HTML-escapes <, >, and &, keeping readable text such as SQL statements intact.

Checklist

  • I have successfully built and used a custom CLI binary, without linter issues from this PR.
  • I have clearly specified in the What section below whether this PR applies to Confluent Cloud, Confluent Platform, or both.
  • I have attached manual CLI verification results or screenshots in the Test & Review section below.
  • I have added appropriate CLI integration or unit tests for any new or updated commands and functionality.
  • I confirm that this PR introduces no breaking changes or backward compatibility issues.
  • I have indicated the potential customer impact if something goes wrong in the Blast Radius section below.
  • I have put checkmarks below confirming that the feature associated with this PR is enabled in:
    • Confluent Cloud prod
    • Confluent Cloud stag
    • Confluent Platform
    • Check this box if the feature is enabled for certain organizations only

What

Both Confluent Cloud and Confluent Platform (shared output package used by every command).

  • Go's encoding/json HTML-escapes <, >, and & by default. Both -o json serializers (pkg/output/serialized_output.go, pkg/output/table.go) used json.Marshal, mangling any JSON output with those characters (most visibly Flink SQL statements).
  • Fix: a shared marshalJSON helper (json.Encoder with SetEscapeHTML(false)) that both serializers use. Drop-in for json.Marshal; YAML path untouched.

Blast Radius

  • -o json for every command now emits <, >, & verbatim instead of their escaped Unicode sequences. Both forms are valid JSON and decode identically, so parsers are unaffected; exact-string matching against the old escaped form would need to match the raw characters.
  • -o yaml and human/table output unchanged.

References

Test & Review

Environment: local CMF cmf-app 2.4-SNAPSHOT (HTTP, --cmf.k8s.enabled=false); CLI built from this branch vs released confluent v4.54.0.

Manual CLI validation: attached in the comment below.

Copilot AI review requested due to automatic review settings July 6, 2026 06:22
@confluent-cla-assistant

Copy link
Copy Markdown

🎉 All Contributor License Agreements have been signed. Ready to merge.
Please push an empty commit if you would like to re-run the checks to verify CLA status for all contributors.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the shared pkg/output JSON serialization path so -o json output no longer HTML-escapes <, >, and &, preserving readability for content like SQL statements and placeholder emails.

Changes:

  • Replaced json.Marshal usage with a shared marshalJSON helper that disables HTML escaping.
  • Updated Table JSON output to use the shared helper.
  • Added/updated tests and refreshed one affected integration golden (api-key list -o json).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
test/fixtures/output/api-key/7.golden Updates expected JSON fixture to reflect unescaped <...> values.
pkg/output/table.go Switches table JSON serialization to the shared marshalJSON helper.
pkg/output/table_test.go Adds unit tests ensuring <, >, & are emitted verbatim in JSON output.
pkg/output/serialized_output.go Introduces marshalJSON helper using json.Encoder with SetEscapeHTML(false).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/output/serialized_output.go Outdated
@paras-negi-flink

Copy link
Copy Markdown
Contributor Author

Manual CLI validation

Local CMF (cmf-app 2.4-SNAPSHOT, HTTP, --cmf.k8s.enabled=false). Same command, released CLI vs this PR; the statement-default value carries <, >, and &.

Before — released confluent v4.54.0

$ confluent --url $CMF flink environment create demo --kubernetes-namespace default \
    --statement-defaults '{"interactive":{"flinkConfiguration":{"note":"1 < 2 && 3 > 2"}}}' -o json
{
  "secrets": {},
  "name": "cf3932-cmt-before",
  "created_time": "2026-07-07T05:04:48.262168Z",
  "updated_time": "2026-07-07T05:04:48.262169Z",
  "kubernetesNamespace": "default",
  "statementDefaults": {
    "interactive": {
      "flinkConfiguration": {
        "note": "1 \u003c 2 \u0026\u0026 3 \u003e 2"
      }
    }
  }
}

After — this PR

$ confluent --url $CMF flink environment create demo --kubernetes-namespace default \
    --statement-defaults '{"interactive":{"flinkConfiguration":{"note":"1 < 2 && 3 > 2"}}}' -o json
{
  "secrets": {},
  "name": "cf3932-cmt-after",
  "created_time": "2026-07-07T05:04:48.68836Z",
  "updated_time": "2026-07-07T05:04:48.68836Z",
  "kubernetesNamespace": "default",
  "statementDefaults": {
    "interactive": {
      "flinkConfiguration": {
        "note": "1 < 2 && 3 > 2"
      }
    }
  }
}

@paras-negi-flink
Paras Negi (paras-negi-flink) marked this pull request as ready for review July 7, 2026 06:06
@paras-negi-flink
Paras Negi (paras-negi-flink) requested a review from a team as a code owner July 7, 2026 06:06
@sonarqube-confluent

Copy link
Copy Markdown

Comment thread pkg/output/table.go
switch t.format {
default:
out, err := json.Marshal(v)
out, err := marshalJSON(v)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The intention and solution is straightforward, but these 2 functions are high blast-radius functions, and we need to pay additional attention before touching these.

For example, can you please evaluate and check the impact on these Confluent Cloud commands that are still using the old marshal function? What should be updated if we make changes to printCore()?
https://github.com/confluentinc/cli/blob/main/internal/schema-registry/command_configuration_describe.go#L80-L110


// marshalJSON marshals v to JSON without HTML-escaping <, >, and & (which
// encoding/json does by default), keeping text like SQL statements readable.
func marshalJSON(v any) ([]byte, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we have the similar issue to yaml format?

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 this pull request may close these issues.

4 participants