{"version":3,"file":"appImageUtil.js","sourceRoot":"","sources":["../../../src/targets/appimage/appImageUtil.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arch, copyDir, copyFile, exec, exists, InvalidConfigurationError, log } from \"builder-util\"\nimport * as fs from \"fs-extra\"\nimport * as path from \"path\"\nimport { FileAssociation } from \"../../options/FileAssociation\"\nimport { IconInfo } from \"../../platformPackager\"\nimport { getAppImageTools } from \"../../toolsets/linux\"\nimport { copyIcons, copyMimeTypes } from \"./appLauncher\"\nimport { appendBlockmap } from \"../differentialUpdateInfoBuilder\"\nimport { BlockMapDataHolder } from \"builder-util-runtime\"\nimport { APP_RUN_ENTRYPOINT } from \"./AppImageTarget\"\n\ninterface Options {\n  productName: string\n  productFilename: string\n  executableName: string\n  desktopEntry: string\n  icons: IconInfo[]\n  license?: string | null\n  fileAssociations: FileAssociation[]\n  compression?: \"xz\" | \"lzo\" | \"zstd\"\n}\n\nexport interface AppImageBuilderOptions {\n  appDir: string\n  stageDir: string\n  arch: Arch\n  output: string\n  options: Options\n}\n\nexport async function buildAppImage(opts: AppImageBuilderOptions): Promise<BlockMapDataHolder> {\n  const { stageDir, output, appDir, options, arch } = opts\n\n  try {\n    await fs.remove(output)\n\n    // Write AppRun launcher and related files\n    await writeAppLauncherAndRelatedFiles(opts)\n\n    const { runtimeLibraries: libraries, runtime, mksquashfs } = await getAppImageTools(arch)\n    await copyDir(libraries, path.join(stageDir, \"usr\", \"lib\"))\n\n    // Copy app directory to stage\n    // mksquashfs doesn't support merging, so we copy the entire app dir\n    await copyDir(appDir, stageDir)\n\n    const runtimeData = await fs.readFile(runtime)\n\n    // Create squashfs with offset for runtime\n    const args: string[] = [stageDir, output, \"-offset\", runtimeData.length.toString(), \"-all-root\", \"-noappend\", \"-no-progress\", \"-quiet\", \"-no-xattrs\", \"-no-fragments\"]\n    if (options.compression) {\n      args.push(\"-comp\", options.compression)\n\n      if (options.compression === \"xz\") {\n        args.push(\"-Xdict-size\", \"100%\", \"-b\", \"1048576\")\n      }\n    }\n    await exec(mksquashfs, args, {\n      cwd: stageDir,\n    })\n\n    // Write runtime data at the beginning of the file\n    await writeRuntimeData(output, runtimeData)\n\n    // Make executable\n    await fs.chmod(output, 0o755)\n\n    // Append blockmap inside try block to ensure cleanup on failure\n    const updateInfo = await appendBlockmap(output)\n    return updateInfo\n  } catch (error) {\n    // Clean up partial build on failure\n    await fs.remove(output).catch(() => {})\n    throw error\n  }\n}\n\nasync function writeRuntimeData(filePath: string, runtimeData: Buffer): Promise<void> {\n  const fd = await fs.open(filePath, \"r+\")\n  try {\n    await fs.write(fd, runtimeData, 0, runtimeData.length, 0)\n  } finally {\n    try {\n      await fs.close(fd)\n    } catch (closeError: any) {\n      // Log but don't throw - preserve original error if any\n      log.warn({ message: closeError.message, file: filePath }, `failed to close file descriptor`)\n    }\n  }\n}\n\n/**\n * Escapes a string for safe use in shell scripts by wrapping in single quotes\n * and escaping any single quotes within the string.\n *\n * This allows strings with spaces, special characters, etc. to be safely used.\n */\nfunction escapeShellString(str: string): string {\n  // Escape single quotes by replacing ' with '\\''\n  // Then wrap the whole string in single quotes\n  return `'${str.replace(/'/g, \"'\\\\''\")}'`\n}\n\n/**\n * Validates that critical executable/filename fields don't contain dangerous characters\n * that could break paths or cause security issues even when escaped.\n */\nfunction validateCriticalPathString(str: string, fieldName: string): void {\n  // Only reject characters that would break filesystem paths or cause severe issues\n  // Allow quotes, spaces, etc. since they can be escaped\n  if (/[`${}|&;<>\\n\\r\\0]/.test(str) || str.includes(\"/\") || str.includes(\"\\\\\")) {\n    throw new InvalidConfigurationError(\n      `${fieldName} contains characters that cannot be safely used in file paths: ${str}. ` +\n        `Please use only alphanumeric characters, hyphens, underscores, dots, spaces, and quotes.`\n    )\n  }\n}\n\nasync function writeAppLauncherAndRelatedFiles(opts: AppImageBuilderOptions): Promise<void> {\n  const {\n    stageDir,\n    options: { license, executableName, productFilename, productName, desktopEntry },\n  } = opts\n\n  // Validate only critical path fields for severe path-breaking characters\n  // productName and productFilename can contain quotes, spaces, etc. - they'll be escaped\n  validateCriticalPathString(executableName, \"executableName\")\n  validateCriticalPathString(productFilename, \"productFilename\")\n\n  // Write desktop file\n  const desktopFileName = `${executableName}.desktop`\n  await fs.writeFile(path.join(stageDir, desktopFileName), desktopEntry, { mode: 0o644 })\n  await copyIcons(opts)\n\n  const templateConfig: AppRunScriptBase = {\n    DesktopFileName: desktopFileName,\n    ExecutableName: executableName,\n    ProductName: productName,\n    ProductFilename: productFilename,\n    ResourceName: `appimagekit-${executableName}`,\n  }\n\n  const mimeTypeFile = await copyMimeTypes(opts)\n  if (mimeTypeFile) {\n    templateConfig.MimeTypeFile = mimeTypeFile\n  }\n\n  let finalConfig: AppRunScript = templateConfig\n\n  // Copy license file if provided\n  if (license) {\n    // Validate license file exists\n    if (!(await exists(license))) {\n      throw new InvalidConfigurationError(`License file not found: ${license}`)\n    }\n\n    const licenseBaseName = path.basename(license)\n    const ext = path.extname(license).toLowerCase()\n\n    // Validate license filename for path safety\n    validateCriticalPathString(licenseBaseName, \"licenseBaseName\")\n\n    // Validate extension\n    if (![\".txt\", \".html\"].includes(ext)) {\n      log.warn({ license, expected: \".txt or .html\" }, `license file has unexpected extension`)\n    }\n\n    await copyFile(license, path.join(stageDir, licenseBaseName))\n\n    finalConfig = {\n      ...templateConfig,\n      EulaFile: licenseBaseName,\n      IsHtmlEula: ext === \".html\",\n    }\n  }\n\n  const appRunContent = generateAppRunScript(finalConfig)\n  await fs.writeFile(path.join(stageDir, APP_RUN_ENTRYPOINT), appRunContent, { mode: 0o755 })\n}\n\ntype AppRunScriptBase = {\n  ExecutableName: string\n  DesktopFileName: string\n  ProductFilename: string\n  ProductName: string\n  ResourceName: string\n  MimeTypeFile?: string\n}\n\ntype AppRunScriptWithEula = AppRunScriptBase & {\n  EulaFile: string\n  IsHtmlEula: boolean\n}\n\ntype AppRunScript = AppRunScriptBase | AppRunScriptWithEula\n\nfunction hasEula(config: AppRunScript): config is AppRunScriptWithEula {\n  return \"EulaFile\" in config && typeof config.EulaFile === \"string\"\n}\n\nfunction generateAppRunScript(config: AppRunScript): string {\n  const eulaEnabled = hasEula(config)\n\n  return `#!/bin/bash\nset -e\n\nTHIS=\"$0\"\n# http://stackoverflow.com/questions/3190818/\nargs=(\"$@\")\nNUMBER_OF_ARGS=\"$#\"\n\nif [ -z \"$APPDIR\" ] ; then\n  # Find the AppDir. It is the directory that contains AppRun.\n  # This assumes that this script resides inside the AppDir or a subdirectory.\n  # If this script is run inside an AppImage, then the AppImage runtime likely has already set $APPDIR\n  path=\"$(dirname \"$(readlink -f \"\\${THIS}\")\")\"\n  while [[ \"$path\" != \"\" && ! -e \"$path/${APP_RUN_ENTRYPOINT}\" ]]; do\n    path=\\${path%/*}\n  done\n  APPDIR=\"$path\"\nfi\n\nexport PATH=\"\\${APPDIR}:\\${APPDIR}/usr/sbin:\\${PATH}\"\nexport XDG_DATA_DIRS=\"./share/:/usr/share/gnome:/usr/local/share/:/usr/share/:\\${XDG_DATA_DIRS}\"\nexport LD_LIBRARY_PATH=\"\\${APPDIR}/usr/lib:\\${LD_LIBRARY_PATH}\"\nexport XDG_DATA_DIRS=\"\\${APPDIR}\"/usr/share/:\"\\${XDG_DATA_DIRS}\":/usr/share/gnome/:/usr/local/share/:/usr/share/\nexport GSETTINGS_SCHEMA_DIR=\"\\${APPDIR}/usr/share/glib-2.0/schemas:\\${GSETTINGS_SCHEMA_DIR}\"\n\nBIN=\"$APPDIR/${config.ExecutableName}\"\n\nif [ -z \"$APPIMAGE_EXIT_AFTER_INSTALL\" ] ; then\n  trap atexit EXIT\nfi\n\nisEulaAccepted=1\n\natexit()\n{\n  if [ $isEulaAccepted == 1 ] ; then\n    if [ $NUMBER_OF_ARGS -eq 0 ] ; then\n      exec \"$BIN\"\n    else\n      exec \"$BIN\" \"\\${args[@]}\"\n    fi\n  fi\n}\n\nerror()\n{\n  if [ -x /usr/bin/zenity ] ; then\n    LD_LIBRARY_PATH=\"\" zenity --error --text \"\\${1}\" 2>/dev/null\n  elif [ -x /usr/bin/kdialog ] ; then\n    LD_LIBRARY_PATH=\"\" kdialog --msgbox \"\\${1}\" 2>/dev/null\n  elif [ -x /usr/bin/Xdialog ] ; then\n    LD_LIBRARY_PATH=\"\" Xdialog --msgbox \"\\${1}\" 2>/dev/null\n  else\n    echo \"\\${1}\"\n  fi\n  exit 1\n}\n\nyesno()\n{\n  TITLE=$1\n  TEXT=$2\n  if [ -x /usr/bin/zenity ] ; then\n    LD_LIBRARY_PATH=\"\" zenity --question --title=\"$TITLE\" --text=\"$TEXT\" 2>/dev/null || exit 0\n  elif [ -x /usr/bin/kdialog ] ; then\n    LD_LIBRARY_PATH=\"\" kdialog --title \"$TITLE\" --yesno \"$TEXT\" || exit 0\n  elif [ -x /usr/bin/Xdialog ] ; then\n    LD_LIBRARY_PATH=\"\" Xdialog --title \"$TITLE\" --clear --yesno \"$TEXT\" 10 80 || exit 0\n  else\n    echo \"zenity, kdialog, Xdialog missing. Skipping \\${THIS}.\"\n    exit 0\n  fi\n}\n\ncheck_dep()\n{\n  DEP=$1\n  if ! command -v \"$DEP\" &>/dev/null ; then\n    echo \"$DEP is missing. Skipping \\${THIS}.\"\n    exit 0\n  fi\n}\n\nif [ -z \"$APPIMAGE\" ] ; then\n  APPIMAGE=\"$APPDIR/${APP_RUN_ENTRYPOINT}\"\n  # not running from within an AppImage; hence using the AppRun for Exec=\nfi\n\n${\n  eulaEnabled\n    ? `if [ -z \"$APPIMAGE_SILENT_INSTALL\" ] ; then\n  EULA_MARK_DIR=\"\\${XDG_CONFIG_HOME:-$HOME/.config}/${config.ProductFilename}\"\n  EULA_MARK_FILE=\"$EULA_MARK_DIR/eulaAccepted\"\n  # show EULA only if desktop file doesn't exist\n  if [ ! -e \"$EULA_MARK_FILE\" ] ; then\n    if [ -x /usr/bin/zenity ] ; then\n      # on cancel simply exits and our trap handler launches app, so, $isEulaAccepted is set here to 0 and then to 1 if EULA accepted\n      isEulaAccepted=0\n      LD_LIBRARY_PATH=\"\" zenity --text-info --title=${escapeShellString(config.ProductName)} --filename=\"$APPDIR/${config.EulaFile}\" --ok-label=Agree --cancel-label=Disagree ${config.IsHtmlEula ? \"--html\" : \"\"}\n    elif [ -x /usr/bin/Xdialog ] ; then\n      isEulaAccepted=0\n      LD_LIBRARY_PATH=\"\" Xdialog --title ${escapeShellString(config.ProductName)} --textbox \"$APPDIR/${config.EulaFile}\" 30 80 --ok-label Agree --cancel-label Disagree\n    elif [ -x /usr/bin/kdialog ] ; then\n      # cannot find any option to force Agree/Disagree buttons for kdialog. And official example exactly with OK button https://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs#Example_21._--textbox_dialog_box\n      # in any case we pass labels text\n      isEulaAccepted=0\n      LD_LIBRARY_PATH=\"\" kdialog --textbox \"$APPDIR/${config.EulaFile}\" --yes-label Agree --cancel-label \"Disagree\"\n    fi\n\n    case $? in\n      0)\n          isEulaAccepted=1\n          echo \"License accepted\"\n          mkdir -p \"$EULA_MARK_DIR\"\n          touch \"$EULA_MARK_FILE\"\n      ;;\n        1)\n          echo \"License not accepted\"\n          exit 0\n      ;;\n        -1)\n          echo \"An unexpected error has occurred.\"\n          isEulaAccepted=1\n      ;;\n    esac\n  fi\nfi`\n    : \"\"\n}\n`\n}\n"]}