From d475b6c0229be86d99195746305252523830ffa7 Mon Sep 17 00:00:00 2001
From: Aaron Cannon <98414629+aaroncannoncv@users.noreply.github.com>
Date: Wed, 23 Oct 2024 11:22:15 -0400
Subject: [PATCH 1/2] Escape special characters in strings to render as
expected for json
---
demo/src/js/entry.js | 2 +-
dev-server/src/index.js | 27 +++++++++--
src/js/components/DataTypes/String.js | 4 +-
src/js/components/VariableEditor.js | 4 +-
src/js/helpers/util.js | 9 ++++
.../js/components/DataTypes/String-test.js | 14 ++++++
.../js/components/VariableEditor-test.js | 48 ++++++++++++++-----
test/tests/js/helpers/Util-test.js | 31 +++++++++++-
8 files changed, 116 insertions(+), 23 deletions(-)
diff --git a/demo/src/js/entry.js b/demo/src/js/entry.js
index 883f8dc..cb7e1c0 100644
--- a/demo/src/js/entry.js
+++ b/demo/src/js/entry.js
@@ -5,7 +5,7 @@ require('./../style/scss/global.scss')
const app = document.getElementById('mac-react-container')
-//app entrypoint
+// app entrypoint
ReactDom.render(
diff --git a/dev-server/src/index.js b/dev-server/src/index.js
index 58e2699..a7bc62d 100644
--- a/dev-server/src/index.js
+++ b/dev-server/src/index.js
@@ -180,6 +180,19 @@ ReactDom.render(
}
src={getExampleJson2()}
/>
+
+ {/* String with special escape sequences */}
+ {
+ console.log('edit callback', e)
+ if (e.new_value == 'error') {
+ return false
+ }
+ }}
+ />
,
document.getElementById('app-container')
)
@@ -189,7 +202,7 @@ ReactDom.render(
/*-------------------------------------------------------------------------*/
//just a function to get an example JSON object
-function getExampleJson1 () {
+function getExampleJson1() {
return {
string: 'this is a test string',
integer: 42,
@@ -218,7 +231,7 @@ function getExampleJson1 () {
}
//and another a function to get an example JSON object
-function getExampleJson2 () {
+function getExampleJson2() {
return {
normalized: {
'1-grams': {
@@ -256,7 +269,7 @@ function getExampleJson2 () {
}
}
-function getExampleJson3 () {
+function getExampleJson3() {
return {
example_information:
'this example has the collapsed prop set to true and the indentWidth prop is set to 8',
@@ -272,7 +285,7 @@ function getExampleJson3 () {
}
}
-function getExampleJson4 () {
+function getExampleJson4() {
const large_array = new Array(225).fill('this is a large array full of items')
large_array.push(getExampleArray())
@@ -282,7 +295,7 @@ function getExampleJson4 () {
return large_array
}
-function getExampleArray () {
+function getExampleArray() {
return [
'you can also display arrays!',
new Date(),
@@ -294,3 +307,7 @@ function getExampleArray () {
}
]
}
+
+function getExampleWithStringEscapeSequences() {
+ return { '\\\n\t\r\f\\n': '\\\n\t\r\f\\n' }
+}
diff --git a/src/js/components/DataTypes/String.js b/src/js/components/DataTypes/String.js
index 29454e5..4faa1d8 100644
--- a/src/js/components/DataTypes/String.js
+++ b/src/js/components/DataTypes/String.js
@@ -1,6 +1,6 @@
import React from 'react'
import DataTypeLabel from './DataTypeLabel'
-import { toType } from './../../helpers/util'
+import { toType, escapeString } from './../../helpers/util'
// theme
import Theme from './../../themes/getStyle'
@@ -46,6 +46,8 @@ export default class extends React.PureComponent {
const collapsible = toType(collapseStringsAfterLength) === 'integer'
const style = { style: { cursor: 'default' } }
+ value = escapeString(value)
+
if (collapsible && value.length > collapseStringsAfterLength) {
style.style.cursor = 'pointer'
if (this.state.collapsed) {
diff --git a/src/js/components/VariableEditor.js b/src/js/components/VariableEditor.js
index 56cbb84..01b7cde 100644
--- a/src/js/components/VariableEditor.js
+++ b/src/js/components/VariableEditor.js
@@ -1,7 +1,7 @@
import React from 'react'
import AutosizeTextarea from 'react-textarea-autosize'
-import { toType } from './../helpers/util'
+import { escapeString } from './../helpers/util'
import dispatcher from './../helpers/dispatcher'
import parseInput from './../helpers/parseInput'
import stringifyVariable from './../helpers/stringifyVariable'
@@ -93,7 +93,7 @@ class VariableEditor extends React.PureComponent {
{!!quotesOnKeys && (
"
)}
- {variable.name}
+ {escapeString(variable.name)}
{!!quotesOnKeys && (
"
)}
diff --git a/src/js/helpers/util.js b/src/js/helpers/util.js
index a11ea83..6654f8a 100644
--- a/src/js/helpers/util.js
+++ b/src/js/helpers/util.js
@@ -23,6 +23,15 @@ function getType (obj) {
.toLowerCase()
}
+export function escapeString (value) {
+ return value
+ .replace(/\\/g, '\\\\')
+ .replace(/\n/g, '\\n')
+ .replace(/\t/g, '\\t')
+ .replace(/\r/g, '\\r')
+ .replace(/\f/g, '\\f')
+}
+
// validation for base-16 themes
export function isTheme (theme) {
const theme_keys = [
diff --git a/test/tests/js/components/DataTypes/String-test.js b/test/tests/js/components/DataTypes/String-test.js
index 1ef0a47..41baea6 100644
--- a/test/tests/js/components/DataTypes/String-test.js
+++ b/test/tests/js/components/DataTypes/String-test.js
@@ -61,4 +61,18 @@ describe('', function () {
'"123456789"'
)
})
+
+ it('string with special escape sequences', function () {
+ const rjvId = 1
+ const props = {
+ value: '\\\n\t\r\f\\n',
+ rjvId: 1,
+ displayDataTypes: false,
+ theme: 'rjv-default'
+ }
+ const component = mount().render()
+ expect(component.find('.string-value').text()).to.equal(
+ '"\\\\\\n\\t\\r\\f\\\\n"'
+ )
+ })
})
diff --git a/test/tests/js/components/VariableEditor-test.js b/test/tests/js/components/VariableEditor-test.js
index fe5c100..9d1f57c 100644
--- a/test/tests/js/components/VariableEditor-test.js
+++ b/test/tests/js/components/VariableEditor-test.js
@@ -13,7 +13,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
singleIndent={1}
variable={{
@@ -48,7 +48,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -66,7 +66,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -172,7 +172,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -192,7 +192,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -212,7 +212,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -232,7 +232,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -252,7 +252,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -274,7 +274,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -294,7 +294,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -314,7 +314,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -334,7 +334,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -348,4 +348,28 @@ describe('', function () {
expect(wrapper.state('editMode')).to.equal(true)
expect(wrapper.find('.variable-editor').props().value).to.equal('5')
})
+
+ it('VariableEditor renders escaped characters', function () {
+ const wrapper = shallow(
+ { }}
+ rjvId={rjvId}
+ variable={{
+ name: '\\\n\t\r\f\\n',
+ value: '\\\n\t\r\f\\n',
+ type: 'string'
+ }}
+ />
+ )
+ console.log(wrapper.debug())
+ expect(wrapper.find('.object-key').text()).to.equal('\\\\\\n\\t\\r\\f\\\\n')
+ expect(wrapper.find('.click-to-edit-icon').length).to.equal(1)
+ wrapper.find('.click-to-edit-icon').simulate('click')
+ expect(wrapper.state('editMode')).to.equal(true)
+ expect(wrapper.find('.variable-editor').props().value).to.equal(
+ '\\\n\t\r\f\\n'
+ )
+ })
})
diff --git a/test/tests/js/helpers/Util-test.js b/test/tests/js/helpers/Util-test.js
index fce258d..19d51ba 100644
--- a/test/tests/js/helpers/Util-test.js
+++ b/test/tests/js/helpers/Util-test.js
@@ -1,7 +1,7 @@
import React from 'react'
import { expect } from 'chai'
-import { toType, isTheme } from './../../../../src/js/helpers/util'
+import { toType, isTheme, escapeString } from './../../../../src/js/helpers/util'
describe('toType', function () {
it('toType object', function () {
@@ -30,7 +30,7 @@ describe('toType', function () {
})
it('toType function', function () {
- const test = () => {}
+ const test = () => { }
expect(toType(test)).to.equal('function')
})
@@ -60,6 +60,33 @@ describe('toType', function () {
})
})
+describe('escapeString', function () {
+ it('escape \\\\', function () {
+ const test = '\\'
+ expect(escapeString(test)).to.equal('\\\\')
+ })
+ it('escape \\n', function () {
+ const test = '\n'
+ expect(escapeString(test)).to.equal('\\n')
+ })
+ it('escape \\t', function () {
+ const test = '\t'
+ expect(escapeString(test)).to.equal('\\t')
+ })
+ it('escape \\r', function () {
+ const test = '\r'
+ expect(escapeString(test)).to.equal('\\r')
+ })
+ it('escape \\f', function () {
+ const test = '\f'
+ expect(escapeString(test)).to.equal('\\f')
+ })
+ it('escape \\\\n', function () {
+ const test = '\\n'
+ expect(escapeString(test)).to.equal('\\\\n')
+ })
+})
+
describe('isTheme', function () {
it('isTheme valid theme', function () {
const test = {
From 41ee6567b9c06571862cd114feed733ac5ebb6b5 Mon Sep 17 00:00:00 2001
From: aaroncannoncv <98414629+aaroncannoncv@users.noreply.github.com>
Date: Wed, 23 Oct 2024 11:27:03 -0400
Subject: [PATCH 2/2] Remove update to entry.js
---
demo/src/js/entry.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/demo/src/js/entry.js b/demo/src/js/entry.js
index cb7e1c0..883f8dc 100644
--- a/demo/src/js/entry.js
+++ b/demo/src/js/entry.js
@@ -5,7 +5,7 @@ require('./../style/scss/global.scss')
const app = document.getElementById('mac-react-container')
-// app entrypoint
+//app entrypoint
ReactDom.render(