Skip to content

Commit

Permalink
Merge branch 'main' into fix/regexless-windows-prompt-detection
Browse files Browse the repository at this point in the history
  • Loading branch information
cpendery authored Apr 30, 2024
2 parents 89ee2dd + 0f91377 commit a0e528d
Show file tree
Hide file tree
Showing 228 changed files with 3,964 additions and 2,523 deletions.
40 changes: 40 additions & 0 deletions .eslintplugin/code-no-dangerous-type-assertions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as eslint from 'eslint';
import { TSESTree } from '@typescript-eslint/experimental-utils';

export = new class NoDangerousTypeAssertions implements eslint.Rule.RuleModule {

create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
// Disable in tests for now
if (context.getFilename().includes('.test')) {
return {};
}

return {
// Disallow type assertions on object literals: <T>{ ... } or {} as T
['TSTypeAssertion > ObjectExpression, TSAsExpression > ObjectExpression']: (node: any) => {
const objectNode = node as TSESTree.Node;

const parent = objectNode.parent as TSESTree.TSTypeAssertion | TSESTree.TSAsExpression;
if (
// Allow `as const` assertions
(parent.typeAnnotation.type === 'TSTypeReference' && parent.typeAnnotation.typeName.type === 'Identifier' && parent.typeAnnotation.typeName.name === 'cost')

// For also now still allow `any` casts
|| (parent.typeAnnotation.type === 'TSAnyKeyword')
) {
return;
}

context.report({
node,
message: "Don't use type assertions for creating objects as this can hide type errors."
});
},
};
}
};
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"local/code-parameter-properties-must-have-explicit-accessibility": "warn",
"local/code-no-nls-in-standalone-editor": "warn",
"local/code-no-potentially-unsafe-disposables": "warn",
"local/code-no-dangerous-type-assertions": "off",
"local/code-no-standalone-editor": "warn",
"local/code-no-unexternalized-strings": "warn",
"local/code-must-use-super-dispose": "warn",
Expand Down Expand Up @@ -671,7 +672,6 @@
"vscode-regexpp",
"vscode-textmate",
"worker_threads",
"@xterm/addon-canvas",
"@xterm/addon-image",
"@xterm/addon-search",
"@xterm/addon-serialize",
Expand Down
10 changes: 10 additions & 0 deletions .vscode/notebooks/endgame.github-issues
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@
"language": "github-issues",
"value": "$REPOS $MILESTONE is:issue is:closed reason:completed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:z-author-verified -label:unreleased -label:*not-reproducible"
},
{
"kind": 1,
"language": "markdown",
"value": "## Verifiable Fixes Missing Steps"
},
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE is:issue is:closed reason:completed sort:updated-asc label:bug label:verification-steps-needed -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:z-author-verified -label:unreleased -label:*not-reproducible"
},
{
"kind": 1,
"language": "markdown",
Expand Down
3 changes: 0 additions & 3 deletions build/.webignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ vscode-textmate/webpack.config.js

@xterm/xterm/src/**

@xterm/addon-canvas/src/**
@xterm/addon-canvas/out/**

@xterm/addon-image/src/**
@xterm/addon-image/out/**

Expand Down
4 changes: 4 additions & 0 deletions build/azure-pipelines/product-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ extends:
notificationAliases: ['monacotools@microsoft.com']
validateToolOutput: None
allTools: true
codeql:
compiled:
enabled: true
runSourceLanguagesInSourceAnalysis: true
credscan:
suppressionsFile: $(Build.SourcesDirectory)/build/azure-pipelines/config/CredScanSuppressions.json
eslint:
Expand Down
1 change: 1 addition & 0 deletions build/filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ module.exports.indentationFilter = [
'!resources/linux/snap/electron-launch',
'!build/ext.js',
'!build/npm/gyp/patches/gyp_spectre_mitigation_support.patch',
'!product.overrides.json',

// except specific folders
'!test/automation/out/**',
Expand Down
10 changes: 10 additions & 0 deletions cli/src/commands/tunnels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,16 @@ async fn serve_with_csa(
match acquire_singleton(&paths.tunnel_lockfile()).await {
Ok(SingletonConnection::Client(stream)) => {
debug!(log, "starting as client to singleton");
if gateway_args.name.is_none()
|| !gateway_args.install_extension.is_empty()
|| gateway_args.tunnel.tunnel_id.is_some()
{
warning!(
log,
"Command-line options will not be applied until the existing tunnel exits."
);
}

let should_exit = start_singleton_client(SingletonClientArgs {
log: log.clone(),
shutdown: shutdown.clone(),
Expand Down
76 changes: 40 additions & 36 deletions cli/src/tunnels/code_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,16 @@ impl<'a> ServerBuilder<'a> {
}
}

/// Removes a cached server.
pub async fn evict(&self) -> Result<(), WrappedError> {
let name = get_server_folder_name(
self.server_params.release.quality,
&self.server_params.release.commit,
);

self.launcher_paths.server_cache.delete(&name)
}

/// Ensures the server is set up in the configured directory.
pub async fn setup(&self) -> Result<(), AnyError> {
debug!(
Expand Down Expand Up @@ -479,24 +489,24 @@ impl<'a> ServerBuilder<'a> {
.arg("--enable-remote-auto-shutdown")
.arg(format!("--port={}", port));

let child = self.spawn_server_process(cmd)?;
let child = self.spawn_server_process(cmd).await?;
let log_file = self.get_logfile()?;
let plog = self.logger.prefixed(&log::new_code_server_prefix());

let (mut origin, listen_rx) =
monitor_server::<PortMatcher, u16>(child, Some(log_file), plog, false);

let port = match timeout(Duration::from_secs(8), listen_rx).await {
Err(e) => {
Err(_) => {
origin.kill().await;
Err(wrap(e, "timed out looking for port"))
return Err(CodeError::ServerOriginTimeout.into());
}
Ok(Err(e)) => {
Ok(Err(s)) => {
origin.kill().await;
Err(wrap(e, "server exited without writing port"))
return Err(CodeError::ServerUnexpectedExit(format!("{}", s)).into());
}
Ok(Ok(p)) => Ok(p),
}?;
Ok(Ok(p)) => p,
};

info!(self.logger, "Server started");

Expand Down Expand Up @@ -553,24 +563,24 @@ impl<'a> ServerBuilder<'a> {
.arg("--enable-remote-auto-shutdown")
.arg(format!("--socket-path={}", socket.display()));

let child = self.spawn_server_process(cmd)?;
let child = self.spawn_server_process(cmd).await?;
let log_file = self.get_logfile()?;
let plog = self.logger.prefixed(&log::new_code_server_prefix());

let (mut origin, listen_rx) =
monitor_server::<SocketMatcher, PathBuf>(child, Some(log_file), plog, false);

let socket = match timeout(Duration::from_secs(30), listen_rx).await {
Err(e) => {
Err(_) => {
origin.kill().await;
Err(wrap(e, "timed out looking for socket"))
return Err(CodeError::ServerOriginTimeout.into());
}
Ok(Err(e)) => {
Ok(Err(s)) => {
origin.kill().await;
Err(wrap(e, "server exited without writing socket"))
return Err(CodeError::ServerUnexpectedExit(format!("{}", s)).into());
}
Ok(Ok(socket)) => Ok(socket),
}?;
Ok(Ok(socket)) => socket,
};

info!(self.logger, "Server started");

Expand All @@ -581,26 +591,7 @@ impl<'a> ServerBuilder<'a> {
})
}

/// Starts with a given opaque set of args. Does not set up any port or
/// socket, but does return one if present, in the form of a channel.
pub async fn start_opaque_with_args<M, R>(
&self,
args: &[String],
) -> Result<(CodeServerOrigin, Receiver<R>), AnyError>
where
M: ServerOutputMatcher<R>,
R: 'static + Send + std::fmt::Debug,
{
let mut cmd = self.get_base_command();
cmd.args(args);

let child = self.spawn_server_process(cmd)?;
let plog = self.logger.prefixed(&log::new_code_server_prefix());

Ok(monitor_server::<M, R>(child, None, plog, true))
}

fn spawn_server_process(&self, mut cmd: Command) -> Result<Child, AnyError> {
async fn spawn_server_process(&self, mut cmd: Command) -> Result<Child, AnyError> {
info!(self.logger, "Starting server...");

debug!(self.logger, "Starting server with command... {:?}", cmd);
Expand All @@ -615,14 +606,17 @@ impl<'a> ServerBuilder<'a> {
let cmd = cmd.creation_flags(
winapi::um::winbase::CREATE_NO_WINDOW
| winapi::um::winbase::CREATE_NEW_PROCESS_GROUP
| winapi::um::winbase::CREATE_BREAKAWAY_FROM_JOB,
| get_should_use_breakaway_from_job()
.await
.then_some(winapi::um::winbase::CREATE_BREAKAWAY_FROM_JOB)
.unwrap_or_default(),
);

let child = cmd
.stderr(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped())
.spawn()
.map_err(|e| wrap(e, "error spawning server"))?;
.map_err(|e| CodeError::ServerUnexpectedExit(format!("{}", e)))?;

self.server_paths
.write_pid(child.id().expect("expected server to have pid"))?;
Expand Down Expand Up @@ -874,3 +868,13 @@ pub async fn download_cli_into_cache(
}
}
}

#[cfg(target_os = "windows")]
async fn get_should_use_breakaway_from_job() -> bool {
let mut cmd = Command::new("cmd");
cmd.creation_flags(
winapi::um::winbase::CREATE_NO_WINDOW | winapi::um::winbase::CREATE_BREAKAWAY_FROM_JOB,
);

cmd.args(["/C", "echo ok"]).output().await.is_ok()
}
25 changes: 22 additions & 3 deletions cli/src/tunnels/control_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -760,17 +760,18 @@ async fn handle_serve(
macro_rules! do_setup {
($sb:expr) => {
match $sb.get_running().await? {
Some(AnyCodeServer::Socket(s)) => s,
Some(AnyCodeServer::Socket(s)) => ($sb, Ok(s)),
Some(_) => return Err(AnyError::from(MismatchedLaunchModeError())),
None => {
$sb.setup().await?;
$sb.listen_on_default_socket().await?
let r = $sb.listen_on_default_socket().await;
($sb, r)
}
}
};
}

let server = if params.use_local_download {
let (sb, server) = if params.use_local_download {
let sb = ServerBuilder::new(
&install_log,
&resolved,
Expand All @@ -784,6 +785,24 @@ async fn handle_serve(
do_setup!(sb)
};

let server = match server {
Ok(s) => s,
Err(e) => {
// we don't loop to avoid doing so infinitely: allow the client to reconnect in this case.
if let AnyError::CodeError(CodeError::ServerUnexpectedExit(ref e)) = e {
warning!(
c.log,
"({}), removing server due to possible corruptions",
e
);
if let Err(e) = sb.evict().await {
warning!(c.log, "Failed to evict server: {}", e);
}
}
return Err(e);
}
};

server_ref.replace(server.clone());
server
}
Expand Down
4 changes: 4 additions & 0 deletions cli/src/util/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,10 @@ pub enum CodeError {
CouldNotCreateConnectionTokenFile(std::io::Error),
#[error("A tunnel with the name {0} exists and is in-use. Please pick a different name or stop the existing tunnel.")]
TunnelActiveAndInUse(String),
#[error("Timed out looking for port/socket")]
ServerOriginTimeout,
#[error("Server exited without writing port/socket: {0}")]
ServerUnexpectedExit(String),
}

makeAnyError!(
Expand Down
2 changes: 1 addition & 1 deletion extensions/dart/cgmanifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"git": {
"name": "dart-lang/dart-syntax-highlight",
"repositoryUrl": "/~https://github.com/dart-lang/dart-syntax-highlight",
"commitHash": "272e2f89f85073c04b7e15b582257f76d2489970"
"commitHash": "bb8f7eebf5a1028e70dbebcf35cfef738dddc7fe"
}
},
"licenseDetail": [
Expand Down
Loading

0 comments on commit a0e528d

Please sign in to comment.