Forced single-quoted or literal style emits raw NUL and U+0001

Open
#1,506 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

  • #1508 by @himanshu748 — closed without merging

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
cpp
Domain
data

Research direction

The bug is in src/emitterutils.cpp: IsValidSingleQuotedScalar and IsValidLiteralScalar lack a non-printable check (both carry a TODO), so the double-quoted fallback never runs. Read how the emitter picks a style, then reproduce with the snippet in the issue and inspect the bytes with xxd. Done when NUL and U+0001 under SingleQuoted or Literal produce escaped output, and the Auto and DoubleQuoted results are unchanged. Closed PR #1508 was not merged, so check why before starting.

Written by the indexing model from the issue text.

Description

On master 1e0876c, forcing YAML::SingleQuoted or YAML::Literal on a string containing NUL (U+0000) or U+0001 writes the raw character into the output. Auto and DoubleQuoted escape them correctly.

YAML 1.2.2 section 5.1: "On output, a YAML processor must only produce only characters in this printable subset. Characters outside this set must be presented using escape sequences." NUL and U+0001 are outside that set, and the JSON-compatibility allowance for quoted scalars only covers non-C0 characters. TAB, LF, CR and NEL are allowed and not reported here. PyYAML and a ruamel.yaml loader set to YAML 1.2 both reject the raw output.

The repro uses UTF-8 strings and the default UTF-8 output; the reported NUL/U+0001 are scalar content characters, not zero bytes in UTF-16/UTF-32 encoding.

Repro: emit "a" + c + "b" for c in {0x00, 0x01} with Auto, SingleQuoted, Literal and DoubleQuoted, then inspect with xxd.

#include <yaml-cpp/yaml.h>
#include <fstream>
#include <string>

int main() {
    const char values[] = {char(0x00), char(0x01)};
    const YAML::EMITTER_MANIP styles[] = {
        YAML::Auto, YAML::SingleQuoted, YAML::Literal, YAML::DoubleQuoted
    };
    const char* names[] = {"auto", "single", "literal", "double"};
    for (unsigned i = 0; i < 2; ++i) {
        for (unsigned j = 0; j < 4; ++j) {
            const std::string s = std::string("a") + values[i] + "b";
            const std::string path = std::to_string(i) + "-" + names[j] + ".yaml";
            std::ofstream f(path, std::ios::binary);
            YAML::Emitter e(f);
            e << styles[j] << s;
        }
    }
}

Cause: IsValidSingleQuotedScalar and IsValidLiteralScalar in src/emitterutils.cpp have no non-printable check (both carry a TODO), so the double-quoted fallback never triggers.

Minor note: U+007F (DEL) is written raw in every style. It's outside c-printable, though the grammar's JSON-compatibility rule admits it inside quoted scalars, and section 5.1 recommends escaping non-printables even there. I'm not claiming quoted DEL is invalid syntax; the raw literal-style case is outside the literal character set. Parsers above also reject it.

I used AI tools to find and reproduce this; I reviewed it myself.

Dominant language
C++
Stars
6.1k
Forks
2.2k
Avg merge
22h 2m
Merged PRs (30d)
1

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from jbeder/yaml-cpp

All issues in jbeder/yaml-cpp

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.