import { describe, expect, test } from 'vitest'; import { parseQzoneWebResponse } from '@/napcat-core/data/qzone-web'; const DOMAIN = 'document.domain="h5.qzone.qq.com";'; const ASSIGN_CALLBACK = 'cb=frameElement.callback;'; const TRY_SETUP = `var cb;try{${DOMAIN}${ASSIGN_CALLBACK}}catch(e){try{${DOMAIN}${ASSIGN_CALLBACK}}catch(e){${DOMAIN}${ASSIGN_CALLBACK}}}`; function html (script: string, doctype = true): string { return `${doctype ? '\n' : ''}\n
\n\n\n\n\n\n`; } function callback (value: unknown): string { return `frameElement.callback(${JSON.stringify(value)});`; } describe('QQ空间 inert FormSender envelopes', () => { test.each([ { code: 0, subcode: 0, data: '' }, { code: 0, subcode: 0, data: { name: 'Ack' } }, { code: 0, subcode: 0, data: { id: 0, content: 'synthetic reply', postTime: 1700000000 }, err: { code: 0 } }, ])('accepts the observed three-domain try/catch wrapper with a synthetic response (%j)', (response) => { for (const doctype of [true, false]) { expect(parseQzoneWebResponse(html(`${TRY_SETUP}\n${callback(response)}`, doctype), true)).toEqual(response); } }); test('accepts the upload domain preamble and explicit ret=0 without inventing code=0', () => { const response = { ret: 0, data: { url: 'https://images.example.test/upload.png', width: 20, height: 10 } }; const body = html(`${DOMAIN}${callback(response)}`, false); expect(parseQzoneWebResponse(body)).toEqual(response); expect(() => parseQzoneWebResponse(body, true)).toThrow('成功状态'); }); test('supports formatting and tag case without accepting extra attributes or syntax', () => { const setup = 'var cb ; try { document.domain = "h5.qzone.qq.com" ; cb = frameElement.callback ; } catch (e) { try { document.domain="h5.qzone.qq.com"; cb=frameElement.callback; } catch(e) { document.domain="h5.qzone.qq.com"; cb=frameElement.callback; } }'; const body = html(`${setup}\n frameElement.callback ( { "code": 0 } ) ;`) .replace('', '') .replace('http-equiv="content-type"', 'http-equiv="Content-Type"') .replace('charset=utf-8', 'charset=UTF-8') .replace(' />', '/>'); expect(parseQzoneWebResponse(body, true)).toEqual({ code: 0 }); }); test('treats callback-looking content as data and preserves existing Ack normalization', () => { const response = { code: 0, data: { content: 'var cb; document.domain="other.test"; callback({"code":-1});', braces: '{}[]()' } }; expect(parseQzoneWebResponse(html(`${TRY_SETUP}${callback(response)}`))).toEqual(response); expect(parseQzoneWebResponse(html(`${DOMAIN}frameElement.callback({"ret":0,"data":{name:"Ack"}});`))) .toEqual({ ret: 0, data: { name: 'Ack' } }); }); test.each(['Example Space', '', '合成空间名称', 'quote " and slash \\', 'line one\nline two', '}; callback({"code":-1});'])('accepts the observed bare name string key without changing its value (%j)', (name) => { const payload = `{"code":0,"subcode":0,"message":"","default":0,"data":{name:${JSON.stringify(name)}}}`; const body = html(`${TRY_SETUP}frameElement.callback(${payload});`); expect(parseQzoneWebResponse(body, true)).toEqual({ code: 0, subcode: 0, message: '', default: 0, data: { name } }); }); test('normalizes only object keys and preserves name-looking text inside JSON strings', () => { const content = '{name:"Example"}, name:"Ack", escaped quote \\"'; const payload = `{"code":0,"data":{"content":${JSON.stringify(content)},name:"Example","nested":[{name:"Nested"}]}}`; expect(parseQzoneWebResponse(html(`${DOMAIN}frameElement.callback(${payload});`))) .toEqual({ code: 0, data: { content, name: 'Example', nested: [{ name: 'Nested' }] } }); }); test.each([ '{"code":0,"data":{name:1}}', '{"code":0,"data":{name:null}}', '{"code":0,"data":{name:false}}', '{"code":0,"data":{name:["Example"]}}', '{"code":0,"data":{name:{"value":"Example"}}}', '{"code":0,"data":{name:someName}}', '{"code":0,"data":{name:"Example"+"suffix"}}', '{"code":0,"data":{name:("Example")}}', '{"code":0,"data":{name:\'Example\'}}', '{"code":0,"data":{other:"Example"}}', '{"code":0,"data":{namex:"Example"}}', '{"code":0,"data":[name:"Example"]}', '{"code":0,"data":{name:"Example",other:"value"}}', '{"code":-1,"\\u0063ode":0,"data":{name:"Example"}}', '{"code":0,"subcode":-1,"data":{name:"Example"}}', ])('does not extend bare-name compatibility to other syntax or failed statuses (%s)', (payload) => { expect(() => parseQzoneWebResponse(html(`${TRY_SETUP}frameElement.callback(${payload});`))).toThrow(); }); test.each([ html(`${TRY_SETUP}${callback({ code: 0 })}`).replace('', ''), html(`${TRY_SETUP}${callback({ code: 0 })}`).replace('', ''), html(`${TRY_SETUP}${callback({ code: 0 })}`).replace('', '