ddn.data.cf
CF - Configuration File Format Parser and Writer
This module provides a complete implementation of CF v1.0 specification, including a lexer, parser, and writer. The parser produces CdmDocument from the CDM (Configuration Data Model) for full roundtrip fidelity.
CF is a human-friendly configuration format that supports:
- Objects with key-value pairs using = or : separators
- Arrays with [...] syntax
- Strings: double, single, triple-quoted, and raw
- Numbers: integers - decimal, hex, octal, binary - and floats
- Booleans: true and false
- Null: null
- Special floats: inf, -inf, nan
- Temporal types: dates, times, datetimes
- Comments: hash, double-slash, and block comments
- Include directive for file inclusion
- Environment variable substitution
Example:
import ddn.data.cf;
// Parse CF source
auto doc = parseCf(`
name = "myapp"
version = 1
server {
host = "localhost"
port = 8080
}
`);
// Access values via CDM
assert(doc.root["name"].as!string == "myapp");
// Write back to CF
string output = toCf(doc);Security_Considerations: The CF parser includes features that can have security implications:
Include Directive:- By default,
enableIncludesisfalseto prevent unintended file access. - When enabled, you MUST provide a
fileReaderdelegate that controlswhich files can be read.
- Path traversal attacks are mitigated by normalizing paths before validation
and rejecting `..` sequences when
allowParentTraversalis false (default). - Absolute paths are rejected by default (
allowAbsolutePaths = false). - Circular includes are detected and rejected.
- Include depth is limited to
MAX_INCLUDE_DEPTH(32) to prevent stack overflow.
- By default,
enableEnvSubstitutionistruebut requires anenvReaderdelegate to actually resolve variables.
- Environment variable expansion is limited to
MAX_ENV_EXPANSION_SIZEbytesto prevent denial-of-service via large expansions.
- Without an
envReader,${VAR}references resolve to empty strings.
CfParserConfig cfg;
cfg.enableIncludes = false; // Disable unless needed
cfg.enableEnvSubstitution = false; // Disable unless needed
auto doc = parseCf(untrustedInput, "input.cf", cfg);Copyright
Types 11
Token types for CF lexical analysis.
These represent all possible token kinds that the lexer can produce, following the CF v1.0 specification.
Source location information.
Tracks the position of tokens and nodes within the source file for error reporting and roundtrip preservation.
size_t lineLine number (1-based)size_t colColumn number (1-based)string sourceSource filename or identifierBase exception class for CF parsing and processing errors.
Includes source location information for precise error reporting.
Location locationSource location where the error occurredLexer for CF source text.
Converts CF source into a stream of tokens, implementing the input range interface. Comments are preserved as tokens to support the roundtrip-preserving document model.
string sourcestring filenamesize_t possize_t linesize_t colToken currentTokenbool initializedbool eofReturnedbool looksLikeTemporalStart() @safe pureChecks if position looks like start of temporal literal.TokenType classifyKeyword(string text) @safe pureClassifies a text as keyword or identifier.Token makeToken(TokenType type, string value) @safe pureCreates a token at the current location.bool isIdStartAt(size_t idx) @safe pureChecks if position has an identifier start character.bool isIdContinueAt(size_t idx) @safe pureChecks if position has an identifier continue character.this(string input, string sourceFilename = "")Constructs a lexer for the given CF source text.Configuration for the CF parser.
Controls parser behavior including include directive handling and security settings.
bool enableIncludesWhether to enable include directive processing. Default is `false` for security - enable only when needed with a proper fileReader.string includeBaseDirBase directory for resolving relative include pathsbool allowAbsolutePathsWhether to allow absolute paths in includesbool allowParentTraversalWhether to allow parent directory traversal (..) in includesstring delegate(string path) @safe fileReaderFile reader delegate for include resolutionbool enableEnvSubstitutionWhether to enable environment variable substitutionstring delegate(string varName) @safe envReaderEnvironment variable reader delegateRecursive-descent parser for CF source text.
Consumes tokens from a CfLexer and produces a CdmDocument that preserves all metadata needed for roundtrip fidelity including comments, locations, and original formatting.
Example:
auto parser = CfParser!CdmBuilder(`key = "value"`);
auto doc = parser.parseDocument();
assert(doc.root.hasKey("key"));CfLexer lexerToken currentTokenToken peekedTokenbool hasPeekedbool initializedsize_t nestingDepthstring sourceFilenameCdmComment[] pendingCommentsCfParserConfig configstring[] includeStacksize_t includeDepthbool[string] seenKeysBuilder builderbool matchAny(TokenType[] types...) @safe pureChecks if the current token matches any of the expected types.CdmFormat.SeparatorStyle skipSeparators() @safe pureSkips separator tokens between members/elements.void parseObjectMembers(bool explicitBraces = false) @safeParses object members into the given node.void parseInclude() @safeParses an include directive and merges the included content into the current builder's top-of-stack container.string normalizeIncludePath(string path) @safe pureNormalizes an include path for security validation.void validateIncludePath(string normalizedPath, string originalPath, Location loc) @safe pureValidates an include path for security.CdmFormat.QuoteStyle detectQuoteStyle(string raw) @safe pureDetects quote style from raw string token.string parseStringValue(string raw) @safeParses string value from raw token, handling escapes.string stripTripleQuotedIndent(string content) @safe pureStrips common indentation from triple-quoted string.bool allHexDigits(string s) @safe pure nothrow @nogcChecks if all characters in a string are valid hex digits.void encodeUTF8(ref Appender!string result, dchar c) @safe pureEncodes a Unicode codepoint as UTF-8.this(string input, string filename = "", CfParserConfig cfg = CfParserConfig.init)Constructs a parser for the given CF source text.this(string input, string filename, CfParserConfig cfg, string[] existingStack, size_t depth)Constructs a parser with an existing include stack.Configuration options for the CF writer.
Controls formatting behavior for output.
string indentIndentation string (default: 3 spaces per CODE_STYLE)bool sortKeysSort object keys for deterministic outputbool useHclStyleUse HCL-style (omit `=` before objects)CdmFormat.SeparatorStyle separatorStyleDefault separator styleCdmFormat.QuoteStyle quoteStyleDefault quote style for new stringsbool minifiedMinified output (no whitespace)Internal CF writer implementation.
void writeMembers(const(CdmMember)[] members, int depth, bool explicit) @safeWrites a sequence of object members.void writeSeparator(CdmFormat.SeparatorStyle style, bool isLast) @safeWrites a separator between members.bool isObjectValue(bool isObj) @safe pure nothrow constReturns true if the value is a nested object that should use HCL-style formatting.void writeVarObjectMembers(ref const var v, int depth) @safeWrites a `var` object as bare key-value pairs (CF/HCL top-level style).this(CfWriterConfig cfg)Constructs a CfWriter with the given configuration.Functions 12
CfLexer tokenize(string input, string filename = "") @safe pureCreates a lexer as an input range for the given CF source.Token[] tokenizeAll(string input, string filename = "") @safe pureTokenizes the entire input and returns all tokens as an array.string toCf(CdmDocument doc, CfWriterConfig config = CfWriterConfig.init) @safeConverts a `CdmDocument` to CF format string.string quoteString(string s, CdmFormat.QuoteStyle style) @safe pureQuotes a string with the specified style.auto parseCf(Builder = CdmBuilder)(string source, string filename = "",
CfParserConfig config = CfParserConfig.init) @safeParses a CF source string.auto parseCfFile(Builder = CdmBuilder)(string path,
CfParserConfig config = CfParserConfig.init)Parses a CF file.CfParserConfig makeEnvConfig() @trustedCreates a CfParserConfig with system environment variable support.auto parseCfWithEnv(Builder = CdmBuilder)(string source,
string filename = "") @trustedParses a CF source string with environment variable substitution.auto parseCfWithIncludes(Builder = CdmBuilder)(string source, string filename,
string delegate(string path) @safe fileReader) @safeParses a CF source with include support.string varToCf(ref const var v, CfWriterConfig config = CfWriterConfig.init) @safeConverts a `var` value to CF format string.Variables 3
MAX_NESTING_DEPTH = 64Maximum nesting depth for objects and arrays.
This limit prevents stack overflow attacks from deeply nested structures.
MAX_INCLUDE_DEPTH = 32Maximum include depth.
This limit prevents excessive include chains.
MAX_ENV_EXPANSION_SIZE = 1024 * 1024Maximum size for environment variable expansion.
This limit prevents denial-of-service via excessively large environment variable values. Default is 1 MB.