@@ -208,6 +208,8 @@ func Play(ctx context.Context, holeID, langID, code string) (score Scorecard) {
208208 case "python" :
209209 // Force the stdout and stderr streams to be unbuffered.
210210 cmd .Args = []string {"/usr/bin/python" , "-u" , "-" }
211+ case "sed" :
212+ cmd .Args = []string {"/usr/bin/sed" , "-E" , "-z" , "--" , code }
211213 case "swift" :
212214 cmd .Args = []string {"/usr/bin/swift" , "-module-cache-path" , "/tmp" , "-" }
213215 default :
@@ -222,13 +224,17 @@ func Play(ctx context.Context, holeID, langID, code string) (score Scorecard) {
222224 args += arg + "\x00 "
223225 }
224226 cmd .Stdin = strings .NewReader (args )
227+ case "sed" :
228+ // For sed we always need to append a null byte, even if no args exist
229+ args := strings .Join (score .Args , "\x00 " ) + "\x00 "
230+ cmd .Stdin = strings .NewReader (args )
225231 default :
226232 cmd .Args = append (cmd .Args , score .Args ... )
227233 }
228234
229235 // Code
230236 switch langID {
231- case "brainfuck" , "fish" , "javascript" :
237+ case "brainfuck" , "fish" , "javascript" , "sed" :
232238 // For these code is passed as an argument above.
233239 case "k" :
234240 code = preprocessKCode (holeID , code )
@@ -277,7 +283,14 @@ func Play(ctx context.Context, holeID, langID, code string) (score Scorecard) {
277283 } else {
278284 // Trim trailing spaces per line.
279285 // FIXME This is all very hacky, but needed for Sierpiński.
280- scanner := bufio .NewScanner (bytes .NewReader (stdout .Next (maxLength )))
286+ stdoutContents := stdout .Next (maxLength )
287+
288+ // Postprocess sed output to turn null bytes into newlines
289+ if langID == "sed" {
290+ stdoutContents = bytes .ReplaceAll (stdoutContents , []byte ("\x00 " ), []byte ("\n " ))
291+ }
292+
293+ scanner := bufio .NewScanner (bytes .NewReader (stdoutContents ))
281294 for scanner .Scan () {
282295 score .Stdout = append (
283296 score .Stdout , bytes .TrimRightFunc (scanner .Bytes (), unicode .IsSpace )... )
0 commit comments