Skip to content

Commit 34936f9

Browse files
committed
In JavaScriptEngineSwitcher.ChakraCore fixed a errors, that occurred during marshaling of Unicode strings in Unix-based operating systems
1 parent f28ad46 commit 34936f9

File tree

5 files changed

+131
-15
lines changed

5 files changed

+131
-15
lines changed

NuGet/JavaScriptEngineSwitcher.ChakraCore/JavaScriptEngineSwitcher.ChakraCore.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
For correct working of the ChakraCore require assemblies `msvcp120.dll` and `msvcr120.dll` from the Visual C++ Redistributable Packages for Visual Studio 2013.</description>
1616
<summary>JavaScriptEngineSwitcher.ChakraCore contains adapter `ChakraCoreJsEngine` (wrapper for the ChakraCore version 1.3).</summary>
17-
<releaseNotes>Fixed a text encoding errors.</releaseNotes>
17+
<releaseNotes>Fixed a errors, that occurred during marshaling of Unicode strings in Unix-based operating systems.</releaseNotes>
1818
<copyright>Copyright (c) 2013-2016 Andrey Taritsyn - http://www.taritsyn.ru</copyright>
1919
<language>en-US</language>
2020
<tags>JavaScriptEngineSwitcher JavaScript ECMAScript ChakraCore</tags>

NuGet/JavaScriptEngineSwitcher.ChakraCore/readme.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
=============
2525
RELEASE NOTES
2626
=============
27-
Fixed a text encoding errors.
27+
Fixed a errors, that occurred during marshaling of Unicode strings in Unix-based
28+
operating systems.
2829

2930
====================
3031
POST-INSTALL ACTIONS

src/JavaScriptEngineSwitcher.ChakraCore/JsRt/JsValue.cs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Runtime.InteropServices;
3+
using System.Text;
34

45
using JavaScriptEngineSwitcher.Core.Utilities;
56

@@ -303,11 +304,18 @@ public static JsValue FromInt32(int value)
303304
public static JsValue FromString(string value)
304305
{
305306
JsValue reference;
306-
JsErrorCode errorCode = Utils.IsWindows() ?
307-
NativeMethods.JsPointerToString(value, new UIntPtr((uint)value.Length), out reference)
308-
:
309-
NativeMethods.JsPointerToStringUtf8(value, new UIntPtr((uint)value.Length), out reference)
310-
;
307+
JsErrorCode errorCode;
308+
309+
if (Utils.IsWindows())
310+
{
311+
int stringLength = value.Length;
312+
errorCode = NativeMethods.JsPointerToString(value, new UIntPtr((uint)stringLength), out reference);
313+
}
314+
else
315+
{
316+
int byteCount = Encoding.GetEncoding(0).GetByteCount(value);
317+
errorCode = NativeMethods.JsPointerToStringUtf8(value, new UIntPtr((uint)byteCount), out reference);
318+
}
311319

312320
JsErrorHelpers.ThrowIfError(errorCode);
313321

@@ -574,24 +582,25 @@ public double ToDouble()
574582
/// <returns>The string</returns>
575583
public new string ToString()
576584
{
577-
IntPtr buffer;
578-
UIntPtr length;
585+
IntPtr ptr;
579586
JsErrorCode errorCode;
580587
string result;
581588

582589
if (Utils.IsWindows())
583590
{
584-
errorCode = NativeMethods.JsStringToPointer(this, out buffer, out length);
591+
UIntPtr stringLength;
592+
errorCode = NativeMethods.JsStringToPointer(this, out ptr, out stringLength);
585593
JsErrorHelpers.ThrowIfError(errorCode);
586594

587-
result = Marshal.PtrToStringUni(buffer, (int)length);
595+
result = Marshal.PtrToStringUni(ptr, (int)stringLength);
588596
}
589597
else
590598
{
591-
errorCode = NativeMethods.JsStringToPointerUtf8Copy(this, out buffer, out length);
599+
UIntPtr byteCount;
600+
errorCode = NativeMethods.JsStringToPointerUtf8Copy(this, out ptr, out byteCount);
592601
JsErrorHelpers.ThrowIfError(errorCode);
593602

594-
result = Marshal.PtrToStringAnsi(buffer, (int)length);
603+
result = Marshal.PtrToStringAnsi(ptr, (int)byteCount);
595604
}
596605

597606
return result;

src/JavaScriptEngineSwitcher.ChakraCore/JsRt/NativeMethods.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,10 @@ internal static extern JsErrorCode JsRunSerializedScriptUtf8(JsSerializedScriptL
124124
internal static extern JsErrorCode JsGetStringLength(JsValue sringValue, out int length);
125125

126126
[DllImport(DllName)]
127-
internal static extern JsErrorCode JsPointerToStringUtf8(string value, UIntPtr stringLength, out JsValue stringValue);
127+
internal static extern JsErrorCode JsPointerToStringUtf8(string value, UIntPtr byteCount, out JsValue stringValue);
128128

129129
[DllImport(DllName)]
130-
internal static extern JsErrorCode JsStringToPointerUtf8Copy(JsValue value, out IntPtr stringValue, out UIntPtr stringLength);
130+
internal static extern JsErrorCode JsStringToPointerUtf8Copy(JsValue value, out IntPtr bytes, out UIntPtr byteCount);
131131

132132
[DllImport(DllName)]
133133
internal static extern JsErrorCode JsConvertValueToString(JsValue value, out JsValue stringValue);

test/JavaScriptEngineSwitcher.Tests/CommonTestsBase.cs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,25 @@ public virtual void EvaluationOfExpressionWithStringResultIsCorrect()
132132
Assert.Equal(targetOutput, output);
133133
}
134134

135+
[Fact]
136+
public virtual void EvaluationOfExpressionWithUnicodeStringResultIsCorrect()
137+
{
138+
// Arrange
139+
const string input = "'Привет, ' + \"Вася\" + '?';";
140+
const string targetOutput = "Привет, Вася?";
141+
142+
// Act
143+
string output;
144+
145+
using (var jsEngine = CreateJsEngine())
146+
{
147+
output = jsEngine.Evaluate<string>(input);
148+
}
149+
150+
// Assert
151+
Assert.Equal(targetOutput, output);
152+
}
153+
135154
#endregion
136155

137156
#region Execution of code
@@ -392,6 +411,29 @@ public virtual void CallingOfFunctionWithStringResultIsCorrect()
392411
Assert.Equal(targetOutput, output);
393412
}
394413

414+
[Fact]
415+
public virtual void CallingOfFunctionWithUnicodeStringResultIsCorrect()
416+
{
417+
// Arrange
418+
const string functionCode = @"function privet(name) {
419+
return 'Привет, ' + name + '!';
420+
}";
421+
const string input = "Вован";
422+
const string targetOutput = "Привет, Вован!";
423+
424+
// Act
425+
string output;
426+
427+
using (var jsEngine = CreateJsEngine())
428+
{
429+
jsEngine.Execute(functionCode);
430+
output = jsEngine.CallFunction<string>("privet", input);
431+
}
432+
433+
// Assert
434+
Assert.Equal(targetOutput, output);
435+
}
436+
395437
[Fact]
396438
public virtual void CallingOfFunctionWithManyParametersIsCorrect()
397439
{
@@ -554,6 +596,36 @@ public virtual void CallingOfFunctionWithManyParametersAndStringResultIsCorrect(
554596
Assert.Equal("Hello, Petya!", output);
555597
}
556598

599+
[Fact]
600+
public virtual void CallingOfFunctionWithManyParametersAndUnicodeStringResultIsCorrect()
601+
{
602+
// Arrange
603+
const string functionCode = @"function obedinit() {
604+
var result = '',
605+
argumentIndex,
606+
argumentCount = arguments.length
607+
;
608+
609+
for (argumentIndex = 0; argumentIndex < argumentCount; argumentIndex++) {
610+
result += arguments[argumentIndex];
611+
}
612+
613+
return result;
614+
}";
615+
616+
// Act
617+
string output;
618+
619+
using (var jsEngine = CreateJsEngine())
620+
{
621+
jsEngine.Execute(functionCode);
622+
output = jsEngine.CallFunction<string>("obedinit", "Привет", ",", " ", "Петя", "!");
623+
}
624+
625+
// Assert
626+
Assert.Equal("Привет, Петя!", output);
627+
}
628+
557629
#endregion
558630

559631
#region Getting, setting and removing variables
@@ -740,6 +812,40 @@ public virtual void SettingAndGettingVariableWithStringValueIsCorrect()
740812
Assert.Equal(input2, output2);
741813
}
742814

815+
[Fact]
816+
public virtual void SettingAndGettingVariableWithUnicodeStringValueIsCorrect()
817+
{
818+
// Arrange
819+
const string variableName = "slovo";
820+
821+
const string input1 = "Ура";
822+
const string targetOutput1 = "Ура!";
823+
824+
const string input2 = "Урааа";
825+
826+
// Act
827+
bool variableExists;
828+
string output1;
829+
string output2;
830+
831+
using (var jsEngine = CreateJsEngine())
832+
{
833+
jsEngine.SetVariableValue(variableName, input1);
834+
variableExists = jsEngine.HasVariable(variableName);
835+
jsEngine.Execute(string.Format("{0} += '!';", variableName));
836+
output1 = jsEngine.GetVariableValue<string>(variableName);
837+
838+
jsEngine.SetVariableValue(variableName, input2);
839+
output2 = jsEngine.GetVariableValue<string>(variableName);
840+
}
841+
842+
// Assert
843+
Assert.True(variableExists);
844+
Assert.Equal(targetOutput1, output1);
845+
846+
Assert.Equal(input2, output2);
847+
}
848+
743849
[Fact]
744850
public virtual void RemovingVariableIsCorrect()
745851
{

0 commit comments

Comments
 (0)