fix: bound custom URL length before persistence

This commit is contained in:
dajiaohuang 2026-09-22 04:11:33 +08:00 committed by Jake Turner
parent a915cdcfc9
commit 7dabc40c85
4 changed files with 24 additions and 4 deletions

View File

@ -101,7 +101,7 @@ export const customAppValidator = vine.compile(
export const setServiceCustomUrlValidator = vine.compile(
vine.object({
service_name: vine.string().trim(),
custom_url: vine.string().trim().nullable(),
custom_url: vine.string().trim().maxLength(255).nullable(),
})
)
@ -118,7 +118,10 @@ export function normalizeCustomUrl(input: string | null | undefined): string | n
try {
const url = new URL(withScheme)
if (url.protocol !== 'http:' && url.protocol !== 'https:') return null
return url.href
// services.custom_url uses the database driver's default VARCHAR(255) size.
// Check the normalized value because prepending a scheme or URL canonicalization
// can make a valid-looking input longer than the stored column.
return url.href.length <= 255 ? url.href : null
} catch {
return null
}

View File

@ -79,6 +79,7 @@ export default function AppUrlModal({ open, service, onClose, onSaved, showError
name="customUrl"
label="Custom URL"
placeholder="http://jellyfin.myhomelab.net"
maxLength={255}
value={value}
onChange={(e) => setValue(e.target.value)}
error={isInvalid}

View File

@ -13,7 +13,8 @@ export function normalizeCustomUrl(input: string | null | undefined): string | n
try {
const url = new URL(withScheme);
if (url.protocol !== 'http:' && url.protocol !== 'https:') return null;
return url.href;
// Keep the normalized value within services.custom_url's VARCHAR(255) column.
return url.href.length <= 255 ? url.href : null;
} catch {
return null;
}
@ -57,4 +58,4 @@ export function getServiceLink(ui_location: string, customUrl?: string | null):
}
return `/${ui_location}`;
}
}

View File

@ -0,0 +1,15 @@
import * as assert from 'node:assert/strict'
import { test } from 'node:test'
import { normalizeCustomUrl } from '../../app/validators/system.js'
test('rejects a normalized custom URL that exceeds the database column size', () => {
const tooLongHost = 'a'.repeat(247)
assert.equal(normalizeCustomUrl(`https://${tooLongHost}`), null)
})
test('accepts a normalized custom URL at the database column limit', () => {
const maxLengthHost = 'a'.repeat(246)
const normalized = normalizeCustomUrl(`https://${maxLengthHost}`)
assert.equal(normalized?.length, 255)
})