madb icon indicating copy to clipboard operation
madb copied to clipboard

AdbHelper.GetDevices fails if device name contains a white space

Open camalot opened this issue 8 years ago • 2 comments

Original Bug on CodePlex

The Visual Studio emulator registers as a device with a space in its device name; the following data is passed to CreateDeviceFromAdbData:

169.254.138.177:5555   device product:VS Emulator Android Device - 480 x 800 model:Android_Device___480_x_800 device:donatello

The current regex doesn't allow white space and throws an ArgumentException with message Invalid device list data.

The fix appears to be to update the RE_DEVICELIST_INFO to allow for whitespaces but not for the colon : in the product name section of the device list.

    private const String RE_DEVICELIST_INFO = @"^([a-z0-9_-]+(?:\s?[\.a-z0-9_-]+)?(?:\:\d{1,})?)\s+(device|offline|unknown|bootloader|recovery|download)(?:\s+product:([^:]+)\s+model\:([\S]+)\s+device\:([\S]+))?$";

camalot avatar May 19 '16 13:05 camalot

private const String RE_DEVICELIST_INFO = @"^([a-z0-9_-]+(?:\s?[\.a-z0-9_-]+)?(?:\:\d{1,})?)\s+(device|offline|unknown|bootloader|recovery|download)(?:\s+product:([^:]+)\s+model\:([^:]+)\s+device\:([^:]+))?$";

I will be updating the code to be the above. This way each value will be under the same restriction. This will work until someone decides they want a product name with a colon in it.

camalot avatar May 19 '16 13:05 camalot

System would be more stable spliting the regex into sections like the following. This ensures as long as the serial number and state are present the object can be created. Adb allows the product / model / device fields to be present or not so this handles those cases. The only thing need is to update missing info on a state change if it becomes available.

        /// <summary>
        /// Regex to match the device serial and state
        /// </summary>
        private const String SerialAndStateRegex = @"^([a-z0-9_-]+(?:\s?[\.a-z0-9_-]+)?(?:\:\d{1,})?)\s+(\w+)";

        /// <summary>
        /// regex to match device info sections.
        /// </summary>
        private const String DeviceDataRegex = @"(\S+):([^:]+)($|\s)";
        /// <summary>
        /// Create a device from Adb Device list data
        /// </summary>
        /// <param name="data">the line data for the device</param>
        /// <returns></returns>
        public static Device CreateFromAdbData(String data)
        {
            Regex re = new Regex(SerialAndStateRegex, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            Match m = re.Match(data);
            string serial = null;
            string state = null;
            if (m.Success)
            {
                serial = m.Groups[1].Value.Trim();
                state = m.Groups[2].Value;

                Regex re2 = new Regex(DeviceDataRegex, RegexOptions.Compiled | RegexOptions.IgnoreCase);
                Match m2 = re2.Match(data);

                Dictionary<string, string> dataMap = new Dictionary<string, string>();
                while (m2.Success)
                {
                    dataMap.Add(m2.Groups[1].Value.Trim(), m2.Groups[2].Value);
                    m2 = m2.NextMatch();
                }

                string product = dataMap.ContainsKey("product") ? dataMap["product"] : "Unknown";
                string model = dataMap.ContainsKey("model") ? dataMap["model"] : "Unknown";
                string device = dataMap.ContainsKey("device") ? dataMap["device"] : "Unknown";
                return new Device(serial, GetStateFromString(state), model, product, device);
            }
            else
            {
                throw new ArgumentException("Invalid device list data");
            }
    }

camalot avatar May 19 '16 13:05 camalot