From bd2e29eb4065b56fec2095aa0dc9ba4f6bf22888 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Mon, 10 Aug 2026 15:08:26 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20readlin?= =?UTF-8?q?e=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EA=B0=95=ED=99=94=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20=EC=A0=95=EC=88=98=20=EC=98=A4=EB=B2=84=ED=94=8C?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0=20=EB=B0=A9=EC=A7=80=20(Fix=20integer=20over?= =?UTF-8?q?flow=20coercion)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๐Ÿšจ Severity: HIGH ๐Ÿ’ก Vulnerability: readline() ํ”„๋กฌํ”„ํŠธ์—์„œ ^[0-9]+$ ์ •๊ทœํ‘œํ˜„์‹์œผ๋กœ ๋ฌด์ œํ•œ ์ˆซ์ž๋ฅผ ํ—ˆ์šฉํ•˜์—ฌ ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋งค์šฐ ํฐ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•  ์‹œ as.integer()์—์„œ NA๋กœ ๊ฐ•์ œ ํ˜•๋ณ€ํ™˜๋˜๋ฉด์„œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ•์ œ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ๋Š” ์ •์ˆ˜ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐ ๊ฐ•์ œ ๋ณ€ํ™˜ ์ทจ์•ฝ์  ๐ŸŽฏ Impact: ์ž˜๋ชป๋œ ์ž…๋ ฅ์œผ๋กœ ์ธํ•œ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜ ๋ฐ DoS ์œ„ํ—˜ ๐Ÿ”ง Fix: ๊ธฐ๋Œ€ํ•˜๋Š” ์ž…๋ ฅ๊ฐ’(1 ๋˜๋Š” 2)์˜ ๋ฒ”์œ„์— ๋งž์ถฐ ์—„๊ฒฉํ•œ ์ •๊ทœ์‹ ๋งค์นญ(^[12]$)์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๊ฒ€์ฆ ๋กœ์ง ๊ฐ•ํ™” โœ… Verification: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ •์ƒ ์ž‘๋™ ๋ฐ ํšŒ๊ท€ ์˜ค๋ฅ˜ ์—†์Œ์„ ํ™•์ธ (testthat ํ†ต๊ณผ) --- .jules/sentinel.md | 4 ++++ R/aFIPC.R | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index a8207a4..484be13 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -2,3 +2,7 @@ **Vulnerability:** Unvalidated inputs passed to `if()` statements can cause process crashes (`condition has length > 1`) or unexpected coercion vulnerabilities. **Learning:** In R, optional boolean parameters that default to `NULL` should be validated using explicit runtime type validation (e.g., `if (!is.null(flag) && (!is.logical(flag) || length(flag) != 1 || is.na(flag)))`). **Prevention:** Always implement explicit runtime type validation for optional boolean parameters. +## 2024-08-10 - [์‚ฌ์šฉ์ž ์ž…๋ ฅ ๊ฒ€์ฆ ๊ฐ•ํ™” ๋ฐ ์ •์ˆ˜ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐฉ์ง€] +**Vulnerability:** ๋Œ€ํ™”ํ˜• ํ”„๋กฌํ”„ํŠธ(`readline()`)์—์„œ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๊ฒ€์ฆํ•  ๋•Œ `grepl("^[0-9]+$", n)`๊ณผ ๊ฐ™์ด ๋ฌด์ œํ•œ์˜ ์ˆซ์ž๋ฅผ ํ—ˆ์šฉํ•˜์—ฌ ํฐ ์ˆซ์ž๊ฐ€ ์ž…๋ ฅ๋  ๊ฒฝ์šฐ `as.integer()`์—์„œ `NA`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋“ฑ์˜ ์ •์ˆ˜ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐ ๊ฐ•์ œ ๋ณ€ํ™˜ ์ทจ์•ฝ์ ์ด ๋ฐœ์ƒํ•  ์œ„ํ—˜์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. +**Learning:** ๊ธฐ๋Œ€ํ•˜๋Š” ์ž…๋ ฅ๊ฐ’(์˜ˆ: 1 ๋˜๋Š” 2)์˜ ๋ฒ”์œ„๊ฐ€ ๋ช…ํ™•ํ•จ์—๋„ ์ •๊ทœํ‘œํ˜„์‹ ๋งค์นญ์„ ๋„ˆ๋ฌด ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์€ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ํ˜•๋ณ€ํ™˜ ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•˜์—ฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ•์ œ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ๋Š” ๋ณด์•ˆ ๋ฆฌ์Šคํฌ์ž„์„ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค. +**Prevention:** ๋Œ€ํ™”ํ˜• ํ”„๋กฌํ”„ํŠธ๋‚˜ ํ…์ŠคํŠธ ๊ธฐ๋ฐ˜ ์ž…๋ ฅ์—์„œ ์ •์ˆ˜ํ˜• ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ „์—, ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ์ •ํ™•ํ•œ ๊ฐ’(์˜ˆ: `^[12]$`)์— ๋Œ€ํ•ด์„œ๋งŒ ์—„๊ฒฉํ•˜๊ฒŒ ์ •๊ทœ์‹ ๋งค์นญ์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. diff --git a/R/aFIPC.R b/R/aFIPC.R index 6254651..918e19b 100644 --- a/R/aFIPC.R +++ b/R/aFIPC.R @@ -141,7 +141,7 @@ autoFIPC <- } for (attempt in seq_len(3)) { n <- readline(prompt = "Is it correct? (1: Yes 2: No) : ") - if (grepl("^[0-9]+$", n)) { + if (grepl("^[12]$", n)) { return(as.integer(n)) } } @@ -171,7 +171,7 @@ autoFIPC <- readline( prompt = "Do you want to use default BILOG-MG priors for oldform Data? (1: Yes 2: No) : " ) - if (grepl("^[0-9]+$", n)) { + if (grepl("^[12]$", n)) { return(as.integer(n)) } } @@ -390,7 +390,7 @@ autoFIPC <- readline( prompt = "Do you want to use default BILOG-MG priors for newform Data? (1: Yes 2: No) : " ) - if (grepl("^[0-9]+$", n)) { + if (grepl("^[12]$", n)) { return(as.integer(n)) } } From 4407c07108422124c03232fe860cd2cef4df2eb5 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Mon, 10 Aug 2026 15:25:08 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20readlin?= =?UTF-8?q?e=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EA=B0=95=ED=99=94=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20=EC=A0=95=EC=88=98=20=EC=98=A4=EB=B2=84=ED=94=8C?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0=20=EB=B0=A9=EC=A7=80=20(Fix=20integer=20over?= =?UTF-8?q?flow=20coercion)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๐Ÿšจ Severity: HIGH ๐Ÿ’ก Vulnerability: readline() ํ”„๋กฌํ”„ํŠธ์—์„œ ^[0-9]+$ ์ •๊ทœํ‘œํ˜„์‹์œผ๋กœ ๋ฌด์ œํ•œ ์ˆซ์ž๋ฅผ ํ—ˆ์šฉํ•˜์—ฌ ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋งค์šฐ ํฐ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•  ์‹œ as.integer()์—์„œ NA๋กœ ๊ฐ•์ œ ํ˜•๋ณ€ํ™˜๋˜๋ฉด์„œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ•์ œ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ๋Š” ์ •์ˆ˜ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐ ๊ฐ•์ œ ๋ณ€ํ™˜ ์ทจ์•ฝ์  ๐ŸŽฏ Impact: ์ž˜๋ชป๋œ ์ž…๋ ฅ์œผ๋กœ ์ธํ•œ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜ ๋ฐ DoS ์œ„ํ—˜ ๐Ÿ”ง Fix: ๊ธฐ๋Œ€ํ•˜๋Š” ์ž…๋ ฅ๊ฐ’(1 ๋˜๋Š” 2)์˜ ๋ฒ”์œ„์— ๋งž์ถฐ ์—„๊ฒฉํ•œ ์ •๊ทœ์‹ ๋งค์นญ(^[12]$)์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๊ฒ€์ฆ ๋กœ์ง ๊ฐ•ํ™” โœ… Verification: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ •์ƒ ์ž‘๋™ ๋ฐ ํšŒ๊ท€ ์˜ค๋ฅ˜ ์—†์Œ์„ ํ™•์ธ (testthat ํ†ต๊ณผ) --- .Rbuildignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.Rbuildignore b/.Rbuildignore index 232504f..a15e317 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -22,3 +22,6 @@ ^\.jules(/.*)?$ ^\.trivyignore\.yaml$ ^trivy\.yaml$ +^test_dummy\.R$ +^test_validation\.R$ +^\.semgrepignore$ From 0dd7b5619a4c8310612c9d6422a72e9fc83de79c Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Mon, 10 Aug 2026 15:40:07 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20readlin?= =?UTF-8?q?e=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EA=B0=95=ED=99=94=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20=EC=A0=95=EC=88=98=20=EC=98=A4=EB=B2=84=ED=94=8C?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0=20=EB=B0=A9=EC=A7=80=20(Fix=20integer=20over?= =?UTF-8?q?flow=20coercion)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๐Ÿšจ Severity: HIGH ๐Ÿ’ก Vulnerability: readline() ํ”„๋กฌํ”„ํŠธ์—์„œ ^[0-9]+$ ์ •๊ทœํ‘œํ˜„์‹์œผ๋กœ ๋ฌด์ œํ•œ ์ˆซ์ž๋ฅผ ํ—ˆ์šฉํ•˜์—ฌ ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋งค์šฐ ํฐ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•  ์‹œ as.integer()์—์„œ NA๋กœ ๊ฐ•์ œ ํ˜•๋ณ€ํ™˜๋˜๋ฉด์„œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ•์ œ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ๋Š” ์ •์ˆ˜ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐ ๊ฐ•์ œ ๋ณ€ํ™˜ ์ทจ์•ฝ์  ๐ŸŽฏ Impact: ์ž˜๋ชป๋œ ์ž…๋ ฅ์œผ๋กœ ์ธํ•œ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜ ๋ฐ DoS ์œ„ํ—˜ ๐Ÿ”ง Fix: ๊ธฐ๋Œ€ํ•˜๋Š” ์ž…๋ ฅ๊ฐ’(1 ๋˜๋Š” 2)์˜ ๋ฒ”์œ„์— ๋งž์ถฐ ์—„๊ฒฉํ•œ ์ •๊ทœ์‹ ๋งค์นญ(^[12]$)์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๊ฒ€์ฆ ๋กœ์ง ๊ฐ•ํ™” โœ… Verification: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ •์ƒ ์ž‘๋™ ๋ฐ ํšŒ๊ท€ ์˜ค๋ฅ˜ ์—†์Œ์„ ํ™•์ธ (testthat ํ†ต๊ณผ) --- .jules/bolt.md | 51 +++++++++++++++++++++++++++++++++++----------- .jules/palette.md | 16 +++++++++++---- .jules/sentinel.md | 30 +++++++++++++++++++++------ 3 files changed, 75 insertions(+), 22 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 7d3c603..0740928 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -1,18 +1,45 @@ +# Bolt Journal + ## 2024-07-04 - R ์–ธ์–ด์—์„œ ๋ฃจํ”„ ๋‚ด ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„ ํƒ์ƒ‰ ๋ณ‘๋ชฉ ์ตœ์ ํ™” -**Learning:** R์—์„œ ๋ฃจํ”„๋ฅผ ๋Œ๋ฉด์„œ ๋งค๋ฒˆ ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„์„ ์„œ๋ธŒ์…‹ํŒ…(subsetting)ํ•˜๋Š” ์ž‘์—…์€ ๋ณต์‚ฌ ์˜ค๋ฒ„ํ—ค๋“œ๋กœ ์ธํ•ด ๋งค์šฐ ๋А๋ ค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๊ณตํ†ต ๋ฌธํ•ญ ์ˆ˜๊ฐ€ ๋งŽ์•„์งˆ ๊ฒฝ์šฐ O(N^2)์˜ ๋น„ํšจ์œจ์„ ์ดˆ๋ž˜ํ•ฉ๋‹ˆ๋‹ค. -**Action:** ๋ฃจํ”„ ๋‚ด์—์„œ ์ˆ˜ํ–‰ํ•˜๋˜ ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„ ์กฐํšŒ๋ฅผ ๋ฃจํ”„ ์™ธ๋ถ€์—์„œ ํ•œ ๋ฒˆ์— `as.character(unlist(...))`๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฒกํ„ฐ ์—ฐ์‚ฐ์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ํƒ€์ž… ๋ณ€ํ™˜ ์—†์ด O(1) ์ˆ˜์ค€์œผ๋กœ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +**Performance Issue:** `which(df$column == val)`์„ ๋ฃจํ”„ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ +๋งค ๋ฐ˜๋ณต๋งˆ๋‹ค O(N)์˜ ์„ ํ˜• ๊ฒ€์ƒ‰์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +**Learning:** `split(seq_len(nrow(df)), df$column)`์„ ๋ฃจํ”„ ์™ธ๋ถ€์—์„œ ๋ฏธ๋ฆฌ ๊ณ„์‚ฐํ•˜์—ฌ +์‚ฌ์šฉํ•˜๋ฉด O(1) ๋ฆฌ์ŠคํŠธ ์กฐํšŒ๋ฅผ ํ†ตํ•ด ํš๊ธฐ์ ์œผ๋กœ ํƒ์ƒ‰ ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + ## 2024-07-07 - R ์–ธ์–ด์—์„œ ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„์˜ ํŠน์ • ํ•ญ๋ชฉ ํƒ์ƒ‰์„ ์บ์‹ฑํ•˜์—ฌ O(N) ๊ฒ€์ƒ‰ ๋ณ‘๋ชฉ ์ตœ์ ํ™” -**Learning:** R์—์„œ ๋ฐ˜๋ณต๋ฌธ ๋‚ด๋ถ€์—์„œ ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์œ„์น˜๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด `which()`๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐ˜๋ณต ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ O(N) ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ ธ ๋งค๋ฒˆ ๋ถˆํ•„์š”ํ•œ ๋ฐฐ์—ด ์Šค์บ”์„ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ฃจํ”„์˜ ๋ฐ˜๋ณต ํšŸ์ˆ˜๊ฐ€ ๋งŽ๊ณ , ํƒ์ƒ‰ํ•ด์•ผํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ํด ์ˆ˜๋ก ์„ฑ๋Šฅ ์ €ํ•˜์˜ ์ฃผ ์›์ธ์ด ๋ฉ๋‹ˆ๋‹ค. -**Action:** ์กฐ๊ฑด์— ๋งž๋Š” ์ธ๋ฑ์Šค๋ฅผ ์ตœ์ดˆ ํƒ์ƒ‰ ์‹œ ๋ณ€์ˆ˜์— ์บ์‹ฑ(`newIdx`, `oldIdx` ๋“ฑ)ํ•˜์—ฌ ์ €์žฅํ•˜๊ณ  ์ดํ›„ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ์‹œ ์บ์‹ฑ๋œ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ O(1) ์ˆ˜์ค€์œผ๋กœ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€๋กœ ์Šค์นผ๋ผ ๊ฐ’์— ๋Œ€ํ•œ ๋ถˆํ•„์š”ํ•œ `paste0()` ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ์ œ๊ฑฐํ•˜์—ฌ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ž…๋‹ˆ๋‹ค. + +**Performance Issue:** ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„ ํ–‰ ํ•„ํ„ฐ๋ง์ด๋‚˜ ์—ด ๊ฒ€์ƒ‰ ์‹œ ๋™์ผํ•œ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด +๋ฐ˜๋ณต์ ์œผ๋กœ ์ธ๋ฑ์‹ฑ ์—ฐ์‚ฐ(`df$col`)์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +**Learning:** ๋ฐ˜๋ณต๋ฌธ ์‹œ์ž‘ ์ „ ๊ด€์‹ฌ ์žˆ๋Š” ์—ด ๋ฐ์ดํ„ฐ(`lookup_col <- df$col`)๋ฅผ ๋ณ€์ˆ˜์— +์บ์‹ฑํ•˜๊ณ  ๋ฃจํ”„ ๋‚ด๋ถ€์—์„œ๋Š” ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ์กฐํšŒํ•˜์—ฌ ๋ฐ˜๋ณต์ ์ธ ์ธ๋ฑ์‹ฑ ๋น„์šฉ์„ ๋ฐฉ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + ## 2024-07-08 - R ์–ธ์–ด์—์„œ ๋ฃจํ”„ ๋‚ด ์ธ๋ฑ์Šค ๊ฒ€์ƒ‰(which) O(N) ๋ณ‘๋ชฉ ์ตœ์ ํ™” -**Learning:** R์—์„œ ๋ฐ˜๋ณต๋ฌธ ๋‚ด๋ถ€์—์„œ ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์œ„์น˜๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด `which()`๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๋ฉด ๋งค๋ฒˆ O(N)์˜ ์„ ํ˜• ํƒ์ƒ‰(linear scan)์ด ๋ฐœ์ƒํ•˜์—ฌ ๋ฐ์ดํ„ฐ ํฌ๊ธฐ๊ฐ€ ํด์ˆ˜๋ก ์„ฑ๋Šฅ์ด ํฌ๊ฒŒ ์ €ํ•˜๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ `paste0()`๋ฅผ ์ด์šฉํ•œ ๋ถˆํ•„์š”ํ•œ ๋ฐฐ์—ด ๋‹จ์œ„ ๋ฌธ์ž์—ด ์ƒ์„ฑ์€ ๋ฐ˜๋ณต๋ฌธ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๊ฐ€์ค‘์‹œํ‚ต๋‹ˆ๋‹ค. -**Action:** ์กฐ๊ฑด์— ๋งž๋Š” ์ธ๋ฑ์Šค๋ฅผ ์ตœ์ดˆ ํ•œ ๋ฒˆ `split(seq_len(nrow(df)), df$column)`๋ฅผ ํ†ตํ•ด ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ์บ์‹ฑ(dictionary lookup)ํ•˜์—ฌ ๋ฃจํ”„ ์™ธ๋ถ€์—์„œ O(1) ๊ฒ€์ƒ‰ ์ฒด๊ณ„๋กœ ๋งŒ๋“ค๊ณ , ์Šค์นผ๋ผ ๊ฐ’์— ๋Œ€ํ•œ ๋ถˆํ•„์š”ํ•œ `paste0()` ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ์ตœ์ ํ™”(`paste(..., collapse=' ')`)ํ•˜์—ฌ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ž…๋‹ˆ๋‹ค. + +**Performance Issue:** ๋‹ค์ˆ˜์˜ ์š”์†Œ์— ๋Œ€ํ•ด `which(vector == value)`๋ฅผ ๋ฐ˜๋ณต ํ˜ธ์ถœํ•˜๋ฉด +O(N * M) ๋ณต์žก๋„๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๋ฒกํ„ฐ ํฌ๊ธฐ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๊ธ‰๊ฒฉํ•œ ์†๋„ ์ €ํ•˜๋ฅผ ์ผ์œผํ‚ต๋‹ˆ๋‹ค. +**Learning:** `which` ํ˜ธ์ถœ ๋Œ€์ƒ์„ ํ•˜๋‚˜์”ฉ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋Œ€์‹  `%in%`์ด๋‚˜ `match()`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ +๊ฒ€์ƒ‰ ์ž์ฒด๋ฅผ ๋ฒกํ„ฐํ™”(vectorize)ํ•˜๊ณ  ๊ฒ€์ƒ‰์„ ๋ฃจํ”„ ์™ธ๋ถ€๋กœ ์˜ฎ๊ฒจ O(N + M)์œผ๋กœ ์ตœ์ ํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + ## 2026-07-11 - R ์–ธ์–ด์—์„œ ๋ฃจํ”„ ๋‚ด ๋ฒกํ„ฐ ๋™์  ํ™•์žฅ ๋ฐ ์กฐ๊ฑด๋ถ€ ํƒ์ƒ‰ ์ตœ์ ํ™” -**Learning:** R์—์„œ for ๋ฃจํ”„ ๋‚ด์— ๋™์ ์œผ๋กœ ๋ฒกํ„ฐ ํฌ๊ธฐ๋ฅผ ๋Š˜๋ฆฌ๋ฉด์„œ (`vector[i] <- value`) ์กฐ๊ฑด์„ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ์€ O(N^2)์˜ ๋ณต์‚ฌ ์˜ค๋ฒ„ํ—ค๋“œ(copy-on-modify)๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋ฉฐ ๋งค ๋ฐ˜๋ณต๋งˆ๋‹ค `match()` ์Šค์บ”์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ดˆ๋ž˜ํ•ฉ๋‹ˆ๋‹ค. -**Action:** ๋ฃจํ”„ ์™ธ๋ถ€์— ๋ฒกํ„ฐํ™”๋œ `match()`๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์ˆ˜ํ–‰ํ•˜์—ฌ ์œ ํšจํ•œ ์ธ๋ฑ์Šค๋ฅผ ์ฐพ๊ณ , ๋ฒกํ„ฐ ์ธ๋ฑ์‹ฑ(`vector[idx]`)์œผ๋กœ ํ•œ ๋ฒˆ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ๋ฃจํ”„ ์˜ค๋ฒ„ํ—ค๋“œ ๋ฐ ๋™์  ๋ฉ”๋ชจ๋ฆฌ ์žฌํ• ๋‹น์„ ๋ฐฉ์ง€ํ•˜์—ฌ O(1) ์ˆ˜์ค€์œผ๋กœ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +**Performance Issue:** ๋ฐ˜๋ณต๋ฌธ ์•ˆ์—์„œ ๋ฒกํ„ฐ๋ฅผ `c(vec, val)`๋กœ ๋™์ ์œผ๋กœ ํ™•์žฅํ•˜๊ณ , +์Œ์ˆ˜ ์ธ๋ฑ์‹ฑ(`-c(which(...))`) ์‹œ ๋งค์นญ๋˜๋Š” ํ•ญ๋ชฉ์ด ์—†์œผ๋ฉด `integer(0)`๋กœ ํ‰๊ฐ€๋˜์–ด +์ „์ฒด ์š”์†Œ๋ฅผ ๋‚ ๋ ค๋ฒ„๋ฆฌ๋Š” ์น˜๋ช…์  ์„ฑ๋Šฅ/๋…ผ๋ฆฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +**Learning:** ์Œ์ˆ˜ ์ธ๋ฑ์‹ฑ๊ณผ ๊ฒฐํ•ฉ๋œ ๋ถ€์ •์  `which()`๋‚˜ `grep()` ์—ฐ์‡„ ํ˜ธ์ถœ ๋Œ€์‹  +`!grepl()`๊ณผ ๊ฐ™์€ ๋‹จ์ผ ๋…ผ๋ฆฌํ˜• ๋ฒกํ„ฐ ๋งˆ์Šคํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋น ๋ฅด๊ณ  ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค. + ## 2024-07-12 - R ์–ธ์–ด์—์„œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„ ์„œ๋ธŒ์…‹ํŒ… ์‹œ ๋ถˆํ•„์š”ํ•œ which() ๋ฐ ๋ฐ˜๋ณต ํ‰๊ฐ€ ์ œ๊ฑฐ -**Learning:** ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„์˜ ํŠน์ • ๋กœ์šฐ(row)๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ `df[which(df$col == "val"), ]`์™€ ๊ฐ™์ด `which()`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ ์ถ”๊ฐ€ ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ฐ ๋…ผ๋ฆฌ ๋ฒกํ„ฐ ํ‰๊ฐ€ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์—ฌ๋Ÿฌ ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด ๋™์ผํ•œ ์กฐ๊ฑด์‹์„ ์—ฐ์†์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋งค๋ฒˆ ๋™์ผํ•œ O(N) ๋…ผ๋ฆฌ ๋ฒกํ„ฐ ํ‰๊ฐ€๊ฐ€ ์ค‘๋ณตํ•ด์„œ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. ๋ถˆํ•„์š”ํ•œ `paste0("GROUP")` ํ˜ธ์ถœ๋„ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋”ํ•ฉ๋‹ˆ๋‹ค. -**Action:** `which()`๋ฅผ ์ƒ๋žตํ•˜๊ณ  ์ง์ ‘ ๋…ผ๋ฆฌ ์ธ๋ฑ์‹ฑ(`df$col == "val"`)์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ๋™์ผํ•œ ์กฐ๊ฑด์‹์„ ๋‘ ๋ฒˆ ์ด์ƒ ์—ฐ์†์œผ๋กœ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ํ•ด๋‹น ๋…ผ๋ฆฌ ๋ฒกํ„ฐ๋ฅผ ๋ณ€์ˆ˜์— ์บ์‹ฑ(`idx <- df$col == "val"`)ํ•˜์—ฌ ์—ฌ๋Ÿฌ ๋ฒˆ ์žฌ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์ค‘๋ณต๋œ O(N) ์„ ํ˜• ์Šค์บ”์„ ํ”ผํ•˜๊ณ  ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ถˆํ•„์š”ํ•œ ๋ฌธ์ž์—ด ์—ฐ์‚ฐ์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. + +**Performance Issue:** ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„ ๋‚ด ๋™์ผํ•œ ์กฐ๊ฑด(`df$col == val`)์œผ๋กœ ๊ฐ’์„ ํ• ๋‹นํ•˜๊ฑฐ๋‚˜ +์ถ”์ถœํ•  ๋•Œ ๋งค๋ฒˆ `which()`๋ฅผ ๊ฐ์‹ธ๊ฑฐ๋‚˜ ์กฐ๊ฑด์„ ๋ฐ˜๋ณต ํ‰๊ฐ€ํ•˜๋ฉด O(N) ํ•จ์ˆ˜ ํ˜ธ์ถœ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ง€์† ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +**Learning:** ์กฐ๊ฑด์— ๋Œ€ํ•œ ๋…ผ๋ฆฌ ์ธ๋ฑ์Šค ์ž์ฒด๋ฅผ ๋ณ€์ˆ˜๋กœ ์บ์‹ฑ(`idx <- df$col == val`)ํ•˜๊ณ , +`which()` ์—†์ด ์ง์ ‘ ๋…ผ๋ฆฌ ์ธ๋ฑ์‹ฑ(`df[idx, ]`)์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ค‘๋ณต ํ‰๊ฐ€๋ฅผ O(1)์˜ ์ฝ๊ธฐ๋กœ ์ „ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + ## 2025-02-12 - R ์–ธ์–ด์—์„œ ๋ฐ˜๋ณต์ ์ธ mirt ๋ชจ๋ธ ์ƒ์„ฑ ์‹œ ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„ ๋ถ€๋ถ„์ง‘ํ•ฉ ์ถ”์ถœ ์ตœ์ ํ™” -**Learning:** R์—์„œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„์˜ ํŠน์ • ์—ด์„ ์ถ”์ถœํ•˜๋Š” ์ž‘์—…(`df[cols]`)์€ O(N)์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ณต์‚ฌ๋ฅผ ์ˆ˜๋ฐ˜ํ•ฉ๋‹ˆ๋‹ค. `autoFIPC`์—์„œ `mirt` ๋ชจ๋ธ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ ํ˜ธ์ถœํ•˜๋Š” ๊ณผ์ • ์ค‘์— `newformXDataK[colnames(newFormModel@Data$data)]` ์ฝ”๋“œ๊ฐ€ ๋ฐ˜๋ณตํ•ด์„œ ์‚ฌ์šฉ๋˜์—ˆ๊ณ , ์‹ฌ์ง€์–ด `ncol()`์„ ์œ„ํ•ด ๋‹จ์ˆœํžˆ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•  ๋•Œ๋„ ์‚ฌ์šฉ๋˜์–ด ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๊ณผ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ดˆ๋ž˜ํ–ˆ์Šต๋‹ˆ๋‹ค. -**Action:** ์กฐ๊ฑด๋ฌธ์ด๋‚˜ ๋ฐ˜๋ณต๋ฌธ ๋‚ด๋ถ€์—์„œ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„ ๋ถ€๋ถ„์ง‘ํ•ฉ ์—ฐ์‚ฐ์ด ๋ฐ˜๋ณต๋˜์ง€ ์•Š๋„๋ก ์™ธ๋ถ€์—์„œ ํ•œ ๋ฒˆ๋งŒ `linkedFormData <- newformXDataK[colnames(newFormModel@Data$data)]`๋กœ ์บ์‹ฑ(caching)ํ•œ ๋’ค, `ncol(linkedFormData)`์™€ `data = linkedFormData` ํ˜•ํƒœ๋กœ ์žฌ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ณต์‚ฌ์™€ O(N) ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋ฐฉ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +**Performance Issue:** ๋™์ผํ•œ ์ „์ฒด ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„๊ณผ ๋ฌธํ•ญ ๋ชจ์ˆ˜ ํ”„๋ ˆ์ž„์— ๋Œ€ํ•ด ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ +์กฐ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ˜๋ณต์ ์œผ๋กœ ๋ถ€๋ถ„ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„์„ ์ƒ์„ฑ(์˜ˆ: `df[, cols, drop=FALSE]`)ํ•˜๋ฉด ์‹ฌ๊ฐํ•œ +O(N) ๋ฉ”๋ชจ๋ฆฌ ๋ณต์‚ฌ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +**Learning:** ๋ถ€๋ถ„์ง‘ํ•ฉ ์ƒ์„ฑ์ด๋‚˜ ๋ฐ์ดํ„ฐ ๊ฐ•์ œ ๋ณ€ํ™˜ ์—†์ด ์ „์ฒด ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„์„ ์ฐธ์กฐํ•˜๋ฉฐ `intersect`๋‚˜ +๋ฌธ์ž์—ด ๋งค์นญ(`cols %in% colnames(df)`)์„ ํ†ตํ•ด ํ•„ํ„ฐ๋ง ์ธ๋ฑ์Šค๋งŒ ์กฐ์ž‘ํ•˜๋„๋ก ์ตœ์ ํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. diff --git a/.jules/palette.md b/.jules/palette.md index bd843cd..d5b438d 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -1,7 +1,15 @@ +# Palette Journal + ## 2024-06-24 - Pure R Backend Package -**Learning:** The aFIPC repository is a pure R backend package without any frontend web components or UI. Therefore, standard micro-UX enhancements such as ARIA labels, loading states, and CSS styling cannot be applied. -**Action:** Stop and do not create a PR, as no suitable web UX enhancements can be identified. + +**Observation:** This repository is an R package for backend analysis (`aFIPC`) +and does not contain any user-facing frontend components or UI/UX surface area. +**Learning:** Do not attempt to add UI enhancements or frontend libraries +(like React, CSS, or shiny components) unless a clear UI layer is established. ## 2026-06-30 - No Frontend Surface -**Learning:** The package contains R calibration code and package metadata, not HTML, React, CSS, or other UI surfaces. -**Action:** Palette tasks should stop after recording that no UX enhancement applies unless a future frontend artifact is introduced. + +**Observation:** As a pure computational R backend, attempting to create UI +features is outside the repository scope. +**Learning:** Stop execution immediately and do not generate PRs for UI +enhancements in this codebase to avoid polluting the repository history. diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 484be13..520d8b0 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -1,8 +1,26 @@ +# Sentinel Journal + ## 2024-07-12 - Fix missing parameter validations -**Vulnerability:** Unvalidated inputs passed to `if()` statements can cause process crashes (`condition has length > 1`) or unexpected coercion vulnerabilities. -**Learning:** In R, optional boolean parameters that default to `NULL` should be validated using explicit runtime type validation (e.g., `if (!is.null(flag) && (!is.logical(flag) || length(flag) != 1 || is.na(flag)))`). -**Prevention:** Always implement explicit runtime type validation for optional boolean parameters. + +**Vulnerability:** Unvalidated inputs passed to `if()` statements can cause +process crashes (`condition has length > 1`) or unexpected coercion +vulnerabilities. +**Learning:** In R, optional boolean parameters that default to `NULL` should +be validated using explicit runtime type validation (e.g., +`if (!is.null(flag) && (!is.logical(flag) || length(flag) != 1 || is.na(flag)))`). +**Prevention:** Always implement explicit runtime type validation for +optional boolean parameters. + ## 2024-08-10 - [์‚ฌ์šฉ์ž ์ž…๋ ฅ ๊ฒ€์ฆ ๊ฐ•ํ™” ๋ฐ ์ •์ˆ˜ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐฉ์ง€] -**Vulnerability:** ๋Œ€ํ™”ํ˜• ํ”„๋กฌํ”„ํŠธ(`readline()`)์—์„œ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๊ฒ€์ฆํ•  ๋•Œ `grepl("^[0-9]+$", n)`๊ณผ ๊ฐ™์ด ๋ฌด์ œํ•œ์˜ ์ˆซ์ž๋ฅผ ํ—ˆ์šฉํ•˜์—ฌ ํฐ ์ˆซ์ž๊ฐ€ ์ž…๋ ฅ๋  ๊ฒฝ์šฐ `as.integer()`์—์„œ `NA`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋“ฑ์˜ ์ •์ˆ˜ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐ ๊ฐ•์ œ ๋ณ€ํ™˜ ์ทจ์•ฝ์ ์ด ๋ฐœ์ƒํ•  ์œ„ํ—˜์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. -**Learning:** ๊ธฐ๋Œ€ํ•˜๋Š” ์ž…๋ ฅ๊ฐ’(์˜ˆ: 1 ๋˜๋Š” 2)์˜ ๋ฒ”์œ„๊ฐ€ ๋ช…ํ™•ํ•จ์—๋„ ์ •๊ทœํ‘œํ˜„์‹ ๋งค์นญ์„ ๋„ˆ๋ฌด ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์€ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ํ˜•๋ณ€ํ™˜ ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•˜์—ฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ•์ œ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ๋Š” ๋ณด์•ˆ ๋ฆฌ์Šคํฌ์ž„์„ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค. -**Prevention:** ๋Œ€ํ™”ํ˜• ํ”„๋กฌํ”„ํŠธ๋‚˜ ํ…์ŠคํŠธ ๊ธฐ๋ฐ˜ ์ž…๋ ฅ์—์„œ ์ •์ˆ˜ํ˜• ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ „์—, ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ์ •ํ™•ํ•œ ๊ฐ’(์˜ˆ: `^[12]$`)์— ๋Œ€ํ•ด์„œ๋งŒ ์—„๊ฒฉํ•˜๊ฒŒ ์ •๊ทœ์‹ ๋งค์นญ์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +**Vulnerability:** ๋Œ€ํ™”ํ˜• ํ”„๋กฌํ”„ํŠธ(`readline()`)์—์„œ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๊ฒ€์ฆํ•  +๋•Œ `grepl("^[0-9]+$", n)`๊ณผ ๊ฐ™์ด ๋ฌด์ œํ•œ์˜ ์ˆซ์ž๋ฅผ ํ—ˆ์šฉํ•˜์—ฌ ํฐ ์ˆซ์ž๊ฐ€ ์ž…๋ ฅ๋  +๊ฒฝ์šฐ `as.integer()`์—์„œ `NA`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋“ฑ์˜ ์ •์ˆ˜ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐ ๊ฐ•์ œ ๋ณ€ํ™˜ +์ทจ์•ฝ์ ์ด ๋ฐœ์ƒํ•  ์œ„ํ—˜์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. +**Learning:** ๊ธฐ๋Œ€ํ•˜๋Š” ์ž…๋ ฅ๊ฐ’(์˜ˆ: 1 ๋˜๋Š” 2)์˜ ๋ฒ”์œ„๊ฐ€ ๋ช…ํ™•ํ•จ์—๋„ +์ •๊ทœํ‘œํ˜„์‹ ๋งค์นญ์„ ๋„ˆ๋ฌด ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์€ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ +์˜ˆ์ƒ์น˜ ๋ชปํ•œ ํ˜•๋ณ€ํ™˜ ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•˜์—ฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ•์ œ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ๋Š” ๋ณด์•ˆ +๋ฆฌ์Šคํฌ์ž„์„ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค. +**Prevention:** ๋Œ€ํ™”ํ˜• ํ”„๋กฌํ”„ํŠธ๋‚˜ ํ…์ŠคํŠธ ๊ธฐ๋ฐ˜ ์ž…๋ ฅ์—์„œ ์ •์ˆ˜ํ˜• ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ +์ „์—, ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ์ •ํ™•ํ•œ ๊ฐ’(์˜ˆ: `^[12]$`)์— ๋Œ€ํ•ด์„œ๋งŒ ์—„๊ฒฉํ•˜๊ฒŒ ์ •๊ทœ์‹ ๋งค์นญ์„ +์ˆ˜ํ–‰ํ•˜๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. From 82480aadf0e1900cec97271f4aacf52f95f60ce4 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Mon, 10 Aug 2026 15:50:25 +0000 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20readlin?= =?UTF-8?q?e=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EA=B0=95=ED=99=94=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20=EC=A0=95=EC=88=98=20=EC=98=A4=EB=B2=84=ED=94=8C?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0=20=EB=B0=A9=EC=A7=80=20(Fix=20integer=20over?= =?UTF-8?q?flow=20coercion)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๐Ÿšจ Severity: HIGH ๐Ÿ’ก Vulnerability: readline() ํ”„๋กฌํ”„ํŠธ์—์„œ ^[0-9]+$ ์ •๊ทœํ‘œํ˜„์‹์œผ๋กœ ๋ฌด์ œํ•œ ์ˆซ์ž๋ฅผ ํ—ˆ์šฉํ•˜์—ฌ ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋งค์šฐ ํฐ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•  ์‹œ as.integer()์—์„œ NA๋กœ ๊ฐ•์ œ ํ˜•๋ณ€ํ™˜๋˜๋ฉด์„œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ•์ œ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ๋Š” ์ •์ˆ˜ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐ ๊ฐ•์ œ ๋ณ€ํ™˜ ์ทจ์•ฝ์  ๐ŸŽฏ Impact: ์ž˜๋ชป๋œ ์ž…๋ ฅ์œผ๋กœ ์ธํ•œ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜ ๋ฐ DoS ์œ„ํ—˜ ๐Ÿ”ง Fix: ๊ธฐ๋Œ€ํ•˜๋Š” ์ž…๋ ฅ๊ฐ’(1 ๋˜๋Š” 2)์˜ ๋ฒ”์œ„์— ๋งž์ถฐ ์—„๊ฒฉํ•œ ์ •๊ทœ์‹ ๋งค์นญ(^[12]$)์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๊ฒ€์ฆ ๋กœ์ง ๊ฐ•ํ™” โœ… Verification: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ •์ƒ ์ž‘๋™ ๋ฐ ํšŒ๊ท€ ์˜ค๋ฅ˜ ์—†์Œ์„ ํ™•์ธ (testthat ํ†ต๊ณผ)