Skip to content

Commit 0962d03

Browse files
authored
Merge pull request #4 from sreelakshmi-bruno/decode-forward-slash
Decode forward slash
2 parents 7277571 + 5497dcd commit 0962d03

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

src/index.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* Pretty-prints a JSON-like string without parsing.
33
* Fast path: chunked copying, fast string scan, lookahead for empty {} / [].
4+
* Decodes \uXXXX unicode sequences and \/ forward slash escapes for readability.
45
*
56
* @param {string} input
67
* @param {string} indent
@@ -45,6 +46,7 @@ function fastJsonFormat(input, indent = ' ') {
4546
// Character codes
4647
const QUOTE = 34; // "
4748
const BACKSLASH = 92; // \
49+
const FORWARD_SLASH = 47;// /
4850
const OPEN_BRACE = 123; // {
4951
const CLOSE_BRACE = 125; // }
5052
const OPEN_BRACKET = 91; // [
@@ -97,7 +99,7 @@ function fastJsonFormat(input, indent = ' ') {
9799
};
98100

99101
// Scan a JSON string starting at index of opening quote `i` (s[i] === '"').
100-
// Returns index just after the closing quote and decodes \uXXXX sequences.
102+
// Returns index just after the closing quote and decodes \uXXXX and \/ sequences.
101103
const scanString = (i) => {
102104
out.push('"'); // opening quote
103105
let j = i + 1;
@@ -134,6 +136,16 @@ function fastJsonFormat(input, indent = ' ') {
134136
}
135137
// If parsing failed, reset and let it be copied as-is
136138
j = backslashPos + 1;
139+
} else if (j < n && s.charCodeAt(j) === FORWARD_SLASH) {
140+
// Found \/ - decode to / for readability
141+
// Copy everything up to the backslash
142+
if (backslashPos > lastCopy) {
143+
out.push(s.slice(lastCopy, backslashPos));
144+
}
145+
out.push('/');
146+
j++; // skip the forward slash
147+
lastCopy = j;
148+
continue;
137149
}
138150
// For other escapes (or invalid \u), just skip the escaped char
139151
if (j < n) j++;

tests/escaped.spec.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,55 @@ describe('escaped characters', () => {
6666
}`;
6767
assertEqual(input, expected);
6868
});
69+
});
70+
71+
describe('forward slash escape sequences', () => {
72+
it('should decode \\/ escape sequences to forward slashes', () => {
73+
const input = '{"url":"https:\\/\\/example.com\\/api\\/v1"}';
74+
const expected = `{
75+
"url": "https://example.com/api/v1"
76+
}`;
77+
assertEqual(input, expected);
78+
});
79+
80+
it('should handle unescaped forward slashes correctly', () => {
81+
const input = '{"url":"https://example.com/api/v1"}';
82+
const expected = `{
83+
"url": "https://example.com/api/v1"
84+
}`;
85+
assertEqual(input, expected);
86+
});
87+
88+
it('should handle forward slashes mixed with other escape sequences', () => {
89+
const input = '{"text":"line1\\npath\\/to\\/file\\ttab","unicode":"\\u4e16\\u754c\\/path"}';
90+
const expected = `{
91+
"text": "line1\\npath/to/file\\ttab",
92+
"unicode": "世界/path"
93+
}`;
94+
assertEqual(input, expected);
95+
});
96+
97+
it('should handle a single escaped forward slash', () => {
98+
const input = '{"slash":"\\/"}';
99+
const expected = `{
100+
"slash": "/"
101+
}`;
102+
assertEqual(input, expected);
103+
});
104+
105+
it('should handle multiple consecutive escaped forward slashes', () => {
106+
const input = '{"path":"\\/\\/network\\/share"}';
107+
const expected = `{
108+
"path": "//network/share"
109+
}`;
110+
assertEqual(input, expected);
111+
});
112+
113+
it('should handle escaped forward slash at end of string', () => {
114+
const input = '{"url":"https://example.com\\/"}';
115+
const expected = `{
116+
"url": "https://example.com/"
117+
}`;
118+
assertEqual(input, expected);
119+
});
69120
});

0 commit comments

Comments
 (0)