Changing load/dump in source files (#190641)

## Summary

Updates usage of `js-yaml` `load` and `dump` to `safeLoad` and
`safeDump`, in preparation for a major version update of dependency,
where the default behavior will be that of the safe function variants.


## Note to reviewers
`safeDump` will throw if it encounters invalid types (e.g. `undefined`),
whereas the `dump` function will still write the file including the
invalid types. This may have an affect within your use cases - if
throwing is not acceptable or is unhandled. To avoid this the
`skipInvalid` option can be used (see
https://github.com/nodeca/js-yaml#dump-object---options-) - this will
write the file, stripping out any invalid types from the input.

Please consider this when reviewing the changes to your code. If the
`skipInvalid` option is needed, please add it, or let us know to make
the change.

---------

Co-authored-by: Sid <siddharthmantri1@gmail.com>
Co-authored-by: “jeramysoucy” <jeramy.soucy@elastic.co>
Co-authored-by: Elena Shostak <elena.shostak@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Maxim Palenov <maxim.palenov@elastic.co>
This commit is contained in:
Kurt 2024-08-21 07:29:36 -04:00 committed by GitHub
parent 5acd638327
commit bcc46b60e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 265 additions and 57 deletions

View file

@ -36,6 +36,7 @@ async function main() {
const preamble = locationFileLines.slice(0, 1);
// eslint-disable-next-line @kbn/eslint/no_unsafe_js_yaml
const locationObj = jsYaml.load(
locationFileLines.slice(1).join('\n')
) as BackstageLocationResource;
@ -43,6 +44,7 @@ async function main() {
(fileName) => `${resourceDefinitionsBaseUrl}/${fileName}`
);
// eslint-disable-next-line @kbn/eslint/no_unsafe_js_yaml
const locationYaml = jsYaml.dump(locationObj, { lineWidth: 400 });
fs.writeFileSync(locationFile, `${preamble.join('\n')}\n${locationYaml}`);

View file

@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
// eslint-disable-next-line @kbn/eslint/no_unsafe_js_yaml
import { dump } from 'js-yaml';
import { BuildkiteClient, BuildkiteCommandStep } from './buildkite';

View file

@ -8,7 +8,10 @@
import axios, { AxiosInstance } from 'axios';
import { execSync, ExecSyncOptions } from 'child_process';
// eslint-disable-next-line @kbn/eslint/no_unsafe_js_yaml
import { dump } from 'js-yaml';
import { parseLinkHeader } from './parse_link_header';
import { Artifact } from './types/artifact';
import { Build, BuildStatus } from './types/build';

View file

@ -10,6 +10,8 @@ import * as Fs from 'fs';
import * as globby from 'globby';
import minimatch from 'minimatch';
// eslint-disable-next-line @kbn/eslint/no_unsafe_js_yaml
import { load as loadYaml } from 'js-yaml';
import { BuildkiteClient, BuildkiteStep } from '../buildkite';

View file

@ -7,7 +7,7 @@
*/
import fs from 'fs';
import { extname } from 'path';
import { load as loadYaml } from 'js-yaml';
import { safeLoad as loadYaml } from 'js-yaml';
export const readRolesFromResource = (resourcePath: string) => {
if (!fs.existsSync(resourcePath) || extname(resourcePath) !== '.yml') {

View file

@ -314,6 +314,7 @@ module.exports = {
'@kbn/eslint/no_constructor_args_in_property_initializers': 'error',
'@kbn/eslint/no_this_in_property_initializers': 'error',
'@kbn/eslint/no_unsafe_console': 'error',
'@kbn/eslint/no_unsafe_js_yaml': 'error',
'@kbn/imports/no_unresolvable_imports': 'error',
'@kbn/imports/uniform_imports': 'error',
'@kbn/imports/no_unused_imports': 'error',

View file

@ -18,5 +18,6 @@ module.exports = {
no_constructor_args_in_property_initializers: require('./rules/no_constructor_args_in_property_initializers'),
no_this_in_property_initializers: require('./rules/no_this_in_property_initializers'),
no_unsafe_console: require('./rules/no_unsafe_console'),
no_unsafe_js_yaml: require('./rules/no_unsafe_js_yaml'),
},
};

View file

@ -0,0 +1,90 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
meta: {
fixable: 'code',
schema: [],
},
create(context) {
const sourceCode = context.getSourceCode();
const jsYamlIdentifiers = new Set();
const isUnsafeMethod = (node) => node.name === 'load' || node.name === 'dump';
return {
ImportDeclaration(node) {
if (node.source.value === 'js-yaml') {
node.specifiers.forEach((specifier) => {
jsYamlIdentifiers.add(specifier.local.name);
if (specifier.imported && isUnsafeMethod(specifier.imported)) {
context.report({
node: specifier,
message:
'Use `safeLoad` instead of `load` and `safeDump` instead of `dump` from `js-yaml`.',
fix(fixer) {
const replacement =
specifier.imported.name === 'load'
? fixer.replaceText(specifier.imported, 'safeLoad')
: fixer.replaceText(specifier.imported, 'safeDump');
return replacement;
},
});
}
});
}
},
CallExpression(node) {
const callee = node.callee;
if (isUnsafeMethod(callee)) {
const scope = sourceCode.getScope(node);
const variable = scope.variables.find((v) => v.name === callee.name);
if (variable && variable.defs.length) {
const [def] = variable.defs;
if (def?.parent?.source?.value === 'js-yaml') {
context.report({
node: callee,
message:
'Use `safeLoad` instead of `load` and `safeDump` instead of `dump` from `js-yaml`.',
fix(fixer) {
const replacement =
callee.name === 'load'
? fixer.replaceText(callee, 'safeLoad')
: fixer.replaceText(callee, 'safeDump');
return replacement;
},
});
}
}
}
if (
callee.type === 'MemberExpression' &&
isUnsafeMethod(callee.property) &&
jsYamlIdentifiers.has(callee.object.name)
) {
context.report({
node: callee.property,
message:
'Use `safeLoad` instead of `load` and `safeDump` instead of `dump` from `js-yaml`.',
fix(fixer) {
const replacement =
callee.property.name === 'load'
? fixer.replaceText(callee.property, 'safeLoad')
: fixer.replaceText(callee.property, 'safeDump');
return replacement;
},
});
}
},
};
},
};

View file

@ -0,0 +1,104 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
const { RuleTester } = require('eslint');
const rule = require('./no_unsafe_js_yaml');
const ruleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
parserOptions: {
sourceType: 'module',
ecmaVersion: 2018,
},
});
ruleTester.run('no_unsafe_js_yaml', rule, {
valid: [
"import { safeLoad } from 'js-yaml'; const data = safeLoad(yamlString);",
"import { safeDump } from 'js-yaml'; const yaml = safeDump(data);",
"import * as yaml from 'js-yaml'; const data = yaml.safeLoad(yamlString);",
"import yaml from 'js-yaml'; yaml.safeLoad('yamlString');",
],
invalid: [
{
code: "import { load } from 'js-yaml'; const data = load(yamlString);",
errors: [
{
message:
'Use `safeLoad` instead of `load` and `safeDump` instead of `dump` from `js-yaml`.',
line: 1,
column: 10,
endLine: 1,
endColumn: 14,
},
{
message:
'Use `safeLoad` instead of `load` and `safeDump` instead of `dump` from `js-yaml`.',
line: 1,
column: 46,
endLine: 1,
endColumn: 50,
},
],
output: "import { safeLoad } from 'js-yaml'; const data = safeLoad(yamlString);",
},
{
code: "import { dump } from 'js-yaml'; const yaml = dump(data);",
errors: [
{
message:
'Use `safeLoad` instead of `load` and `safeDump` instead of `dump` from `js-yaml`.',
line: 1,
column: 10,
endLine: 1,
endColumn: 14,
},
{
message:
'Use `safeLoad` instead of `load` and `safeDump` instead of `dump` from `js-yaml`.',
line: 1,
column: 46,
endLine: 1,
endColumn: 50,
},
],
output: "import { safeDump } from 'js-yaml'; const yaml = safeDump(data);",
},
{
code: "import * as yaml from 'js-yaml'; const data = yaml.load(yamlString);",
errors: [
{
message:
'Use `safeLoad` instead of `load` and `safeDump` instead of `dump` from `js-yaml`.',
},
],
output: "import * as yaml from 'js-yaml'; const data = yaml.safeLoad(yamlString);",
},
{
code: "import yaml from 'js-yaml'; yaml.load('someYAMLContent')",
errors: [
{
message:
'Use `safeLoad` instead of `load` and `safeDump` instead of `dump` from `js-yaml`.',
},
],
output: "import yaml from 'js-yaml'; yaml.safeLoad('someYAMLContent')",
},
{
code: "import yaml, { safeDump } from 'js-yaml'; safeDump(data); yaml.load('someYAMLContent');",
errors: [
{
message:
'Use `safeLoad` instead of `load` and `safeDump` instead of `dump` from `js-yaml`.',
},
],
output:
"import yaml, { safeDump } from 'js-yaml'; safeDump(data); yaml.safeLoad('someYAMLContent');",
},
],
});

View file

@ -7,7 +7,7 @@
*/
import chalk from 'chalk';
import { dump } from 'js-yaml';
import { safeDump } from 'js-yaml';
import { isPlainObjectType } from './is_plain_object_type';
/**
@ -32,7 +32,9 @@ export function extractByJsonPointer(document: unknown, pointer: string): unknow
throw new Error(
`JSON Pointer ${chalk.bold(pointer)} resolution failure. Expected ${chalk.magenta(
path.join('/')
)} to be a plain object but it has type "${typeof target}" in \n\n${dump(document)}`
)} to be a plain object but it has type "${typeof target}" in \n\n${safeDump(document, {
skipInvalid: true,
})}`
);
}
@ -66,7 +68,7 @@ export function extractObjectByJsonPointer(
throw new Error(
`JSON Pointer resolution failure. Expected ${chalk.magenta(
pointer
)} to be a plain object in \n\n${dump(document)}`
)} to be a plain object in \n\n${safeDump(document, { skipInvalid: true })}`
);
}

View file

@ -8,7 +8,7 @@
import fs from 'fs/promises';
import { basename, extname } from 'path';
import { load } from 'js-yaml';
import { safeLoad } from 'js-yaml';
import chalk from 'chalk';
import { logger } from '../logger';
import { isPlainObjectType } from './is_plain_object_type';
@ -45,7 +45,7 @@ async function readYamlFile(filePath: string): Promise<Record<string, unknown>>
// Typing load's result to Record<string, unknown> is optimistic as we can't be sure
// there is object inside a yaml file. We don't have this validation layer so far
// but using JSON Schemas here should mitigate this problem.
return load(await fs.readFile(filePath, { encoding: 'utf8' }));
return safeLoad(await fs.readFile(filePath, { encoding: 'utf8' }));
}
async function readJsonFile(filePath: string): Promise<Record<string, unknown>> {

View file

@ -7,7 +7,7 @@
*/
import fs from 'fs/promises';
import { dump } from 'js-yaml';
import { safeDump } from 'js-yaml';
import { dirname } from 'path';
export async function writeYamlDocument(filePath: string, document: unknown): Promise<void> {
@ -23,21 +23,16 @@ export async function writeYamlDocument(filePath: string, document: unknown): Pr
function stringifyToYaml(document: unknown): string {
try {
// We don't want to have `undefined` values serialized into YAML.
// `JSON.stringify()` simply skips `undefined` values while js-yaml v 3.14 DOES NOT.
// js-yaml >= v4 has it fixed so `dump()`'s behavior is consistent with `JSON.stringify()`.
// Until js-yaml is updated to v4 use the hack with JSON serialization/deserialization.
const clearedDocument = JSON.parse(JSON.stringify(document));
// Disable YAML Anchors https://yaml.org/spec/1.2.2/#3222-anchors-and-aliases
// It makes YAML much more human readable
return dump(clearedDocument, {
return safeDump(document, {
noRefs: true,
sortKeys: sortYamlKeys,
skipInvalid: true, // Skip invalid types like `undefined`
});
} catch (e) {
// Try to stringify with YAML Anchors enabled
return dump(document, { noRefs: false, sortKeys: sortYamlKeys });
return safeDump(document, { noRefs: false, sortKeys: sortYamlKeys, skipInvalid: true });
}
}

View file

@ -16,7 +16,7 @@ import {
unlinkSync,
writeFileSync,
} from 'fs';
import { dump, load } from 'js-yaml';
import { safeDump, safeLoad } from 'js-yaml';
import { OpenAPIV3 } from 'openapi-types';
import { bundle, BundlerConfig } from '../../src/openapi_bundler';
@ -56,7 +56,10 @@ function dumpSpecs(folderPath: string, oasSpecs: Record<string, OpenAPIV3.Docume
mkdirSync(folderPath, { recursive: true });
for (const [fileName, oasSpec] of Object.entries(oasSpecs)) {
writeFileSync(join(folderPath, `${fileName}.schema.yaml`), dump(oasSpec));
writeFileSync(
join(folderPath, `${fileName}.schema.yaml`),
safeDump(oasSpec, { skipInvalid: true }) // Skip invalid types like `undefined`
);
}
}
@ -66,7 +69,7 @@ export function readBundledSpecs(folderPath: string): Record<string, OpenAPIV3.D
for (const fileName of readdirSync(folderPath)) {
const yaml = readFileSync(join(folderPath, fileName), { encoding: 'utf8' });
bundledSpecs[fileName] = load(yaml);
bundledSpecs[fileName] = safeLoad(yaml);
}
return bundledSpecs;

View file

@ -7,7 +7,7 @@
*/
import { readFileSync } from 'fs';
import { load } from 'js-yaml';
import { safeLoad } from 'js-yaml';
import { join } from 'path';
import { bundleFolder, readBundledSpecs } from './bundle_specs';
@ -25,7 +25,7 @@ describe('OpenAPI Bundler - specs with multiple modifications', () => {
const [bundledSpec] = Object.values(readBundledSpecs(outputFolderPath));
const expected = load(
const expected = safeLoad(
readFileSync(join(folderToBundlePath, 'expected.yaml'), { encoding: 'utf8' })
);

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import { dump } from 'js-yaml';
import { safeDump } from 'js-yaml';
import { OpenAPIV3 } from 'openapi-types';
import { bundleSpecs } from './bundle_specs';
import { createOASDocument } from '../create_oas_document';
@ -48,7 +48,8 @@ describe('OpenAPI Bundler - circular specs', () => {
})
);
expect(dump(bundledSpec.paths['/api/some_api']!.get!.responses['200'])).toMatchInlineSnapshot(`
expect(safeDump(bundledSpec.paths['/api/some_api']!.get!.responses['200']))
.toMatchInlineSnapshot(`
"content:
application/json:
schema: &ref_0

View file

@ -16,7 +16,7 @@ import {
unlinkSync,
writeFileSync,
} from 'fs';
import { dump, load } from 'js-yaml';
import { safeDump, safeLoad } from 'js-yaml';
import { OpenAPIV3 } from 'openapi-types';
import { merge, MergerConfig } from '../../src/openapi_merger';
@ -56,7 +56,10 @@ function dumpSpecs(folderPath: string, oasSpecs: Record<string, OpenAPIV3.Docume
mkdirSync(folderPath, { recursive: true });
for (const [fileName, oasSpec] of Object.entries(oasSpecs)) {
writeFileSync(join(folderPath, `${fileName}.schema.yaml`), dump(oasSpec));
writeFileSync(
join(folderPath, `${fileName}.schema.yaml`),
safeDump(oasSpec, { skipInvalid: true })
);
}
}
@ -66,7 +69,7 @@ export function readMergedSpecs(folderPath: string): Record<string, OpenAPIV3.Do
for (const fileName of readdirSync(folderPath)) {
const yaml = readFileSync(join(folderPath, fileName), { encoding: 'utf8' });
mergedSpecs[fileName] = load(yaml);
mergedSpecs[fileName] = safeLoad(yaml);
}
return mergedSpecs;

View file

@ -19,7 +19,7 @@ var allManifestPaths = Object.values(manifestsSource).flat();
try {
for (var manifestRelPath of allManifestPaths) {
var manifest = yaml.load(fs.readFileSync(manifestRelPath, 'utf8'));
var manifest = yaml.safeLoad(fs.readFileSync(manifestRelPath, 'utf8'));
if (manifest.enabled) {
manifest.enabled.forEach(function (x) {
console.log(x);

View file

@ -8,7 +8,7 @@
import { readFileSync, writeFileSync } from 'fs';
import { resolve } from 'path';
import { dump } from 'js-yaml';
import { safeDump } from 'js-yaml';
import { Build, Config, mkdirp } from '../../lib';
export async function createOSPackageKibanaYML(config: Config, build: Build) {
@ -24,7 +24,7 @@ export async function createOSPackageKibanaYML(config: Config, build: Build) {
[/#pid.file:.*/g, 'pid.file: /run/kibana/kibana.pid'],
[
/#logging.appenders.default:.*kibana\.log\n/gs,
dump({
safeDump({
logging: {
appenders: {
file: {

View file

@ -14,7 +14,7 @@ import { DEFAULTS } from '../constants';
export async function readConfig(filePath: string): Promise<PartialConfig> {
const data = await promises.readFile(filePath);
const decodedPartialConfig = PartialConfigRT.decode(yaml.load(data.toString()));
const decodedPartialConfig = PartialConfigRT.decode(yaml.safeLoad(data.toString()));
if (isLeft(decodedPartialConfig)) {
throw new Error(
`Could not validate config: ${PathReporter.report(decodedPartialConfig).join('\n')}`

View file

@ -48,7 +48,7 @@ export function getSelectorsAndResponsesFromYaml(configuration: string): {
let responses: Response[] = [];
try {
const result = yaml.load(configuration);
const result = yaml.safeLoad(configuration);
if (result) {
// iterate selector/response types
@ -107,5 +107,5 @@ export function getYamlFromSelectorsAndResponses(selectors: Selector[], response
return current;
}, schema);
return yaml.dump(schema);
return yaml.safeDump(schema);
}

View file

@ -44,7 +44,7 @@ describe('<ControlGeneralView />', () => {
const configuration = input?.vars?.configuration?.value;
try {
const json = yaml.load(configuration);
const json = yaml.safeLoad(configuration);
expect(json.file.selectors.length).toBe(getAllByTestId('cloud-defend-selector').length);
expect(json.file.responses.length).toBe(getAllByTestId('cloud-defend-file-response').length);
@ -69,7 +69,7 @@ describe('<ControlGeneralView />', () => {
const configuration = input?.vars?.configuration?.value;
try {
const json = yaml.load(configuration);
const json = yaml.safeLoad(configuration);
expect(json.file.selectors.length).toBe(getAllByTestId('cloud-defend-selector').length);
} catch (err) {
@ -91,7 +91,7 @@ describe('<ControlGeneralView />', () => {
const configuration = input?.vars?.configuration?.value;
try {
const json = yaml.load(configuration);
const json = yaml.safeLoad(configuration);
expect(json.file.responses.length).toBe(getAllByTestId('cloud-defend-file-response').length);
} catch (err) {
@ -113,7 +113,7 @@ describe('<ControlGeneralView />', () => {
const configuration = input?.vars?.configuration?.value;
try {
const json = yaml.load(configuration);
const json = yaml.safeLoad(configuration);
expect(json.process.responses.length).toBe(
getAllByTestId('cloud-defend-process-response').length
@ -166,7 +166,7 @@ describe('<ControlGeneralView />', () => {
const configuration = input?.vars?.configuration?.value;
try {
const json = yaml.load(configuration);
const json = yaml.safeLoad(configuration);
expect(json.file.responses[0].match).toHaveLength(1);
} catch (err) {
@ -205,7 +205,7 @@ describe('<ControlGeneralView />', () => {
const configuration = input?.vars?.configuration?.value;
try {
const json = yaml.load(configuration);
const json = yaml.safeLoad(configuration);
expect(json.file.selectors).toHaveLength(4);
expect(json.file.selectors[3].name).toEqual(json.file.selectors[0].name + '1');

View file

@ -205,7 +205,7 @@ function decodeDiscoveryRulesYaml(
defaultDiscoveryRules: IDiscoveryRule[] = []
): IDiscoveryRule[] {
try {
const parsedYaml: DiscoveryRulesParsedYaml = yaml.load(discoveryRulesYaml) ?? [];
const parsedYaml: DiscoveryRulesParsedYaml = yaml.safeLoad(discoveryRulesYaml) ?? [];
if (parsedYaml.length === 0) {
return defaultDiscoveryRules;
@ -232,5 +232,5 @@ function encodeDiscoveryRulesYaml(discoveryRules: IDiscoveryRule[]): string {
[`${operation}-${type}`]: probe,
})
);
return yaml.dump(mappedDiscoveryRules);
return yaml.safeDump(mappedDiscoveryRules);
}

View file

@ -99,7 +99,7 @@ function ensureValidMultiText(textMultiValue: string[] | undefined) {
function escapeInvalidYamlString(yamlString: string) {
try {
yaml.load(yamlString);
yaml.safeLoad(yamlString);
} catch (error) {
if (error instanceof yaml.YAMLException) {
return `"${yamlString}"`;

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { dump } from 'js-yaml';
import { safeDump } from 'js-yaml';
import { generateCustomLogsYml } from './generate_custom_logs_yml';
const baseMockConfig = {
@ -46,7 +46,7 @@ describe('generateCustomLogsYml', () => {
it('should return a yml configuration with customConfigurations', () => {
const mockConfig = {
...baseMockConfig,
customConfigurations: dump({
customConfigurations: safeDump({
['agent.retry']: {
enabled: true,
retriesCount: 3,

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { dump, load } from 'js-yaml';
import { safeDump, safeLoad } from 'js-yaml';
export const generateCustomLogsYml = ({
datasetName = '',
@ -26,7 +26,7 @@ export const generateCustomLogsYml = ({
esHost: string[];
logfileId: string;
}) => {
const customConfigYaml = load(customConfigurations ?? '');
const customConfigYaml = safeLoad(customConfigurations ?? '');
const processors = [
{
add_fields: {
@ -38,7 +38,7 @@ export const generateCustomLogsYml = ({
},
];
return dump({
return safeDump({
...{
outputs: {
default: {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { dump } from 'js-yaml';
import { safeDump } from 'js-yaml';
interface SystemLogsStream {
id: string;
@ -36,7 +36,7 @@ export const generateSystemLogsYml = ({
esHost: string[];
uuid: string;
}) => {
return dump({
return safeDump({
outputs: {
default: {
type: 'elasticsearch',

View file

@ -12,7 +12,7 @@ import {
FleetUnauthorizedError,
type PackageClient,
} from '@kbn/fleet-plugin/server';
import { dump } from 'js-yaml';
import { safeDump } from 'js-yaml';
import { PackageDataStreamTypes } from '@kbn/fleet-plugin/common/types';
import { getObservabilityOnboardingFlow, saveObservabilityOnboardingFlow } from '../../lib/state';
import type { SavedObservabilityOnboardingFlow } from '../../saved_objects/observability_onboarding_status';
@ -501,7 +501,7 @@ function parseIntegrationsTSV(tsv: string) {
}
const generateAgentConfig = ({ esHost, inputs = [] }: { esHost: string[]; inputs: unknown[] }) => {
return dump({
return safeDump({
outputs: {
default: {
type: 'elasticsearch',

View file

@ -138,7 +138,7 @@ const manageZipFields = async (beat, filePath, beatFields) => {
try {
await extract(filePath, { dir: beat.outputDir });
console.log('building fields', beat.index);
const obj = yaml.load(
const obj = yaml.safeLoad(
fs.readFileSync(`${beat.outputDir}/winlogbeat-${BEATS_VERSION}-windows-x86_64/fields.yml`, {
encoding: 'utf-8',
})
@ -172,7 +172,7 @@ const manageTarFields = async (beat, filePath, beatFields) =>
return reject(new Error(err));
}
console.log('building fields', beat.index);
const obj = yaml.load(
const obj = yaml.safeLoad(
fs.readFileSync(`${beat.outputDir}/fields.yml`, { encoding: 'utf-8' })
);
const ebeatFields = convertSchemaToHash(obj, beatFields);

View file

@ -11,7 +11,7 @@ import type { KbnClient } from '@kbn/test';
import type { ToolingLog } from '@kbn/tooling-log';
import chalk from 'chalk';
import execa from 'execa';
import { dump } from 'js-yaml';
import { safeDump } from 'js-yaml';
import {
fetchFleetServerUrl,
getAgentVersionMatchingCurrentStack,
@ -111,7 +111,7 @@ export const startElasticAgentWithDocker = async ({
})
).stdout;
} catch (error) {
log.error(dump(error));
log.error(safeDump(error));
throw error;
}

View file

@ -6,7 +6,7 @@
*/
import expect from '@kbn/expect';
import { load } from 'js-yaml';
import { safeLoad } from 'js-yaml';
import { FtrProviderContext } from '../../common/ftr_provider_context';
export default function ApiTest({ getService }: FtrProviderContext) {
@ -39,7 +39,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
expect(req.status).to.be(200);
const ymlConfig = load(req.text);
const ymlConfig = safeLoad(req.text);
expect(ymlConfig.inputs[0].data_stream.namespace).to.be('');
expect(ymlConfig.inputs[0].streams[0].data_stream.dataset).to.be('');
expect(ymlConfig.inputs[0].streams[0].paths).to.be.empty();
@ -75,7 +75,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
expect(req.status).to.be(200);
const ymlConfig = load(req.text);
const ymlConfig = safeLoad(req.text);
expect(ymlConfig.inputs[0].data_stream.namespace).to.be(namespace);
expect(ymlConfig.inputs[0].streams[0].data_stream.dataset).to.be(datasetName);
expect(ymlConfig.inputs[0].streams[0].paths).to.be.eql([logFilepath]);
@ -107,7 +107,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
expect(req.status).to.be(200);
const ymlConfig = load(req.text);
const ymlConfig = safeLoad(req.text);
expect(ymlConfig.inputs[0].data_stream.namespace).to.be('default');
expect(ymlConfig.inputs[0].streams.length).to.be(2);
expect(ymlConfig.inputs[0].streams[0].data_stream.dataset).to.be('system.auth');