IJPL-148255: assert that jvm path contains only symbols from current code page

othwerwise CreateJVM call will exit via NtTerminateProcess which will cause us to die w/o user facing message

GitOrigin-RevId: 2ead12a8483dd4169b2d31bdecb6dcbf83e10e2c
This commit is contained in:
Ivan Pashchenko
2024-04-16 19:18:23 +02:00
committed by intellij-monorepo-bot
parent ebb0dbfe70
commit f25a254d0f
2 changed files with 65 additions and 1 deletions

View File

@@ -25,7 +25,7 @@ va_list = "0.1.4"
[target.'cfg(target_os = "windows")'.dependencies.windows]
version = "0.51.1"
features = ["Win32_Foundation", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging", "Win32_System_Environment", "Win32_System_Services", "Win32_Security", "Win32_System_Console", "Win32_System_LibraryLoader"]
features = ["Win32_Foundation", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging", "Win32_System_Environment", "Win32_System_Services", "Win32_Security", "Win32_System_Console", "Win32_System_LibraryLoader", "Win32_Globalization"]
[target.'cfg(target_family = "unix")'.dependencies]
libc = "0.2.142"

View File

@@ -7,6 +7,14 @@ use std::path::{Path, PathBuf};
use anyhow::{bail, Result};
use log::debug;
#[cfg(target_os = "windows")]
use {
std::os::windows::ffi::OsStrExt,
windows::Win32::Globalization::{GetACP, WC_ERR_INVALID_CHARS, WC_NO_BEST_FIT_CHARS, WideCharToMultiByte},
windows::core::PCSTR,
windows::core::imp::GetLastError,
};
use crate::*;
const IDE_HOME_LOOKUP_DEPTH: usize = 5;
@@ -223,9 +231,65 @@ impl DefaultLaunchConfiguration {
if !java_executable.is_executable()? {
bail!("Not an executable file: {java_executable:?}");
}
#[cfg(target_os = "windows")] {
Self::assert_valid_in_system_default_ansi_codepage(&adjusted_home)?;
}
Ok(adjusted_home)
}
#[cfg(target_os = "windows")]
fn assert_valid_in_system_default_ansi_codepage(path: &Path) -> Result<()> {
let path_wide: Vec<u16> = path.as_os_str().encode_wide().chain(Some(0)).collect();
let mut used_default_char: i32 = -1;
let acp = unsafe {
GetACP()
};
let flags = match acp {
50220..=50222 |
50225 |
50227 |
50229 |
57002..=57011 |
65000 |
42 => 0,
65001 | 54936 => WC_ERR_INVALID_CHARS,
_ => WC_NO_BEST_FIT_CHARS
};
let result = unsafe {
WideCharToMultiByte(
acp,
flags,
&path_wide,
None,
PCSTR(std::ptr::null_mut::<u8>()),
Some(&mut used_default_char)
)
};
if result == 0 {
let error = unsafe {
GetLastError()
};
let path = path.to_string_checked()?;
bail!("Failed to determined if path can be represented using the system default ANSI codepage. Win32 error: {error}, ACP: {acp}, Path: {path}")
}
if used_default_char > 0 {
let path = path.to_string_checked()?;
bail!("Path cannot be represented using the system default ANSI codepage. ACP: {acp}, Path: {path}")
}
Ok(())
}
/// Reads VM options from both distribution and user-specific files and puts them into the given vector.
///
/// When `<product>_VM_OPTIONS` environment variable points to an existing file, only its content is used;