Skip to content

Commit e714ddc

Browse files
authored
[AzureRG Deploy] File encoding check before parsing (#3749)
* Detecting encoding of file before parsing * refactoring code * bug fix and message fixes * Fixing messages
1 parent f776eca commit e714ddc

File tree

5 files changed

+115
-8
lines changed

5 files changed

+115
-8
lines changed

Tasks/AzureResourceGroupDeployment/Strings/resources.resjson/en-US/resources.resjson

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,5 +158,8 @@
158158
"loc.messages.DeletingMGAgentOnVMs": "Deleting machine group agent on virtual machines",
159159
"loc.messages.AddingExtensionFailed": "Addition of extension on vm %s failed",
160160
"loc.messages.TimeoutWhileWaiting": "Timed out while waiting",
161-
"loc.messages.InvalidTemplateLocation": "The template location supplied is invalid. Task only supports 'Linked artifact' or 'URL of the file'"
161+
"loc.messages.InvalidTemplateLocation": "The template location supplied is invalid. Task only supports 'Linked artifact' or 'URL of the file'",
162+
"loc.messages.EncodingNotSupported": "Encoding of the file '%s' is '%s' which is not supported. Supported encodings are ['utf-8', 'utf-16le']",
163+
"loc.messages.CouldNotDetectEncoding": "Could not detect encoding of file '%s'",
164+
"loc.messages.ShortFileBufferError": "Short file buffer error on file '%s'"
162165
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//File Encoding detected to be : utf-32be, which is not supported by Node.js
2+
//'Unable to detect encoding of file ' + typeCode
3+
//'File buffer is too short to detect encoding type'
4+
var fs = require('fs');
5+
import tl = require('vsts-task-lib');
6+
7+
export class FileEncoding {
8+
public type: string;
9+
public usesBOM: boolean;
10+
constructor(type: string, usesBOM: boolean) {
11+
this.type = type;
12+
this.usesBOM = usesBOM;
13+
}
14+
}
15+
16+
function detectFileEncodingWithBOM(fileName: string, buffer: Buffer) {
17+
tl.debug('Detecting file encoding using BOM');
18+
var type: string;
19+
if (buffer.slice(0, 3).equals(new Buffer([239, 187, 191]))) {
20+
type = 'utf-8';
21+
}
22+
else if (buffer.slice(0, 4).equals(new Buffer([255, 254, 0, 0]))) {
23+
type = 'UTF-32LE';
24+
}
25+
else if (buffer.slice(0, 2).equals(new Buffer([254, 255]))) {
26+
type = 'UTF-16BE';
27+
}
28+
else if (buffer.slice(0, 2).equals(new Buffer([255, 254]))) {
29+
type = 'utf-16le';
30+
}
31+
else if (buffer.slice(0, 4).equals(new Buffer([0, 0, 254, 255]))) {
32+
type = 'UTF-32BE';
33+
}
34+
else {
35+
tl.debug('Unable to detect File encoding using BOM');
36+
return null;
37+
}
38+
return new FileEncoding(type, true);
39+
}
40+
41+
function detectFileEncodingWithoutBOM(fileName: string, buffer: Buffer) {
42+
tl.debug('Detecting file encoding without BOM');
43+
var typeCode = 0;
44+
var type: string;
45+
for (var index = 0; index < 4; index++) {
46+
typeCode = typeCode << 1;
47+
typeCode = typeCode | (buffer[index] > 0 ? 1 : 0);
48+
}
49+
switch (typeCode) {
50+
case 1:
51+
type = 'UTF-32BE';
52+
break;
53+
case 5:
54+
type = 'UTF-16BE';
55+
break;
56+
case 8:
57+
type = 'UTF-32LE';
58+
break;
59+
case 10:
60+
type = 'utf-16le';
61+
break;
62+
case 15:
63+
type = 'utf-8';
64+
break;
65+
default:
66+
return null;
67+
}
68+
return new FileEncoding(type, false);
69+
}
70+
export function detectFileEncoding(fileName: string, buffer: Buffer): FileEncoding {
71+
if (buffer.length < 4) {
72+
tl.debug(tl.loc('ShortFileBufferError', fileName))
73+
throw Error(tl.loc("CouldNotDetectEncoding", fileName));
74+
}
75+
var fileEncoding: FileEncoding = detectFileEncodingWithBOM(fileName, buffer);
76+
if (fileEncoding == null)
77+
fileEncoding = detectFileEncodingWithoutBOM(fileName, buffer);
78+
79+
if (fileEncoding == null) {
80+
throw new Error(tl.loc("CouldNotDetectEncoding", fileName));
81+
}
82+
return fileEncoding;
83+
}
84+
85+
export function readFileContentsAsText(fileName: string): string {
86+
var buffer = fs.readFileSync(fileName);
87+
var supportedFileEncodings = ["utf-8", "utf-16le"]
88+
var fileEncoding = detectFileEncoding(fileName, buffer);
89+
if (supportedFileEncodings.indexOf(fileEncoding.type) < 0) {
90+
throw new Error(tl.loc('EncodingNotSupported', fileName, fileEncoding.type));
91+
}
92+
var fileContents: string = buffer.toString(fileEncoding.type);
93+
if (fileEncoding.usesBOM) {
94+
fileContents = fileContents.slice(1);
95+
}
96+
return fileContents;
97+
}

Tasks/AzureResourceGroupDeployment/operations/ResourceGroup.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import winRM = require("./WinRMExtensionHelper");
1515
import mgExtensionHelper = require("./MachineGroupExtensionHelper");
1616
var parameterParser = require("./ParameterParser").parse;
1717
import utils = require("./Utils");
18+
import fileEncoding = require('./FileEncoding');
1819

1920
var httpClient = require('vso-node-api/HttpClient');
2021
var httpObj = new httpClient.HttpCallbackClient("VSTS_AGENT");
@@ -190,7 +191,7 @@ export class ResourceGroup {
190191
var template: Object;
191192
try {
192193
tl.debug("Loading CSM Template File.. " + this.taskParameters.csmFile);
193-
template = JSON.parse(fs.readFileSync(this.taskParameters.csmFile, 'UTF-8'));
194+
template = JSON.parse(fileEncoding.readFileContentsAsText(this.taskParameters.csmFile));
194195
tl.debug("Loaded CSM File");
195196
}
196197
catch (error) {
@@ -202,9 +203,9 @@ export class ResourceGroup {
202203
if (utils.isNonEmpty(this.taskParameters.csmParametersFile)) {
203204
if (!fs.lstatSync(this.taskParameters.csmParametersFile).isDirectory()) {
204205
tl.debug("Loading Parameters File.. " + this.taskParameters.csmParametersFile);
205-
var parameterFile = fs.readFileSync(this.taskParameters.csmParametersFile, 'UTF-8');
206+
var parameterFile = JSON.parse(fileEncoding.readFileContentsAsText(this.taskParameters.csmParametersFile));
206207
tl.debug("Loaded Parameters File");
207-
parameters = JSON.parse(parameterFile).parameters;
208+
parameters = parameterFile["parameters"];
208209
}
209210
}
210211
}

Tasks/AzureResourceGroupDeployment/task.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"version": {
1515
"Major": 2,
1616
"Minor": 0,
17-
"Patch": 3
17+
"Patch": 4
1818
},
1919
"demands": [],
2020
"minimumAgentVersion": "2.0.0",
@@ -367,6 +367,9 @@
367367
"DeletingMGAgentOnVMs": "Deleting machine group agent on virtual machines",
368368
"AddingExtensionFailed": "Addition of extension on vm %s failed",
369369
"TimeoutWhileWaiting": "Timed out while waiting",
370-
"InvalidTemplateLocation": "The template location supplied is invalid. Task only supports 'Linked artifact' or 'URL of the file'"
370+
"InvalidTemplateLocation": "The template location supplied is invalid. Task only supports 'Linked artifact' or 'URL of the file'",
371+
"EncodingNotSupported": "Encoding of the file '%s' is '%s' which is not supported. Supported encodings are ['utf-8', 'utf-16le']",
372+
"CouldNotDetectEncoding": "Could not detect encoding of file '%s'",
373+
"ShortFileBufferError": "Short file buffer error on file '%s'"
371374
}
372375
}

Tasks/AzureResourceGroupDeployment/task.loc.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"version": {
1515
"Major": 2,
1616
"Minor": 0,
17-
"Patch": 3
17+
"Patch": 4
1818
},
1919
"demands": [],
2020
"minimumAgentVersion": "2.0.0",
@@ -367,6 +367,9 @@
367367
"DeletingMGAgentOnVMs": "ms-resource:loc.messages.DeletingMGAgentOnVMs",
368368
"AddingExtensionFailed": "ms-resource:loc.messages.AddingExtensionFailed",
369369
"TimeoutWhileWaiting": "ms-resource:loc.messages.TimeoutWhileWaiting",
370-
"InvalidTemplateLocation": "ms-resource:loc.messages.InvalidTemplateLocation"
370+
"InvalidTemplateLocation": "ms-resource:loc.messages.InvalidTemplateLocation",
371+
"EncodingNotSupported": "ms-resource:loc.messages.EncodingNotSupported",
372+
"CouldNotDetectEncoding": "ms-resource:loc.messages.CouldNotDetectEncoding",
373+
"ShortFileBufferError": "ms-resource:loc.messages.ShortFileBufferError"
371374
}
372375
}

0 commit comments

Comments
 (0)