mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-12 09:36:27 +00:00
firmware/installPybricksDialog: add basic metadata check
This will catch some errors. Mainly this is to ensure we show an error if someone tries to use, e.g. a NXT firmware file that isn't supported in Pybricks Code yet. Error message isn't great but we don't expect this to be hit often, if ever, by non-developers.
This commit is contained in:
committed by
David Lechner
parent
c8bcddbffd
commit
13c69918e1
@@ -14,6 +14,7 @@ import { useIsMounted } from 'usehooks-ts';
|
||||
import { alertsShowAlert } from '../../alerts/actions';
|
||||
import { Hub } from '../../components/hubPicker';
|
||||
import { ensureError } from '../../utils';
|
||||
import { validateMetadata } from './';
|
||||
|
||||
export type FirmwareData = {
|
||||
firmwareZip: ArrayBuffer;
|
||||
@@ -175,6 +176,9 @@ export function useCustomFirmware(zipFile: File | undefined) {
|
||||
const reader = await FirmwareReader.load(firmwareZip);
|
||||
const licenseText = await reader.readReadMeOss();
|
||||
const metadata = await reader.readMetadata();
|
||||
|
||||
validateMetadata(metadata);
|
||||
|
||||
const data = {
|
||||
firmwareZip,
|
||||
licenseText,
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2023 The Pybricks Authors
|
||||
|
||||
import { validateMetadata } from '.';
|
||||
|
||||
describe('validateMetadata', () => {
|
||||
it('should accept 1.x firmware metadata', () => {
|
||||
expect(() =>
|
||||
validateMetadata({
|
||||
'metadata-version': '1.0.0',
|
||||
'device-id': 0x40,
|
||||
'firmware-version': '3.0.0',
|
||||
'checksum-type': 'sum',
|
||||
'max-firmware-size': 100000,
|
||||
'mpy-abi-version': 6,
|
||||
'mpy-cross-options': ['-mno-unicode'],
|
||||
'user-mpy-offset': 90000,
|
||||
}),
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('should accept 2.x firmware metadata', () => {
|
||||
expect(() =>
|
||||
validateMetadata({
|
||||
'metadata-version': '2.0.0',
|
||||
'device-id': 0x40,
|
||||
'firmware-version': '3.0.0',
|
||||
'checksum-type': 'sum',
|
||||
'checksum-size': 100000,
|
||||
'hub-name-offset': 100000 - 16,
|
||||
'hub-name-size': 16,
|
||||
}),
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('should reject 3.x firmware metadata', () => {
|
||||
expect(() =>
|
||||
validateMetadata({
|
||||
// @ts-expect-error: testing bad data
|
||||
'metadata-version': '3.0.0',
|
||||
'device-id': 0x40,
|
||||
'firmware-version': '3.0.0',
|
||||
'checksum-type': 'sum',
|
||||
'checksum-size': 100000,
|
||||
'hub-name-offset': 100000 - 16,
|
||||
'hub-name-size': 16,
|
||||
}),
|
||||
).toThrow(/"metadata-version"/);
|
||||
});
|
||||
|
||||
it('should reject unsupported device id', () => {
|
||||
expect(() =>
|
||||
validateMetadata({
|
||||
'metadata-version': '2.0.0',
|
||||
'device-id': 0xe0,
|
||||
'firmware-version': '3.0.0',
|
||||
'checksum-type': 'sum',
|
||||
'checksum-size': 100000,
|
||||
'hub-name-offset': 100000 - 16,
|
||||
'hub-name-size': 16,
|
||||
}),
|
||||
).toThrow(/"device-id"/);
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,8 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2022 The Pybricks Authors
|
||||
// Copyright (c) 2022-2023 The Pybricks Authors
|
||||
|
||||
import { FirmwareMetadata, HubType } from '@pybricks/firmware';
|
||||
import * as semver from 'semver';
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
@@ -18,3 +21,27 @@ export function validateHubName(hubName: string): boolean {
|
||||
// user earlier for better UX.
|
||||
return encoded.length < 16;
|
||||
}
|
||||
|
||||
const supportHubs: readonly HubType[] = [
|
||||
HubType.MoveHub,
|
||||
HubType.CityHub,
|
||||
HubType.TechnicHub,
|
||||
HubType.PrimeHub,
|
||||
HubType.EssentialHub,
|
||||
];
|
||||
|
||||
export function validateMetadata(metadata: FirmwareMetadata) {
|
||||
if (semver.satisfies(metadata['metadata-version'], '^1')) {
|
||||
if (!supportHubs.includes(metadata['device-id'])) {
|
||||
throw new Error(`"unsupported "device-id": ${metadata['device-id']}`);
|
||||
}
|
||||
} else if (semver.satisfies(metadata['metadata-version'], '^2')) {
|
||||
if (!supportHubs.includes(metadata['device-id'])) {
|
||||
throw new Error(`"unsupported "device-id": ${metadata['device-id']}`);
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
`unsupported "metadata-version": "${metadata['metadata-version']}"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user