0

I am trying to send some data via SMS with a .net core 2.2 app, running on a Linux system. To do this I am using Gammu, an external program that I can call and supply with my text data in an escaped string.

I believe that I have used the correct quotations, formatted correctly and used in the correct places; however, I am seeing the following error output:

/bin/bash: -c: line 0: unexpected EOF while looking for matching `"'
/bin/bash: -c: line 1: syntax error: unexpected end of file

I have isolated the strings that I have been using and these errors appear to be being caused by only a specific string that I suspect may be improperly terminated somehow. Since, apparently, c# doesn't use null terminating characters, their presence (or absence) shouldn't really matter, yet removing (or keeping) them seems to still cause an issue.

The following is an example to illustrate the issue;

Here's the code that triggers the issue.

        string smsMessageString = "gammu sendsms TEXT ++4478901234 -text ";
        string a1 = "08REEEKP010EEE";
        string a2 = testStructure.serial;

        //simply proves that a1 and a2 are the "same"
        if (a1.Equals(a2))
        {
            Console.WriteLine(a1 + " is " + a2);
        }

        //This constructs two strings that should look identical
        string smsMessageString2 = smsMessageString + "\"" + a1 + "\"";
        string smsMessageString3 = smsMessageString + "\"" + a2 + "\"";

        //Both strings should then be executed and two SMSs sent
        Console.WriteLine(smsMessageString2);
        var output = smsMessageString2.Bash();
        Console.WriteLine(smsMessageString3);
        output = smsMessageString3.Bash();

Here's the helper function I'm using to run a command with bash.

public static class ShellHelper
{
    public static string Bash(this string cmd)
    {
        var escapedArgs = cmd.Replace("\"", "\\\"");

        var process = new Process()
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "/bin/bash",
                Arguments = $"-c \"{escapedArgs}\"",
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true,
            }
        };
        process.Start();
        string result = process.StandardOutput.ReadToEnd();
        process.WaitForExit();
        return result;
    }
}

The code above produces the following output:

08REEEKP010EEE is 08REEEKP010EEE
gammu sendsms TEXT ++4478901234 -text "08REEEKP010EEE"
If you want break, press Ctrl+C...

gammu sendsms TEXT ++4478901234 -text "08REEEKP010EEE"
/bin/bash: -c: line 0: unexpected EOF while looking for matching `"'
/bin/bash: -c: line 1: syntax error: unexpected end of file

One successfully sends, the other throws an error. Literally the only difference is the string of text, but I can't see where the issue is.

I believe a1 and a2 "should" be exactly the same, as a2 is a copy of what I observed a1 was populated with, both share the same length and .equals appears to return "true". So it appears as though two strings match, yet they cause different behaviour so they clearly can't be the same.

The code for populating my structure is as follows:

//The string's origin is a series of bytes, which is often padded by zeros.
//[0x30, 0x38, 0x52, 0x45, 0x45, 0x45, 0x4b, 0x50, 0x30, 0x31, 0x30, 0x45, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00]            

tempArray = new byte[18]; //This is the maximum that this value could be
Array.Copy(myBytesAbove, indexToStartFrom, tempArray, 0, 18); //It could start from a different place in the packet
serial = System.Text.Encoding.UTF8.GetString(tempArray); //Get a string from these bytes

//The following code was added to strip out all of the \0 characters  

 int index = serial.IndexOf("\0"); //There could be other crud copied after a \0
   if (index > 0)
   {
     serial = serial.Substring(0, index); // Take the first string before the first \0
     //serial = serial.Substring(0, index+1); //Same result, even if I just leave one of the \0 characters, which shouldn't be necessary..
    }

I've also tried creating two char[] arrays to store both strings with a .ToCharArray() - and these are identical, too. I've tried .Trim(), .ToString() with no luck. I'm just incredibly lost as to what the issue could be, given that I have included enough quotes - and in the right places.

It feels as though my "serial" string just isn't terminated properly - but how can I verify and/or correct that?

Trevelyan
  • 87
  • 10
  • Did you tried using UseShellExecute = true? – pim3nt3l Aug 14 '19 at 13:25
  • Yes, this produced "Unhandled Exception: System.InvalidOperationException: The Process object must have the UseShellExecute property set to false in order to redirect IO streams.". I'd be happy if something like this would fix the issue, but I am more concerned that I can't observe, or test, for the difference between two seemingly identical strings (where one does, and one doesn't, work) – Trevelyan Aug 14 '19 at 13:33
  • Very interesting issue. I can only assume something goes wrong when you try to replace \" to \\\" - try to Console.WriteLine(escapedArgs); right after you replaced it, or alternatively check bash commands that had been run (it probably ran something like `gammu sendsms TEXT ++4478901234 -text "08REEEKP010EEE""`) – Vytautas Plečkaitis Aug 15 '19 at 10:13
  • So the WriteLine showed the \".. but that is the case in both cases. Sigh. – Trevelyan Aug 15 '19 at 12:18

1 Answers1

0

Right, fixed it. Turns out that I need to replace this code:

int index = serial.IndexOf("\0");
if (index > 0)
   {
     serial = serial.Substring(0, index); 
    }

With code from this answer, if you want to trim all the \0s

cmd = cmd.TrimEnd('\0');

...or this code if you want to just stop after the first \0..

int index = cmd.IndexOf('\0');

if (index >= 0)

cmd = cmd.Remove(index);

Hope that helps anyone else who er, comes across this weirdness!

Trevelyan
  • 87
  • 10