Skip to content

Commit ce9f8e1

Browse files
committed
adopt json.ParseOptions.allowEmptyContent and getNodeType
1 parent db5a09c commit ce9f8e1

14 files changed

Lines changed: 61 additions & 33 deletions

File tree

src/vs/platform/diagnostics/node/diagnosticsService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { virtualMachineHint } from 'vs/base/node/id';
77
import { IMachineInfo, WorkspaceStats, WorkspaceStatItem, PerformanceInfo, SystemInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError, isRemoteDiagnosticError, IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnostics';
88
import { readdir, stat, exists, readFile } from 'fs';
99
import { join, basename } from 'vs/base/common/path';
10-
import { parse, ParseError } from 'vs/base/common/json';
10+
import { parse, ParseError, getNodeType } from 'vs/base/common/json';
1111
import { listProcesses } from 'vs/base/node/ps';
1212
import product from 'vs/platform/product/common/product';
1313
import { repeat, pad } from 'vs/base/common/strings';
@@ -223,7 +223,7 @@ export function collectLaunchConfigs(folder: string): Promise<WorkspaceStatItem[
223223
return resolve([]);
224224
}
225225

226-
if (json['configurations']) {
226+
if (getNodeType(json) === 'object' && json['configurations']) {
227227
for (const each of json['configurations']) {
228228
const type = each['type'];
229229
if (type) {

src/vs/platform/userDataSync/common/settingsSync.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser {
188188

189189
private hasErrors(content: string): boolean {
190190
const parseErrors: ParseError[] = [];
191-
parse(content, parseErrors);
191+
parse(content, parseErrors, { allowEmptyContent: true, allowTrailingComma: true });
192192
return parseErrors.length > 0;
193193
}
194194

@@ -248,13 +248,23 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser {
248248
}
249249

250250
private getIgnoredSettings(settingsContent?: string): string[] {
251-
const value: string[] = (settingsContent ? parse(settingsContent)['configurationSync.settingsToIgnore'] : this.configurationService.getValue<string[]>('configurationSync.settingsToIgnore')) || [];
251+
let value: string[] = [];
252+
if (settingsContent) {
253+
const setting = parse(settingsContent);
254+
if (setting) {
255+
value = setting['configurationSync.settingsToIgnore'];
256+
}
257+
} else {
258+
value = this.configurationService.getValue<string[]>('configurationSync.settingsToIgnore');
259+
}
252260
const added: string[] = [], removed: string[] = [];
253-
for (const key of value) {
254-
if (startsWith(key, '-')) {
255-
removed.push(key.substring(1));
256-
} else {
257-
added.push(key);
261+
if (Array.isArray(value)) {
262+
for (const key of value) {
263+
if (startsWith(key, '-')) {
264+
removed.push(key.substring(1));
265+
} else {
266+
added.push(key);
267+
}
258268
}
259269
}
260270
return [...DEFAULT_IGNORED_SETTINGS, ...added].filter(setting => removed.indexOf(setting) === -1);

src/vs/platform/workspaces/common/workspaces.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,12 +285,9 @@ function doParseStoredWorkspace(path: URI, contents: string): IStoredWorkspace {
285285
let storedWorkspace: IStoredWorkspace = json.parse(contents); // use fault tolerant parser
286286

287287
// Filter out folders which do not have a path or uri set
288-
if (Array.isArray(storedWorkspace.folders)) {
288+
if (storedWorkspace && Array.isArray(storedWorkspace.folders)) {
289289
storedWorkspace.folders = storedWorkspace.folders.filter(folder => isStoredWorkspaceFolder(folder));
290-
}
291-
292-
// Validate
293-
if (!Array.isArray(storedWorkspace.folders)) {
290+
} else {
294291
throw new Error(`${path} looks like an invalid workspace file.`);
295292
}
296293

src/vs/platform/workspaces/electron-main/workspacesMainService.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,9 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain
130130
let storedWorkspace: IStoredWorkspace = json.parse(contents); // use fault tolerant parser
131131

132132
// Filter out folders which do not have a path or uri set
133-
if (Array.isArray(storedWorkspace.folders)) {
133+
if (storedWorkspace && Array.isArray(storedWorkspace.folders)) {
134134
storedWorkspace.folders = storedWorkspace.folders.filter(folder => isStoredWorkspaceFolder(folder));
135-
}
136-
137-
// Validate
138-
if (!Array.isArray(storedWorkspace.folders)) {
135+
} else {
139136
throw new Error(`${path.toString()} looks like an invalid workspace file.`);
140137
}
141138

src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as nls from 'vs/nls';
7-
import { ParseError, parse } from 'vs/base/common/json';
7+
import { ParseError, parse, getNodeType } from 'vs/base/common/json';
88
import { IJSONSchema } from 'vs/base/common/jsonSchema';
99
import * as types from 'vs/base/common/types';
1010
import { URI } from 'vs/base/common/uri';
@@ -91,10 +91,14 @@ export class LanguageConfigurationFileHandler {
9191
private _handleConfigFile(languageIdentifier: LanguageIdentifier, configFileLocation: URI): void {
9292
this._fileService.readFile(configFileLocation).then((contents) => {
9393
const errors: ParseError[] = [];
94-
const configuration = <ILanguageConfiguration>parse(contents.value.toString(), errors);
94+
let configuration = <ILanguageConfiguration>parse(contents.value.toString(), errors);
9595
if (errors.length) {
9696
console.error(nls.localize('parseErrors', "Errors parsing {0}: {1}", configFileLocation.toString(), errors.map(e => (`[${e.offset}, ${e.length}] ${getParseErrorMessage(e.error)}`)).join('\n')));
9797
}
98+
if (getNodeType(configuration) !== 'object') {
99+
console.error(nls.localize('formatError', "{0}: Invalid format, JSON object expected.", configFileLocation.toString()));
100+
configuration = {};
101+
}
98102
this._handleConfig(languageIdentifier, configuration);
99103
}, (err) => {
100104
console.error(err);

src/vs/workbench/contrib/extensions/browser/extensionsActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2101,7 +2101,7 @@ export abstract class AbstractConfigureRecommendedExtensionsAction extends Actio
21012101
protected getWorkspaceFolderExtensionsConfigContent(extensionsFileResource: URI): Promise<IExtensionsConfigContent> {
21022102
return Promise.resolve(this.fileService.readFile(extensionsFileResource))
21032103
.then(content => {
2104-
return (<IExtensionsConfigContent>json.parse(content.value.toString()));
2104+
return (<IExtensionsConfigContent>json.parse(content.value.toString()) || {});
21052105
}, err => ({ recommendations: [], unwantedRecommendations: [] }));
21062106
}
21072107

src/vs/workbench/contrib/snippets/browser/snippetsFile.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { parse as jsonParse } from 'vs/base/common/json';
6+
import { parse as jsonParse, getNodeType } from 'vs/base/common/json';
77
import { forEach } from 'vs/base/common/collections';
88
import { localize } from 'vs/nls';
99
import { extname, basename } from 'vs/base/common/path';
@@ -203,7 +203,7 @@ export class SnippetFile {
203203
if (!this._loadPromise) {
204204
this._loadPromise = Promise.resolve(this._fileService.readFile(this.location)).then(content => {
205205
const data = <JsonSerializedSnippets>jsonParse(content.value.toString());
206-
if (typeof data === 'object') {
206+
if (getNodeType(data) === 'object') {
207207
forEach(data, entry => {
208208
const { key: name, value: scopeOrTemplate } = entry;
209209
if (isJsonSerializedSnippet(scopeOrTemplate)) {

src/vs/workbench/contrib/url/common/trustedDomainsFileSystemProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export class TrustedDomainsFileSystemProvider implements IFileSystemProvider, IW
121121
this.storageService.store('http.linkProtectionTrustedDomainsContent', trustedDomainsContent, StorageScope.GLOBAL);
122122
this.storageService.store(
123123
'http.linkProtectionTrustedDomains',
124-
JSON.stringify(trustedDomains),
124+
JSON.stringify(trustedDomains) || '',
125125
StorageScope.GLOBAL
126126
);
127127
} catch (err) { }

src/vs/workbench/services/configuration/common/configurationEditingService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ export class ConfigurationEditingService {
409409
return false;
410410
}
411411
const parseErrors: json.ParseError[] = [];
412-
json.parse(model.getValue(), parseErrors);
412+
json.parse(model.getValue(), parseErrors, { allowTrailingComma: true, allowEmptyContent: true });
413413
return parseErrors.length > 0;
414414
}
415415

src/vs/workbench/services/configuration/common/jsonEditingService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export class JSONEditingService implements IJSONEditingService {
9898

9999
private hasParseErrors(model: ITextModel): boolean {
100100
const parseErrors: json.ParseError[] = [];
101-
json.parse(model.getValue(), parseErrors);
101+
json.parse(model.getValue(), parseErrors, { allowTrailingComma: true, allowEmptyContent: true });
102102
return parseErrors.length > 0;
103103
}
104104

0 commit comments

Comments
 (0)