Skip to content

[Code Quality] AppFoldersHelper.EnsureFolders — hand-rolled connection-string parser fails on quoted paths and paths containing semicolons #922

@Christophe-Rogiers

Description

@Christophe-Rogiers

Severity: Warning

File: src/Servy.Core/Helpers/AppFoldersHelper.cs (lines 86-95)

Code:

var dataSourcePrefix = \"Data Source=\";
var startIndex = connectionString.IndexOf(dataSourcePrefix, StringComparison.OrdinalIgnoreCase);
if (startIndex < 0)
    throw new InvalidOperationException(\"Connection string does not contain 'Data Source='.\");

startIndex += dataSourcePrefix.Length;
var endIndex = connectionString.IndexOf(';', startIndex);
var dbFilePath = endIndex < 0
    ? connectionString.Substring(startIndex).Trim()
    : connectionString.Substring(startIndex, endIndex - startIndex).Trim();

Explanation:
This is a hand-rolled parser for the SQLite connection string. It works for simple cases like Data Source=C:\path\db.db;Version=3; but fails on perfectly legal SQLite connection strings:

  1. Quoted paths: SQLite allows Data Source=\"C:\path with spaces\db.db\"; (or single-quoted, or backtick-quoted). The parser includes the surrounding quotes in dbFilePath, then Path.GetDirectoryName returns garbage or fails.
  2. Paths containing semicolons: rare but legal under quoting, e.g. Data Source=\"C:\weird;path\db.db\";. The parser splits at the first ; it sees, truncating the path.
  3. DataSource= (no space): ADO.NET happily accepts this form. The case-insensitive match still requires the literal Data Source with the space.
  4. Custom keys / ; quoted within values: anything outside the strict format breaks silently.

The .NET BCL ships System.Data.Common.DbConnectionStringBuilder (and SQLite-specific subclasses) which already handle all of the above. Use it.

Suggested fix:

var sb = new System.Data.Common.DbConnectionStringBuilder { ConnectionString = connectionString };
if (!sb.TryGetValue(\"Data Source\", out var raw) && !sb.TryGetValue(\"DataSource\", out raw))
    throw new InvalidOperationException(\"Connection string does not contain 'Data Source='.\");
var dbFilePath = (raw as string)?.Trim();

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions