From cb87bb6e7f1147c7c63fc0d37c580681db3ebee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Houl=C3=A9?= Date: Wed, 30 Nov 2022 13:24:14 +0100 Subject: [PATCH] psl: fix newline boundary search in relation reformatting 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. closes https://github.com/prisma/prisma/issues/14895 --- psl/psl-core/src/reformat.rs | 5 ++++ psl/psl/tests/reformat_tests.rs | 2 ++ .../regression_thai_trailing_comments.prisma | 23 +++++++++++++++++++ ..._thai_trailing_comments.reformatted.prisma | 23 +++++++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 psl/psl/tests/reformatter/regression_thai_trailing_comments.prisma create mode 100644 psl/psl/tests/reformatter/regression_thai_trailing_comments.reformatted.prisma diff --git a/psl/psl-core/src/reformat.rs b/psl/psl-core/src/reformat.rs index d2ce95518505..b3334f7d7f66 100644 --- a/psl/psl-core/src/reformat.rs +++ b/psl/psl-core/src/reformat.rs @@ -332,6 +332,11 @@ fn references_argument(inline: walkers::InlineRelationWalker<'_>) -> String { /// 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"); + + if !original_schema.is_char_boundary(span_end - 2) { + return span_end - 1; + } + match &original_schema[span_end - 2..span_end - 1] { "\r" => span_end - 2, _ => span_end - 1, diff --git a/psl/psl/tests/reformat_tests.rs b/psl/psl/tests/reformat_tests.rs index 1d070107a7d5..ea6207894047 100644 --- a/psl/psl/tests/reformat_tests.rs +++ b/psl/psl/tests/reformat_tests.rs @@ -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."); } } diff --git a/psl/psl/tests/reformatter/regression_thai_trailing_comments.prisma b/psl/psl/tests/reformatter/regression_thai_trailing_comments.prisma new file mode 100644 index 000000000000..faa11066ff2a --- /dev/null +++ b/psl/psl/tests/reformatter/regression_thai_trailing_comments.prisma @@ -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[] +} diff --git a/psl/psl/tests/reformatter/regression_thai_trailing_comments.reformatted.prisma b/psl/psl/tests/reformatter/regression_thai_trailing_comments.reformatted.prisma new file mode 100644 index 000000000000..5a3ded258e9e --- /dev/null +++ b/psl/psl/tests/reformatter/regression_thai_trailing_comments.reformatted.prisma @@ -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[] +}