Index: reference/jquery-plugins/select2-4.0.13/src/scss/theme/default/layout.scss =================================================================== diff -u -rb3c2413568d9b6e23eb808ec7adf7e4f43f3af9e -rb06daf4899ec2ab5c3e9f84ae2b5df0dda007564 --- reference/jquery-plugins/select2-4.0.13/src/scss/theme/default/layout.scss (.../layout.scss) (revision b3c2413568d9b6e23eb808ec7adf7e4f43f3af9e) +++ reference/jquery-plugins/select2-4.0.13/src/scss/theme/default/layout.scss (.../layout.scss) (revision b06daf4899ec2ab5c3e9f84ae2b5df0dda007564) @@ -1796,10 +1796,30 @@ const targets = document.querySelectorAll("[data-locale]"); targets.forEach((tag) => { - tag.textContent = locales[tag.dataset.locale]; + const content = locales[tag.dataset.locale]; + if (isIncludeHTMLTag(content)) { + tag.innerHTML = sanitizeHTML(content); + } else { + tag.textContent = content; + } }); } +function isIncludeHTMLTag(content) { + return /<\/?[a-z][\s\S]*>/i.test(content); +} + +function sanitizeHTML(content) { + const allowedTags = ['span', 'small', 'strong', 'p', 'b', 'ul', 'li']; + return content.replace(/<(\w+)[^>]*>|<\/(\w+)>/g, (match, openTag, closeTag) => { + const tagName = (openTag || closeTag).toLowerCase(); + if (allowedTags.includes(tagName)) { + return match.replace(/ on\w+="[^"]*"| on\w+='[^']*'/g, ''); // 이벤트 핸들러 속성 제거 + } + return ''; // 허용되지 않은 태그 제거 + }); +} + function flattenObject(obj, parentKey) { let result = {};