Skip to content

Commit 39241b0

Browse files
committed
Addition logic to check whether sheet name is validate
1 parent 63185f7 commit 39241b0

File tree

2 files changed

+146
-1
lines changed

2 files changed

+146
-1
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<queries>
3+
<excel db="sampleDB" output="d:/temp/시트명검증_테스트.xlsx">
4+
</excel>
5+
6+
<!-- 정상적인 시트명 -->
7+
<sheet name="정상_시트명" use="true">
8+
<![CDATA[
9+
SELECT '정상' as 상태
10+
]]>
11+
</sheet>
12+
13+
<!-- 허용되지 않는 문자 포함: 백슬래시 -->
14+
<sheet name="잘못된\시트명" use="true">
15+
<![CDATA[
16+
SELECT '백슬래시 포함' as 상태
17+
]]>
18+
</sheet>
19+
20+
<!-- 허용되지 않는 문자 포함: 슬래시 -->
21+
<sheet name="잘못된/시트명" use="true">
22+
<![CDATA[
23+
SELECT '슬래시 포함' as 상태
24+
]]>
25+
</sheet>
26+
27+
<!-- 허용되지 않는 문자 포함: 콜론 -->
28+
<sheet name="잘못된:시트명" use="true">
29+
<![CDATA[
30+
SELECT '콜론 포함' as 상태
31+
]]>
32+
</sheet>
33+
34+
<!-- 허용되지 않는 문자 포함: 별표 -->
35+
<sheet name="잘못된*시트명" use="true">
36+
<![CDATA[
37+
SELECT '별표 포함' as 상태
38+
]]>
39+
</sheet>
40+
41+
<!-- 허용되지 않는 문자 포함: 물음표 -->
42+
<sheet name="잘못된?시트명" use="true">
43+
<![CDATA[
44+
SELECT '물음표 포함' as 상태
45+
]]>
46+
</sheet>
47+
48+
<!-- 허용되지 않는 문자 포함: 대괄호 -->
49+
<sheet name="잘못된[시트명]" use="true">
50+
<![CDATA[
51+
SELECT '대괄호 포함' as 상태
52+
]]>
53+
</sheet>
54+
55+
<!-- 31자 초과 -->
56+
<sheet name="이것은매우긴시트명으로31자를초과합니다" use="true">
57+
<![CDATA[
58+
SELECT '31자 초과' as 상태
59+
]]>
60+
</sheet>
61+
62+
<!-- 앞뒤 공백 -->
63+
<sheet name=" 앞뒤공백 " use="true">
64+
<![CDATA[
65+
SELECT '앞뒤 공백' as 상태
66+
]]>
67+
</sheet>
68+
69+
<!-- 정상적인 시트명 (한글) -->
70+
<sheet name="한글_시트명_테스트" use="true">
71+
<![CDATA[
72+
SELECT '한글 정상' as 상태
73+
]]>
74+
</sheet>
75+
76+
<!-- 정상적인 시트명 (숫자 포함) -->
77+
<sheet name="시트_123" use="true">
78+
<![CDATA[
79+
SELECT '숫자 포함' as 상태
80+
]]>
81+
</sheet>
82+
</queries>
83+

src/query-parser.js

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,46 @@ class QueryParser {
1111
this.fileUtils = FileUtils;
1212
}
1313

14+
/**
15+
* 시트명 유효성 검증
16+
* @param {string} sheetName - 검증할 시트명
17+
* @param {number} sheetIndex - 시트 인덱스 (에러 메시지용)
18+
* @returns {Object} { valid: boolean, errors: string[] }
19+
*/
20+
validateSheetName(sheetName, sheetIndex = 0) {
21+
const errors = [];
22+
23+
// Excel 시트명에 사용할 수 없는 문자
24+
const invalidChars = ['\\', '/', '*', '?', '[', ']', ':'];
25+
26+
// 1. 빈 문자열 체크
27+
if (!sheetName || sheetName.trim() === '') {
28+
errors.push('시트명이 비어있습니다.');
29+
return { valid: false, errors };
30+
}
31+
32+
// 2. 최대 길이 체크 (31자)
33+
if (sheetName.length > 31) {
34+
errors.push(`시트명이 너무 깁니다 (최대 31자, 현재: ${sheetName.length}자)`);
35+
}
36+
37+
// 3. 허용되지 않는 문자 체크
38+
const foundInvalidChars = invalidChars.filter(char => sheetName.includes(char));
39+
if (foundInvalidChars.length > 0) {
40+
errors.push(`허용되지 않는 문자 포함: ${foundInvalidChars.join(', ')}`);
41+
}
42+
43+
// 4. 시트명 시작/끝 공백 체크
44+
if (sheetName !== sheetName.trim()) {
45+
errors.push('시트명 앞뒤에 공백이 있습니다.');
46+
}
47+
48+
return {
49+
valid: errors.length === 0,
50+
errors
51+
};
52+
}
53+
1454
/**
1555
* XML 파일에서 쿼리 로드
1656
* @param {string} xmlPath - XML 파일 경로
@@ -148,6 +188,17 @@ class QueryParser {
148188
}
149189
}
150190

191+
// 시트명 검증
192+
const sheetNameValidation = this.validateSheetName(s.$.name, i);
193+
if (!sheetNameValidation.valid) {
194+
console.error(`\n❌ 시트명 검증 실패 (시트 #${i + 1}):`);
195+
console.error(` 시트명: "${s.$.name}"`);
196+
sheetNameValidation.errors.forEach(error => {
197+
console.error(` - ${error}`);
198+
});
199+
throw new Error(`시트명 검증 실패: "${s.$.name}"`);
200+
}
201+
151202
// queryRef 속성이 있으면 쿼리 정의에서 참조
152203
if (s.$.queryRef) {
153204
const queryRef = s.$.queryRef;
@@ -202,10 +253,21 @@ class QueryParser {
202253
const dynamicVars = queries.dynamicVars || [];
203254

204255
// JSON 시트에서 queryRef 처리
205-
const sheets = (queries.sheets || []).map(sheet => {
256+
const sheets = (queries.sheets || []).map((sheet, i) => {
206257
let query = sheet.query || '';
207258
let sheetParams = sheet.params || {};
208259

260+
// 시트명 검증
261+
const sheetNameValidation = this.validateSheetName(sheet.name, i);
262+
if (!sheetNameValidation.valid) {
263+
console.error(`\n❌ 시트명 검증 실패 (시트 #${i + 1}):`);
264+
console.error(` 시트명: "${sheet.name}"`);
265+
sheetNameValidation.errors.forEach(error => {
266+
console.error(` - ${error}`);
267+
});
268+
throw new Error(`시트명 검증 실패: "${sheet.name}"`);
269+
}
270+
209271
// queryRef가 있으면 쿼리 정의에서 참조
210272
if (sheet.queryRef) {
211273
if (queryDefs[sheet.queryRef]) {

0 commit comments

Comments
 (0)