Skip to content

Unescaped --description value can produce invalid pubspec.yaml #8

Description

@saimskywalker

Problem

The optional --description CLI flag is interpolated into the generated pubspec.yaml as a bare, unquoted YAML scalar. Any value containing YAML-significant characters (a colon followed by a space, a leading #, a wrapping quote, a newline) produces a pubspec.yaml that either fails to parse or is silently misparsed by pub/flutter pub get — the one file every consumer of the generated package needs to load first.

BridgeSpec.validate() checks pluginName, organization, the binary names, iosDeploymentTarget, androidMinSdk/androidCompileSdk, and javaVersion, but never validates or sanitizes description.

Evidence

  • lib/src/spec.dart: description is declared (final String? description;) and accepted by the constructor, but validate() (roughly lines 110–197) never references it — it is the one free-text field with no length limit, character restriction, or escaping step.
  • lib/src/templates/dart_templates.dart:15:
    description: ${spec.description ?? 'Wrapper for a closed-source binary SDK.'}
    This is a plain, unquoted YAML scalar.
  • Reproduction: dart run bin/binary_sdk_bridge.dart --name acme_ads --org com.example --android-aar AcmeSDK --description "Bridge: handles ads and analytics" --out /tmp/x emits:
    description: Bridge: handles ads and analytics
    which YAML parses as a mapping (Bridgehandles ads and analytics) rather than a string, not the single-line description the user intended — flutter pub get then fails on that package.
  • grep -rn "description" lib/ test/ bin/ shows no test exercises a description containing YAML-special characters — the injection-payload tests in test/generator_test.dart cover only the binary-name fields.

Proposed fix

Emit description as a YAML-quoted (or block) scalar — e.g. wrap it in double quotes with the standard YAML escaping for embedded " and backslashes, or reject/normalize newlines — so any input the user supplies round-trips into valid YAML. Optionally add a length/printable-character check in BridgeSpec.validate() consistent with how the other free-text-adjacent fields (binary names) are already guarded.

Acceptance criteria

  • A --description value containing a colon+space, a #, a double quote, or a newline produces a pubspec.yaml that parses correctly and preserves the intended string.
  • A test in test/generator_test.dart generates a package with an adversarial description (mirroring the existing binary-name injection-payload tests) and asserts the emitted pubspec.yaml round-trips through a YAML parse to the original string.
  • dart test and the CI "Generated output is valid" step continue to pass.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions