From 09147f137866aa1e689bf8a6cfb63e65dd93017c Mon Sep 17 00:00:00 2001 From: Gandalf Date: Fri, 12 Dec 2025 10:15:49 +0100 Subject: [PATCH] Add regex fallback for WASM isValidAccountName failures TEMPORARY WORKAROUND for wax WASM thread-safety issue. The wax WASM module isn't thread-safe - concurrent Server Component requests calling chain.isValidAccountName() cause memory corruption: "RuntimeError: memory access out of bounds" This fix: - Keeps wax as primary validation method - Catches WASM errors and falls back to regex validation - Logs warnings when fallback is used (helps track issue frequency) - Documents as temporary with TODO and issue references Once wax#140 is resolved, remove the try/catch and regex fallback. Related: #758 See also: https://gitlab.syncad.com/hive/wax/-/issues/140 --- apps/blog/utils/validate-links.ts | 66 ++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/apps/blog/utils/validate-links.ts b/apps/blog/utils/validate-links.ts index fec5dfefc..68b701654 100644 --- a/apps/blog/utils/validate-links.ts +++ b/apps/blog/utils/validate-links.ts @@ -1,12 +1,74 @@ import { getChain } from '@hive/transaction/lib/chain'; +import { getLogger } from '@ui/lib/logging'; + +const logger = getLogger('app'); export function isPermlinkValid(permlink: string): boolean { if (typeof permlink !== 'string') return false; return /^[a-z0-9-]{1,255}$/.test(permlink); } +/** + * Validates Hive account names using wax library with regex fallback. + * + * TEMPORARY WORKAROUND: The wax WASM module isn't thread-safe - concurrent + * Server Component requests cause "memory access out of bounds" errors. + * We catch WASM errors and fall back to regex validation until wax is fixed. + * + * @see https://gitlab.syncad.com/hive/denser/-/issues/758 + * @see https://gitlab.syncad.com/hive/wax/-/issues/140 + * + * TODO: Remove regex fallback once wax thread-safety is resolved + */ export async function isUsernameValid(accountName: string): Promise { if (typeof accountName !== 'string') return false; - const chain = await getChain(); - return chain.isValidAccountName(accountName); + + try { + const chain = await getChain(); + return chain.isValidAccountName(accountName); + } catch (error) { + // TEMPORARY: Log WASM failure and fall back to regex validation + // See: https://gitlab.syncad.com/hive/wax/-/issues/140 + logger.warn({ err: error, accountName }, 'WASM isValidAccountName failed, using regex fallback'); + return isUsernameValidRegex(accountName); + } +} + +/** + * Regex fallback for Hive account name validation. + * Used when wax WASM fails due to concurrent access. + * + * Rules based on Hive blockchain consensus: + * - 3-16 characters + * - Lowercase letters, numbers, dots, hyphens only + * - Must start with a letter + * - Cannot end with hyphen or dot + * - Each segment (separated by dots) must start with a letter + * - No consecutive dots or hyphens + * + * TODO: Remove once wax thread-safety is resolved (see wax#140) + */ +function isUsernameValidRegex(accountName: string): boolean { + if (accountName.length < 3 || accountName.length > 16) return false; + + // Must contain only lowercase letters, numbers, dots, and hyphens + if (!/^[a-z0-9.-]+$/.test(accountName)) return false; + + // Must start with a letter + if (!/^[a-z]/.test(accountName)) return false; + + // Cannot end with hyphen or dot + if (/[.-]$/.test(accountName)) return false; + + // No consecutive dots or hyphens + if (/[.-]{2}/.test(accountName)) return false; + + // Each segment must start with a letter + const segments = accountName.split('.'); + for (const segment of segments) { + if (segment.length === 0) return false; + if (!/^[a-z]/.test(segment)) return false; + } + + return true; } -- GitLab