rliou92 / python-umonitor

Manage monitor configuration automatically.
MIT License
39 stars 6 forks source link

Fix usage of '0' instead of '\x00' #7

Closed FortStatement closed 3 years ago

FortStatement commented 3 years ago

Hey! One of my monitors had a problem where the name wasn't identified correctly. After a quick debug session, it seems b'0' was used to terminate display names instead of b'\x00'. strlen is used immediately afterwards, so whenever it worked so far it was because luckily a \x00 byte was at the right place at the right time.

rliou92 commented 3 years ago

Thanks for taking the time to debug the code. Great find!

joaotavora commented 3 years ago

@GPery was the "problem" you had similar to this one?

❯ umonitor -l docked-with-the-big-one
Traceback (most recent call last):
  File "/usr/bin/umonitor", line 33, in <module>
    sys.exit(load_entry_point('umonitor==20181018', 'console_scripts', 'umonitor')())
  File "/usr/lib/python3.9/site-packages/umonitor-20181018-py3.9-linux-x86_64.egg/umonitor/__init__.py", line 23, in main
    umon.run()
  File "/usr/lib/python3.9/site-packages/umonitor-20181018-py3.9-linux-x86_64.egg/umonitor/umonitor.py", line 36, in run
    self.load_profile()
  File "/usr/lib/python3.9/site-packages/umonitor-20181018-py3.9-linux-x86_64.egg/umonitor/umonitor.py", line 112, in load_profile
    self.setup_info = self.get_setup_info()
  File "umonitor/screen.pyx", line 417, in screen.Screen.get_setup_info
  File "umonitor/screen.pyx", line 106, in screen.Screen._get_output_info
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8d in position 4: invalid start byte

?

FortStatement commented 3 years ago

This is very likely the same bug, yes (I believe you'll notice the byte that can't be decoded is different each run) But it won't be fixed until issue #8 is addressed.

joaotavora commented 3 years ago

Right, regenerate the .c file from the pyx file. Any hints on how I can do that manually?

joaotavora commented 3 years ago

This is very likely the same bug, yes (I believe you'll notice the byte that can't be decoded is different each run)

Indeed it is, and now I understand your fix. Also, it seems to sometimes work if it happens to find a \0 there, I guess

joaotavora commented 3 years ago

This is very likely the same bug, yes (I believe you'll notice the byte that can't be decoded is different each run)

Indeed it is, and now I understand your fix. Also, it seems to sometimes work if it happens to find a \0 there, I guess. I ended up fixing it directly in the horribly long .c file. Since your fix was so simple, it wasn't that hard. Here's the diff:

diff --git a/umonitor/screen.c b/umonitor/screen.c
index ea9f9eb..03ca333 100644
--- a/umonitor/screen.c
+++ b/umonitor/screen.c
@@ -3700,7 +3700,7 @@ static char *__pyx_f_6screen_6Screen__get_output_name(CYTHON_UNUSED struct __pyx
  *             return output_name
  */
   __pyx_t_5 = __Pyx_PyIndex_AsSsize_t(__pyx_v_output_name_length); if (unlikely((__pyx_t_5 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 194, __pyx_L1_error)
-  (__pyx_v_output_name[__pyx_t_5]) = '0';
+  (__pyx_v_output_name[__pyx_t_5]) = 0;

   /* "screen.pyx":195
  *
@@ -4013,7 +4013,7 @@ static char *__pyx_f_6screen_6Screen__get_edid_name(struct __pyx_obj_6screen_Scr
  *
  *             # product = (edid[11] << 8) | edid[10];
  */
-  (__pyx_v_vendor[3]) = '0';
+  (__pyx_v_vendor[3]) = 0;

   /* "screen.pyx":240
  *             # snprintf(edid_info, length, "%04X%04X%08X", vendor, product, serial);