support JSONC comments in config profile validation#154
support JSONC comments in config profile validation#154chirizxc wants to merge 1 commit intoremnawave:mainfrom
JSONC comments in config profile validation#154Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
PR Summary
|
|
This will not work, Remnawave stores JSON as |
What if we added support for TOML? Xray can handle that type of configuration. |
Greptile SummaryThis PR adds support for JSONC (JSON with Comments) in config profile validation by replacing Confidence Score: 3/5Not safe to merge — invalid JSONC input silently bypasses error handling, and a TypeScript type mismatch between the new schema and the service signatures will break compilation. Two P1 issues: (1)
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[HTTP Request with config] --> B{Zod schema validation}
B -->|string JSONC| C[prevValidateConfig: string branch]
B -->|object| D[prevValidateConfig: object branch]
C --> E["jsonc-parser parse()"]
E -->|Valid JSONC| F[Returns IXrayConfig]
E -->|"Invalid JSONC - no throw!"| G["Returns undefined silently"]
G --> H["this.config = undefined"]
H --> I["validate() - TypeError on .inbounds"]
F --> J[validate]
D --> J
J --> K[resolveInbounds]
K --> L[Config accepted]
Reviews (1): Last reviewed commit: "support JSONC comments in config profile..." | Re-trigger Greptile |
| try { | ||
| config = JSON.parse(configInput) as IXrayConfig; | ||
| config = parse(configInput) as IXrayConfig; | ||
| } catch (error) { | ||
| throw new Error(`Invalid JSON input or file path: ${error}`); | ||
| throw new Error(`Invalid JSON/JSONC input: ${error}`); | ||
| } |
There was a problem hiding this comment.
jsonc-parser's parse() never throws — try-catch is dead code
According to the official jsonc-parser docs: "On invalid input, the parser tries to be as fault tolerant as possible, but still return a result. Therefore always check the errors list to find out if the input was valid."
parse() does not throw on invalid JSON/JSONC. It returns undefined (or a partial result) for completely invalid input and communicates errors through the optional second errors array argument. This means:
- The
catchblock is unreachable dead code for any malformed JSONC string - If the input is completely invalid,
parse()returnsundefined, soconfigends up asundefined, and the subsequentthis.config.inboundsaccess invalidate()causes a crypticTypeErrorinstead of the intended clear"Invalid JSON/JSONC input"message
The fix is to pass an errors array and check it explicitly:
import { parse, ParseError } from 'jsonc-parser';
if (typeof configInput === 'string') {
const errors: ParseError[] = [];
config = parse(configInput, errors) as IXrayConfig;
if (errors.length > 0) {
throw new Error(`Invalid JSON/JSONC input: error code ${errors[0].error} at offset ${errors[0].offset}`);
}
}| 'Name can only contain letters, numbers, underscores, dashes and spaces', | ||
| ), | ||
| config: z.object({}).passthrough(), | ||
| config: z.union([z.string(), z.object({}).passthrough()]), |
There was a problem hiding this comment.
Service signature not updated to accept
string
The Zod schema now infers config as string | Record<string, unknown>, but ConfigProfileService.createConfigProfile still declares config: object:
public async createConfigProfile(
name: string,
config: object, // ← only object, not string | object
)In TypeScript, string is not assignable to object, so passing createConfigProfileDto.config (which is string | Record<string, unknown>) to this method is a type error that will break compilation.
The service (and likewise updateConfigProfile) needs its signature updated:
public async createConfigProfile(
name: string,
config: string | object,
)The same applies to src/modules/config-profiles/config-profile.service.ts line 133 (createConfigProfile) and line 192 (updateConfigProfile).
https://github.com/microsoft/node-jsonc-parser