Permalink
Browse files

Passing string with null bytes and unicode to perl5 land correctly.

  • Loading branch information...
1 parent 5e23fcd commit fb15db442532dc461db34671042b5cfaef3c66bb @pmurias pmurias committed Jan 16, 2012
Showing with 39 additions and 2 deletions.
  1. +24 −2 lib/Perl5Interpreter.cs
  2. +4 −0 lib/p5embed.c
  3. +11 −0 t/p5/strings.t
View
@@ -32,7 +32,10 @@ public class Perl5Interpreter : IForeignInterpreter {
public static extern int SvPOKp(IntPtr sv);
[DllImport("obj/p5embed.so", EntryPoint="p5embed_newSVpvn")]
- public static extern IntPtr newSVpvn(string s,int length);
+ public static extern IntPtr newSVpvn(IntPtr s,int length);
+
+ [DllImport("obj/p5embed.so", EntryPoint="p5embed_SvUTF8_on")]
+ public static extern void SvUTF8_on(IntPtr sv);
[DllImport("obj/p5embed.so", EntryPoint="p5embed_subcall")]
public static extern IntPtr SubCall(
@@ -100,13 +103,32 @@ int argument_n
throw new NieczaException("Freezing perl5 SV* NYI.");
}
+
+ public static IntPtr MarshalString(string s) {
+ byte[] array = System.Text.Encoding.UTF8.GetBytes(s);
+ int size = Marshal.SizeOf(typeof(byte)) * (array.Length + 1);
+
+ IntPtr ptr = Marshal.AllocHGlobal(size);
+
+ /* This is a hack not to crash on mono!!! */
+ //allocated.Add(ptr, null);
+
+ Marshal.Copy(array, 0, ptr, array.Length);
+ Marshal.WriteByte(ptr, array.Length, 0);
+
+ IntPtr sv = Perl5Interpreter.newSVpvn(ptr,array.Length);
+ Perl5Interpreter.SvUTF8_on(sv);
+ return sv;
+ }
+
+
public static IntPtr VariableToSV(Variable var) {
P6any obj = var.Fetch();
if (obj is SVany) {
return ((SVany)obj).sv;
} else if (obj.Does(Kernel.StrMO)) {
string s = Kernel.UnboxAny<string>(obj);
- return Perl5Interpreter.newSVpvn(s,s.Length);
+ return MarshalString(s);
} else {
throw new NieczaException("can't convert argument to p5 type");
}
View
@@ -129,3 +129,7 @@ char* p5embed_SvPV_nolen(SV* sv) {
SV* p5embed_newSVpvn(char* str,int len) {
return newSVpvn(str,len);
}
+
+void p5embed_SvUTF8_on(SV* sv) {
+ SvUTF8_on(sv);
+}
View
@@ -1,5 +1,16 @@
use Test;
+
is(eval("'Yet Another Perl Hacker'",:lang<perl5>),"Yet Another Perl Hacker");
is(eval('"Yet Ano\0ther P\0erl Hacker"',:lang<perl5>),"Yet Ano\0ther P\0erl Hacker","Null Bytes in the middle of a converted string");
is(eval('"ąęóśćż"',:lang<perl5>),"ąęóśćż","utf8 in literals");
+
+
+my &test1 := eval('sub {$_[0] eq "Yet Another Perl Hacker"}',:lang<perl5>);
+
+my &test2 := eval('sub {$_[0] eq "Yet Ano\0ther P\0erl Hacker"}',:lang<perl5>);
+my &test3 := eval('sub {$_[0] eq "\x{105}\x{119}\x{f3}\x{15b}\x{107}\x{17c}"}',:lang<perl5>);
+
+ok(test1("Yet Another Perl Hacker"),"Passing simple strings to p5 land");
+ok(test2("Yet Ano\0ther P\0erl Hacker"),"Passing strings with null bytes to p5 land");
+ok(test3("ąęóśćż"),"Passing strings with unicode to p5 land");
done;

0 comments on commit fb15db4

Please sign in to comment.