fix(learning): remove archive size validation
This commit is contained in:
@@ -2,7 +2,6 @@ import { app, dialog, type SaveDialogOptions } from 'electron';
|
||||
import type { IncomingMessage, ServerResponse } from 'node:http';
|
||||
import { join } from 'node:path';
|
||||
import {
|
||||
LEARNING_ARCHIVE_MAX_BYTES,
|
||||
LEARNING_MEDIA_MAX_BYTES,
|
||||
type LearningProjectDetail,
|
||||
} from '../../../shared/learning';
|
||||
@@ -166,7 +165,7 @@ function projectSummary(value: unknown): Record<string, unknown> {
|
||||
cover: projectImage(project.cover),
|
||||
tags,
|
||||
version: nullableString(project.version, 64),
|
||||
archiveBytes: boundedInteger(project.archiveBytes, 1, LEARNING_ARCHIVE_MAX_BYTES),
|
||||
archiveBytes: boundedInteger(project.archiveBytes, 1, Number.MAX_SAFE_INTEGER),
|
||||
publishedAt: isoTimestamp(project.publishedAt),
|
||||
updatedAt: isoTimestamp(project.updatedAt),
|
||||
};
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import { createHash, randomUUID } from 'node:crypto';
|
||||
import { open, rename, rm } from 'node:fs/promises';
|
||||
import { basename, dirname, extname, join } from 'node:path';
|
||||
import {
|
||||
LEARNING_ARCHIVE_MAX_BYTES,
|
||||
type LearningProjectDetail,
|
||||
} from '../../shared/learning';
|
||||
import type { LearningProjectDetail } from '../../shared/learning';
|
||||
import type { WorksSquareAccountBinding } from './works-square-session';
|
||||
|
||||
const PROJECT_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
||||
@@ -53,9 +50,6 @@ function assertCurrentAccount(
|
||||
|
||||
function validateProject(project: LearningProjectDetail): void {
|
||||
if (!PROJECT_ID_PATTERN.test(project.id)
|
||||
|| !Number.isSafeInteger(project.archiveBytes)
|
||||
|| project.archiveBytes <= 0
|
||||
|| project.archiveBytes > LEARNING_ARCHIVE_MAX_BYTES
|
||||
|| !SHA256_PATTERN.test(project.archiveSha256)) {
|
||||
throw new LearningProjectDownloadError(502, 'LEARNING_PROJECT_INVALID', '项目下载信息无效');
|
||||
}
|
||||
@@ -122,26 +116,15 @@ async function writeVerifiedArchive(input: {
|
||||
await input.response.body.cancel().catch(() => undefined);
|
||||
throw new LearningProjectDownloadError(502, 'LEARNING_ARCHIVE_MIME_INVALID', '项目压缩包类型无效');
|
||||
}
|
||||
const declaredLength = Number(input.response.headers.get('content-length'));
|
||||
if (Number.isFinite(declaredLength) && declaredLength !== input.project.archiveBytes) {
|
||||
await input.response.body.cancel().catch(() => undefined);
|
||||
throw new LearningProjectDownloadError(502, 'LEARNING_ARCHIVE_SIZE_MISMATCH', '项目压缩包大小校验失败');
|
||||
}
|
||||
|
||||
const handle = await open(input.temporaryPath, 'wx');
|
||||
const hash = createHash('sha256');
|
||||
const signature: number[] = [];
|
||||
let bytes = 0;
|
||||
const reader = input.response.body.getReader();
|
||||
try {
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
assertCurrentAccount(input.binding, input.isCurrentAccountBinding);
|
||||
bytes += value.byteLength;
|
||||
if (bytes > input.project.archiveBytes || bytes > LEARNING_ARCHIVE_MAX_BYTES) {
|
||||
throw new LearningProjectDownloadError(502, 'LEARNING_ARCHIVE_SIZE_MISMATCH', '项目压缩包大小校验失败');
|
||||
}
|
||||
for (const byte of value.subarray(0, Math.max(0, 4 - signature.length))) signature.push(byte);
|
||||
hash.update(value);
|
||||
await handle.write(value);
|
||||
@@ -151,9 +134,6 @@ async function writeVerifiedArchive(input: {
|
||||
await handle.close();
|
||||
}
|
||||
|
||||
if (bytes !== input.project.archiveBytes) {
|
||||
throw new LearningProjectDownloadError(502, 'LEARNING_ARCHIVE_SIZE_MISMATCH', '项目压缩包大小校验失败');
|
||||
}
|
||||
if (signature.length < 4 || signature[0] !== 0x50 || signature[1] !== 0x4b
|
||||
|| !((signature[2] === 0x03 && signature[3] === 0x04)
|
||||
|| (signature[2] === 0x05 && signature[3] === 0x06)
|
||||
|
||||
Reference in New Issue
Block a user