Skip to content

Commit

Permalink
#15 - escape special chars in environment variable values when storin…
Browse files Browse the repository at this point in the history
…g in a file
  • Loading branch information
callmekatootie committed Apr 12, 2024
1 parent 891f7a9 commit 6e2bc12
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 7 deletions.
39 changes: 37 additions & 2 deletions src/lib/envLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,26 @@ const fs = require('fs')
const fsp = require('fs').promises
const readline = require('readline')

/**
* If a value starts and ends with single quote AND contains special characters,
* this will remove the quote and unescape the special characters
* @param {String} value The value to unquote
*/
function unquoteIfSpecialChars (value) {
if (value.startsWith("'") && value.endsWith("'")) {
let content = value.slice(1, -1)
// Unescape any single quotes within the content
content = content.replace(/'\\''/g, "'")
// Check for special characters inside the original content
const specialCharsRegex = /[$\\"!` ]/
if (specialCharsRegex.test(content)) {
return content
}
}

return value
}

async function readEnvFile (filename) {
const aParams = []

Expand All @@ -18,7 +38,7 @@ async function readEnvFile (filename) {
if (aLine.length === 2) {
aParams.push({
key: aLine[0],
value: aLine[1]
value: unquoteIfSpecialChars(aLine[1])
})
}
})
Expand Down Expand Up @@ -76,11 +96,26 @@ async function loadFileIntoEnv (filename) {
loadParamsIntoEnv(params)
}

/**
* Returns the value in single quote if it contains special characters
* else returns the value as is
* @param {String} value The value to quote
*/
function quoteIfSpecialChars (value) {
const specialCharsRegex = /[$\\"!` ]/

if (specialCharsRegex.test(value)) {
return `'${value.replace(/'/g, "'\\''")}'`
} else {
return value
}
}

async function paramsToSourceFile (params, filename) {
const aParams = []

params.forEach((param) => {
aParams.push(`${param.key}=${param.value}`)
aParams.push(`${param.key}=${quoteIfSpecialChars(param.value)}`)
})

const paramsToString = aParams.join('\n')
Expand Down
29 changes: 24 additions & 5 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ describe('envLoader', async () => {
const params = [
{ key: 'key01', value: 'value01' },
{ key: 'key02', value: 'value02' },
{ key: 'key03', value: 'value03' }
{ key: 'key03', value: 'value03' },
{ key: 'key04', value: 'special$code' },
{ key: 'key05', value: '"quoted"' },
{ key: 'key06', value: '`code`!' }
]

describe('paramsToSourceFile', async () => {
Expand All @@ -26,7 +29,14 @@ describe('envLoader', async () => {
for (let i = 0; i < aParams.length; i++) {
const aLine = aParams[i].split('=')
aLine[0].should.equal(params[i].key)
aLine[1].should.equal(params[i].value)

const specialCharsRegex = /[$\\"!` ]/

if (specialCharsRegex.test(aLine[1])) {
aLine[1].should.equal(`'${params[i].value}'`)
} else {
aLine[1].should.equal(params[i].value)
}
}
})
})
Expand Down Expand Up @@ -57,7 +67,10 @@ describe('envLoader', async () => {
const testParams = [
{ key: 'new_key_01', value: 'value01' },
{ key: 'new_key_02', value: 'value02' },
{ key: 'new_key_03', value: 'value03' }
{ key: 'new_key_03', value: 'value03' },
{ key: 'new_key_04', value: 'special$code' },
{ key: 'new_key_05', value: '"quoted"' },
{ key: 'new_key_06', value: '`code`!' }
]
const remapped = envLoader.remapKeys(params, 'key', 'new_key_')
remapped.should.deep.equal(testParams)
Expand All @@ -69,12 +82,18 @@ describe('envLoader', async () => {
const testParams = [
{ key: 'new_key_01', value: 'value01' },
{ key: 'new_key_02', value: 'value02' },
{ key: 'new_key_03', value: 'value03' }
{ key: 'new_key_03', value: 'value03' },
{ key: 'new_key_04', value: 'special$code' },
{ key: 'new_key_05', value: '"quoted"' },
{ key: 'new_key_06', value: '`code`!' }
]
const testParams2 = [
{ key: 'key_01', value: 'value01' },
{ key: 'key_02', value: 'value02' },
{ key: 'key_03', value: 'value03' }
{ key: 'key_03', value: 'value03' },
{ key: 'new_key_04', value: 'special$code' },
{ key: 'new_key_05', value: '"quoted"' },
{ key: 'new_key_06', value: '`code`!' }
]

const remapped = envLoader.remapKeysInEnv('key', 'new_key_', params)
Expand Down

0 comments on commit 6e2bc12

Please sign in to comment.