Skip to content

Commit

Permalink
psl: fix newline boundary search in relation reformatting (#3457)
Browse files Browse the repository at this point in the history
When adding an @relation attribute to a forward relation field in the
relation reformatting code that deals with adding missing relation
fields and attributes, we searched for the last character before a
newline to check whether it is a carriage return, but we failed to
check whether the byte offset was a char boundary first. This caused
crashes.

This commit fixes the problem by adding the relation attribute directly after the field type, rather than walking back from the end of the field (including trailing comment). We could do better with a proper AST.

closes prisma/prisma#14895
  • Loading branch information
tomhoule committed Dec 1, 2022
1 parent 9527a31 commit 7f090a3
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 9 deletions.
16 changes: 7 additions & 9 deletions psl/psl-core/src/reformat.rs
Expand Up @@ -137,7 +137,7 @@ fn push_missing_relation_attribute(inline_relation: walkers::InlineRelationWalke
content.push(')');

ctx.missing_bits.push(MissingBit {
position: before_newline(forward.ast_field().span().end, ctx.original_schema),
position: after_type(forward.ast_field().field_type.span().end, ctx.original_schema),
content,
})
}
Expand Down Expand Up @@ -328,12 +328,10 @@ fn references_argument(inline: walkers::InlineRelationWalker<'_>) -> String {
format!("references: [{}]", field_names.join(", "))
}

/// Assuming the last characters before span_end are newlines. We can fix this more thoroughly by
/// not including the newline in field spans.
fn before_newline(span_end: usize, original_schema: &str) -> usize {
assert!(&original_schema[span_end - 1..span_end] == "\n");
match &original_schema[span_end - 2..span_end - 1] {
"\r" => span_end - 2,
_ => span_end - 1,
}
fn after_type(type_span_end: usize, original_schema: &str) -> usize {
original_schema[type_span_end..]
.chars()
.position(|chr| !['[', ']', '?', '!'].contains(&chr))
.map(|pos| type_span_end + pos)
.unwrap_or(type_span_end)
}
2 changes: 2 additions & 0 deletions psl/psl/tests/reformat_tests.rs
Expand Up @@ -28,6 +28,8 @@ fn run_reformat_test(test_file_path: &str) {
}

if reformat(&reformatted_text) != reformatted_text {
println!("=== reformatted ===\n{reformatted_text}");
println!("=== reformatted again ===\n{}", reformat(&reformatted_text));
panic!("Reformatting this schema is not idempotent.");
}
}
Expand Down
@@ -0,0 +1,23 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
provider = "prisma-client-js"
output = "./generated/client"
}

datasource db {
provider = "sqlserver"
url = "***"
}

model somemodel {
frownyFaceId String
frownyFace frownyface // 囧
id Int @id
}

model frownyface {
somes somemodel[]
}
@@ -0,0 +1,23 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
provider = "prisma-client-js"
output = "./generated/client"
}

datasource db {
provider = "sqlserver"
url = "***"
}

model somemodel {
frownyFaceId String
frownyFace frownyface @relation(fields: [], references: []) // 囧
id Int @id
}

model frownyface {
somes somemodel[]
}

0 comments on commit 7f090a3

Please sign in to comment.