Skip to content

Commit e961d41

Browse files
committed
Throw for empty strings in primitive collection columns (#32924)
Fixes #32896
1 parent 1b51aa3 commit e961d41

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

src/EFCore/Properties/CoreStrings.Designer.cs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/EFCore/Properties/CoreStrings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,9 @@
486486
<data name="EmptyComplexType" xml:space="preserve">
487487
<value>Complex type '{complexType}' has no properties defines. Configure at least one property or don't include this type in the model.</value>
488488
</data>
489+
<data name="EmptyJsonString" xml:space="preserve">
490+
<value>The empty string is not valid JSON.</value>
491+
</data>
489492
<data name="EntityEqualityOnCompositeKeyEntitySubqueryNotSupported" xml:space="preserve">
490493
<value>Cannot translate '{comparisonOperator}' on a subquery expression of entity type '{entityType}' because it has a composite primary key. See https://go.microsoft.com/fwlink/?linkid=2141942 for information on how to rewrite your query.</value>
491494
</data>

src/EFCore/Storage/Json/JsonValueReaderWriter.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ internal JsonValueReaderWriter()
6363
/// <returns>The read value.</returns>
6464
public object FromJsonString(string json, object? existingObject = null)
6565
{
66+
if (string.IsNullOrWhiteSpace(json))
67+
{
68+
throw new InvalidOperationException(CoreStrings.EmptyJsonString);
69+
}
70+
6671
var readerManager = new Utf8JsonReaderManager(new JsonReaderData(Encoding.UTF8.GetBytes(json)), null);
6772
return FromJson(ref readerManager, existingObject);
6873
}

test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,48 @@ FROM json_each(@__strings_0) AS "s"
13171317
""");
13181318
}
13191319

1320+
[ConditionalTheory]
1321+
[InlineData(false)]
1322+
[InlineData(true)] // Issue #32896
1323+
public async Task Empty_string_used_for_primitive_collection_throws(bool async)
1324+
{
1325+
await using var connection = new SqliteConnection("DataSource=:memory:");
1326+
await connection.OpenAsync();
1327+
1328+
await using var context = new SimpleContext(connection);
1329+
await context.Database.EnsureDeletedAsync();
1330+
await context.Database.EnsureCreatedAsync();
1331+
1332+
await context.Database.ExecuteSqlRawAsync("INSERT INTO SimpleEntities (List) VALUES ('');");
1333+
1334+
var set = context.SimpleEntities;
1335+
1336+
var message = await Assert.ThrowsAsync<InvalidOperationException>(
1337+
async () =>
1338+
{
1339+
if (async)
1340+
{
1341+
await set.FirstAsync();
1342+
}
1343+
else
1344+
{
1345+
set.First();
1346+
}
1347+
});
1348+
1349+
Assert.Equal(CoreStrings.EmptyJsonString, message.Message);
1350+
}
1351+
1352+
public class SimpleContext(SqliteConnection connection) : DbContext
1353+
{
1354+
public DbSet<SimpleEntity> SimpleEntities => Set<SimpleEntity>();
1355+
1356+
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
1357+
=> optionsBuilder.UseSqlite(connection);
1358+
}
1359+
1360+
public record SimpleEntity(int Id, IEnumerable<string> List);
1361+
13201362
[ConditionalFact]
13211363
public virtual void Check_all_tests_overridden()
13221364
=> TestHelpers.AssertAllMethodsOverridden(GetType());

0 commit comments

Comments
 (0)