Skip to content

Conversation

@Starrah
Copy link
Contributor

@Starrah Starrah commented Jan 28, 2026

2025年挖过的坑,现在开始填。
draft状态, NOT ready for review

  • 对现有的,仅支持MA2格式的replaceChart功能进行重构
  • 复用 ImportChartCheckApi ,这样在替换maidata.txt谱面前,也去做和导入新的类似的语法检查
  • 导入新谱面时会把导入模式存在XML的自定义字段中
  • 使 ReplaceChartModal 可以显示上述语法检查结果,和选择导入模式
    • 导入模式会尝试从XML中读取,读到了就不用用户选了,没读到(即老版本已经存在的谱面)则需要用户选择
  • 修改后端ReplaceChartApi,支持导入maidata(大概在此之前需要对ImportChart进行些小重构、逻辑通用的部分抽取出来之类的)

…是普通的导入谱面功能发起的。

2. ReplaceChart新增参数shift,仅在导入的是MA2时需要传入,表示延迟调整模式。
3. 并进一步重构 ReplaceChartModal.tsx,确保原来的直接替换MA2功能可用的同时,预留新功能的空间。
@gemini-code-assist
Copy link

Summary of Changes

Hello @Starrah, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求旨在扩展现有谱面替换功能,使其能够处理maidata.txt格式的谱面,而不仅仅是MA2格式。通过复用导入时的语法检查逻辑,确保替换的maidata.txt谱面质量。此外,还引入了将导入模式存储到音乐XML元数据中的机制,并对前端UI进行了调整,以更好地支持不同文件类型的替换流程,并为用户提供了关于替换功能适用范围的明确警告。

Highlights

  • 谱面替换功能重构: 重构了现有的谱面替换功能,使其不仅支持MA2格式,还初步支持maidata.txt格式的谱面替换。
  • 引入语法检查: 在替换maidata.txt谱面之前,复用了ImportChartCheckApi进行语法检查,确保替换的谱面符合规范。
  • 导入模式存储: 在导入新谱面时,会将导入模式(ShiftMethod)存储到XML的自定义字段中,以便后续读取和使用。
  • 前端交互优化: 前端界面现在能够区分处理MA2和maidata.txt文件,并为maidata.txt文件显示检查模态框,同时新增了“替换谱面”按钮。
  • MA2谱面音符数量修正: 替换MA2谱面时,会自动检查并修正谱面中的音符总数(MaxNotes)。
  • XML节点操作简化: 引入了SelectSingleNodeOrCreate辅助方法,简化了XML文档中节点的存在性检查和创建逻辑。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This PR aims to refactor the replaceChart functionality to support maidata.txt charts, enhancing both backend API logic and frontend UI. However, a security audit revealed two significant vulnerabilities in ChartController.cs: a Denial of Service (DoS) risk from reading large files into memory without validation, and a Path Traversal vulnerability allowing arbitrary file overwrites due to unsanitized assetDir parameters. Addressing these security issues is critical. Additionally, there are opportunities to improve the efficiency and robustness of backend file processing.

Comment on lines +98 to +99
public void ReplaceChart(int id, int level, IFormFile file, string assetDir,
[FromForm] ImportChartController.ShiftMethod? shift)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The assetDir parameter, which is a route parameter and thus user-controlled, is used to construct file paths using Path.Combine (e.g., on line 106) without any validation or sanitization. An attacker can provide a path containing directory traversal sequences (e.g., ..) to escape the intended directory and overwrite arbitrary files on the server where the application has write permissions.

Remediation: Validate the assetDir parameter against an allowlist of expected directory names or sanitize it to remove any path traversal sequences before using it in file system operations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@clansty 这个用管吗😰 虽然他说有问题的这段并不是我写的,我只是加了个shift参数而已(

string fileContent;
using (var reader = new StreamReader(file.OpenReadStream()))
{
fileContent = reader.ReadToEnd();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The ReplaceChart method at this line reads the entire content of an uploaded file into memory using reader.ReadToEnd() without any size validation. This creates a Denial of Service (DoS) risk, as a large file could lead to an OutOfMemoryException and application crash, especially when passed to ParseTNumAllFromMa2. Additionally, the current implementation has two code quality issues: it attempts to read the file stream multiple times (file.CopyTo(stream) then file.OpenReadStream()), which can cause errors with non-seekable streams, and it includes a redundant stream.Close() within a using statement. It is recommended to implement a maximum file size limit, process files using a stream-based approach, and refactor to read the file content only once for both writing and parsing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个不用太管吧,后端是在用户自己的电脑上运行的,我DoS我自己吗?

const checkRet = (await api.ImportChartCheck({file, isReplacement: true})).data;
if (!checking.value) return; // 说明检查期间用户点击了关闭按钮、取消了操作。则不再执行后续流程。
// TODO 显示导入界面(类似ErrorDisplayIdInput)、完成导入流程
console.log(checkRet)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

这里有一个 console.log 语句,可能是用于调试的。在代码最终合并之前,建议移除这些调试相关的日志输出,以保持生产环境代码的整洁。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant