On 12/19/2011 04:41 PM, maarten wrote:

and added it to String.st in the kernel folder.
Now withing every call of system in the VFS library I've added  (string)
escape. This way anyone could escape any string in any situation and it
also works for this particular problem.

Your code is a bit inefficient. Never use the comma message. Always use streams instead.

Also, a partial fix (not escaping everything) is as ineffective as no fix.

I attach a patch that does this more efficiently and adds #system:withArguments:. Can you fix VFS using this new method?

Paolo
diff --git a/kernel/CFuncs.st b/kernel/CFuncs.st
index f9ca606..dc4da1a 100644
--- a/kernel/CFuncs.st
+++ b/kernel/CFuncs.st
@@ -115,6 +115,12 @@ to perform the actual call-out to C routines.'>
 
 SystemDictionary extend [
 
+    system: aString withArguments: args [
+	<category: 'c call-outs'>
+	^self system: aString % (args collect: [ :string | string withShellEscapes ])
+	
+    ]
+
     system: aString [
 	<category: 'c call-outs'>
 	<cCall: 'system' returning: #int args: #(#string)>
diff --git a/kernel/CharArray.st b/kernel/CharArray.st
index c0545ad..4e6276a 100644
--- a/kernel/CharArray.st
+++ b/kernel/CharArray.st
@@ -446,6 +446,85 @@ accessing and manipulation methods for strings.'>
 	^result contents
     ]
 
+    withShellEscapes [
+	"Answer the receiver with special shell characters converted to a
+         backslash sequence."
+
+	<category: 'string processing'>
+        ^Directory pathSeparator == $\ 
+            ifTrue: [ self withWindowsShellEscapes ]
+            ifFalse: [ self withUnixShellEscapes ]
+    ]
+
+    withWindowsShellEscapes [
+	"Answer the receiver with Windows shell characters escaped properly."
+
+	| num result table slashes |
+        table := ##(
+            | t |
+            t := ByteArray new: 256.
+            #($% $" $< $> $| $& $^ $ ) do: [ :each | t at: each codePoint put: 1 ].
+            t).
+
+        num := 0.
+        1 to: self size do: [ :i |
+            num := num + (table at: (self valueAt: i) ifAbsent: [0])].
+
+        num = 0 ifTrue: [^self].
+        result := self copyEmpty writeStream.
+        result nextPut: $".
+        slashes := 0.
+        self do: [:each|
+            (each = $" or: [each = $%])
+                ifFalse: [
+                    "Backslash is not special per se, but must be treated
+                     specially inside quotes."
+                    slashes := each = $\ ifTrue: [slashes+1] ifFalse: [0].
+                    result nextPut: each]
+                ifTrue: [
+                    slashes > 0 ifTrue: [result next: slashes put: $\].
+                    slashes := 0.
+                    result nextPut: $".
+                    each = $% ifTrue: [ result nextPut: $% ].
+                    result nextPut: $"]].
+        result next: slashes put: $\.
+        result nextPut: $".
+
+	^result contents
+    ]
+
+    withUnixShellEscapes [
+	"Answer the receiver with special shell characters converted to a
+         backslash sequence."
+
+	| num result table i j ch |
+        table := ##(
+            | t |
+            t := ByteArray new: 256.
+            #($  $' $" $` $| $^ $> $[ $= $< $; $( $) $*
+              $& $$ $" $! $# $~ ${ $} $? $\) do: [ :each |
+                t at: each codePoint put: 1 ].
+            t).
+
+        num := 0.
+        1 to: self size do: [ :i |
+            num := num + (table at: (self valueAt: i) ifAbsent: [0])].
+
+        num = 0 ifTrue: [^self].
+        result := self copyEmpty: self size + num.
+        i := 1. j := 0.
+        [j < num] whileTrue: [
+            ch := self valueAt: i.
+            (table at: ch ifAbsent: [0]) = 0 ifFalse: [
+                result at: j + i put: $\.
+                j := j + 1].
+            result valueAt: j + i put: ch.
+            i := i + 1].
+
+        result replaceFrom: j+i to: self size + num with: self startingAt: i.
+	^result
+    ]
+
     asNumber [
 	"Parse a Number from the receiver until the input character is invalid
 	 and answer the result at this point"
_______________________________________________
help-smalltalk mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/help-smalltalk

Reply via email to