mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-09-04 09:27:15 +00:00
fix(frontend): tolerate a malformed happyEyeballs value in the Xray Basics tab
BasicsTab derived directHappyEyeballs by calling HappyEyeballsSchema.parse during render, guarding only against null/non-object. A wrong-typed field (e.g. happyEyeballs.tryDelayMs as a string) or any other shape mismatch — reachable via the Complete Template JSON editor or an imported config — threw straight out of render, white-screening the default Xray landing tab. Use safeParse and fall back to null so a bad value degrades to "no override" instead of crashing the page.
This commit is contained in:
@@ -115,7 +115,8 @@ export default function BasicsTab({
|
|||||||
?.sockopt;
|
?.sockopt;
|
||||||
const raw = sockopt?.happyEyeballs;
|
const raw = sockopt?.happyEyeballs;
|
||||||
if (raw == null || typeof raw !== 'object') return null;
|
if (raw == null || typeof raw !== 'object') return null;
|
||||||
return HappyEyeballsSchema.parse(raw);
|
const parsed = HappyEyeballsSchema.safeParse(raw);
|
||||||
|
return parsed.success ? parsed.data : null;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const setDirectHappyEyeballs = useCallback(
|
const setDirectHappyEyeballs = useCallback(
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { describe, it, expect, vi } from 'vitest';
|
||||||
|
|
||||||
|
import BasicsTab from '@/pages/xray/basics/BasicsTab';
|
||||||
|
import type { XraySettingsValue } from '@/hooks/useXraySetting';
|
||||||
|
|
||||||
|
import { renderWithProviders } from './test-utils';
|
||||||
|
|
||||||
|
function settingsWithMalformedHappyEyeballs(): XraySettingsValue {
|
||||||
|
return {
|
||||||
|
outbounds: [
|
||||||
|
{
|
||||||
|
protocol: 'freedom',
|
||||||
|
tag: 'direct',
|
||||||
|
streamSettings: { sockopt: { happyEyeballs: { tryDelayMs: 'fast' } } },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} as unknown as XraySettingsValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('BasicsTab malformed happyEyeballs', () => {
|
||||||
|
it('renders instead of white-screening on a wrong-typed happyEyeballs value', () => {
|
||||||
|
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
expect(() =>
|
||||||
|
renderWithProviders(
|
||||||
|
<BasicsTab
|
||||||
|
templateSettings={settingsWithMalformedHappyEyeballs()}
|
||||||
|
setTemplateSettings={vi.fn()}
|
||||||
|
outboundTestUrl=""
|
||||||
|
onChangeOutboundTestUrl={vi.fn()}
|
||||||
|
onResetDefault={vi.fn()}
|
||||||
|
/>,
|
||||||
|
),
|
||||||
|
).not.toThrow();
|
||||||
|
errorSpy.mockRestore();
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user