Skip to content
Snippets Groups Projects
  1. Oct 19, 2017
  2. Oct 07, 2017
    • Aleksander Morgado's avatar
      base-modem: plug memleaks when building port lists · e8ce6a04
      Aleksander Morgado authored
      The mm_base_modem_find_ports() method builds a list of full
      references, so we need to unref them in the peek() methods.
      
          ==10047== 14,959 (24 direct, 14,935 indirect) bytes in 1 blocks are definitely lost in loss record 5,470 of 5,473
          ==10047==    at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
          ==10047==    by 0x66E3028: g_malloc (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==10047==    by 0x66FAB25: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==10047==    by 0x66D9A33: g_list_append (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==10047==    by 0x15F6A7: mm_base_modem_find_ports (mm-base-modem.c:845)
          ==10047==    by 0x15E9F3: mm_base_modem_peek_port_qmi_for_data (mm-base-modem.c:579)
          ==10047==    by 0x15E8FC: mm_base_modem_get_port_qmi_for_data (mm-base-modem.c:555)
          ==10047==    by 0x1BB99F: _connect (mm-bearer-qmi.c:1391)
          ==10047==    by 0x1540B4: mm_base_bearer_connect (mm-base-bearer.c:841)
          ==10047==    by 0x181F4F: connection_step (mm-iface-modem-simple.c:597)
          ==10047==    by 0x181321: create_bearer_ready (mm-iface-modem-simple.c:258)
          ==10047==    by 0x612FD52: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
      
      (cherry picked from commit 58e6f652)
      e8ce6a04
  3. Oct 06, 2017
    • Aleksander Morgado's avatar
      port-qmi: don't allow client allocation if port is closed · f613103f
      Aleksander Morgado authored
      The internal QmiDevice will be gone when the port is closed, so we
      cannot really do anything.
      
      This avoid an issue happening when the modem goes away in the middle
      of the client allocation logic performed by MMBroadbandModemQmi:
      
          ModemManager[24820]: <debug> [1507279407.225777] Couldn't allocate client for service 'wms': Couldn't create client for service 'wms': CID allocation failed in the CTL client: Transaction timed out
          ModemManager[24820]: qmi_device_allocate_client: assertion 'QMI_IS_DEVICE (self)' failed
          ==24820==
          ==24820== Process terminating with default action of signal 5 (SIGTRAP): dumping core
          ==24820==    at 0x66E3411: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==24820==    by 0x66E46FA: g_logv (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==24820==    by 0x66E484E: g_log (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==24820==    by 0x538E259: qmi_device_allocate_client (qmi-device.c:1008)
          ==24820==    by 0x1F5690: mm_port_qmi_allocate_client (mm-port-qmi.c:157)
          ==24820==    by 0x1D20BA: allocate_next_client (mm-broadband-modem-qmi.c:11319)
          ==24820==    by 0x1D2027: qmi_port_allocate_client_ready (mm-broadband-modem-qmi.c:11306)
          ==24820==    by 0x612FD52: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
          ==24820==    by 0x6130775: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
          ==24820==    by 0x1F54E8: allocate_client_ready (mm-port-qmi.c:113)
          ==24820==    by 0x612FD52: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
          ==24820==    by 0x6130775: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
      
      (cherry picked from commit efaa780d)
      f613103f
  4. Oct 05, 2017
    • Aleksander Morgado's avatar
      plugin-manager: allow multiple calls to port_context_complete() · 631eadb6
      Aleksander Morgado authored
      Only the first one will work.
      
      (cherry picked from commit 2dc13fd9)
      631eadb6
    • Aleksander Morgado's avatar
      plugin-manager: ensure valid reference during cancellation · 3c3c9aa1
      Aleksander Morgado authored
      Cancelling the port_context->cancellable may end up finishing the
      async task and completing the last reference of the port
      context. Avoid that by making sure we hold a valid reference for as
      long as we may need it.
      
          ==2277== Invalid read of size 4
          ==2277==    at 0x14ACE2: port_context_cancel (mm-plugin-manager.c:547)
          ==2277==    by 0x14C32E: device_context_port_released (mm-plugin-manager.c:1142)
          ==2277==    by 0x83831C7: ffi_call_unix64 (in /usr/lib/libffi.so.6.0.4)
          ==2277==    by 0x8382C29: ffi_call (in /usr/lib/libffi.so.6.0.4)
          ==2277==    by 0x64506A8: g_cclosure_marshal_generic (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==2277==    by 0x644FEAC: g_closure_invoke (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==2277==    by 0x64624AD: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==2277==    by 0x646AC84: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==2277==    by 0x646B69E: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==2277==    by 0x1483E7: mm_device_release_port (mm-device.c:196)
          ==2277==    by 0x145D5D: device_removed (mm-base-manager.c:217)
          ==2277==    by 0x1464A9: handle_kernel_event (mm-base-manager.c:401)
          ==2277==  Address 0xf677d18 is 88 bytes inside a block of size 96 free'd
          ==2277==    at 0x4C2E14B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
          ==2277==    by 0x14A1B7: port_context_unref (mm-plugin-manager.c:234)
          ==2277==    by 0x14AB51: plugin_supports_port_ready (mm-plugin-manager.c:492)
          ==2277==    by 0x612FD52: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
          ==2277==    by 0x6130775: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
          ==2277==    by 0x1AFDF8: port_probe_run_ready (mm-plugin.c:624)
          ==2277==    by 0x612FD52: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
          ==2277==    by 0x6130775: ??? (in /usr/lib/libgio-2.0.so.0.5200.3)
          ==2277==    by 0x6131367: g_task_return_error_if_cancelled (in /usr/lib/libgio-2.0.so.0.5200.3)
          ==2277==    by 0x1A9EDA: port_probe_task_return_error_if_cancelled (mm-port-probe.c:109)
          ==2277==    by 0x1ABCD2: serial_probe_at_parse_response (mm-port-probe.c:900)
          ==2277==    by 0x611E475: g_simple_async_result_complete (in /usr/lib/libgio-2.0.so.0.5200.3)
          ==2277==  Block was alloc'd at
          ==2277==    at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
          ==2277==    by 0x66E3028: g_malloc (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==2277==    by 0x66FAB25: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==2277==    by 0x66FAFB8: g_slice_alloc0 (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==2277==    by 0x14B18D: port_context_new (mm-plugin-manager.c:649)
          ==2277==    by 0x14C4A7: device_context_port_grabbed (mm-plugin-manager.c:1182)
          ==2277==    by 0x83831C7: ffi_call_unix64 (in /usr/lib/libffi.so.6.0.4)
          ==2277==    by 0x8382C29: ffi_call (in /usr/lib/libffi.so.6.0.4)
          ==2277==    by 0x64506A8: g_cclosure_marshal_generic (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==2277==    by 0x644FEAC: g_closure_invoke (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==2277==    by 0x64624AD: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==2277==    by 0x646AC84: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
      
      (cherry picked from commit bbe50645)
      3c3c9aa1
    • Aleksander Morgado's avatar
      port-serial: avoid invalid memory write on cancellation logic · 574ba880
      Aleksander Morgado authored
      If the GCancellable is already cancelled when trying to connect a
      signal, the callback given will be run right away, and that may end up
      completing the async task and removing the last MMPortSerial
      reference.
      
          ==30627== Invalid write of size 8
          ==30627==    at 0x1ED43B: port_serial_queue_process (mm-port-serial.c:812)
          ==30627==    by 0x66DE342: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x66DD8C4: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x66DDC87: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x66DDFA1: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x143F9B: main (main.c:180)
          ==30627==  Address 0xf6f0e98 is 200 bytes inside a block of size 328 free'd
          ==30627==    at 0x4C2E14B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
          ==30627==    by 0x64742B2: g_type_free_instance (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==30627==    by 0x1ED0F2: port_serial_got_response (mm-port-serial.c:704)
          ==30627==    by 0x1ED21B: port_serial_response_wait_cancelled (mm-port-serial.c:757)
          ==30627==    by 0x60E1A81: g_cancellable_connect (in /usr/lib/libgio-2.0.so.0.5200.3)
          ==30627==    by 0x1ED43A: port_serial_queue_process (mm-port-serial.c:812)
          ==30627==    by 0x66DE342: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x66DD8C4: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x66DDC87: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x66DDFA1: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x143F9B: main (main.c:180)
          ==30627==  Block was alloc'd at
          ==30627==    at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
          ==30627==    by 0x66E3028: g_malloc (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x66FAB25: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x66FAFB8: g_slice_alloc0 (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x6473FB5: g_type_create_instance (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==30627==    by 0x6455027: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==30627==    by 0x6456DBC: g_object_new_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==30627==    by 0x6457200: g_object_new (in /usr/lib/libgobject-2.0.so.0.5200.3)
          ==30627==    by 0x1F253A: mm_port_serial_at_new (mm-port-serial-at.c:533)
          ==30627==    by 0x1AC7E7: serial_open_at (mm-port-probe.c:1210)
          ==30627==    by 0x66DD8C4: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.5200.3)
          ==30627==    by 0x66DDC87: ??? (in /usr/lib/libglib-2.0.so.0.5200.3)
      
      (cherry picked from commit 48850f21)
      574ba880
    • Aleksander Morgado's avatar
      bearer-qmi: fix build with libqmi 1.16 · ffdf20e7
      Aleksander Morgado authored
      The cleanup_event_report_unsolicited_events() method is only defined
      when using libqmi >= 1.18.0.
      
          CC       ModemManager-mm-bearer-qmi.o
         <mm-1-6-with-qmi-1.16-mbim-1.14/ws/source/src/mm-bearer-qmi.c>: In function ‘reset_bearer_connection’:
         <mm-1-6-with-qmi-1.16-mbim-1.14/ws/source/src/mm-bearer-qmi.c>:1589:17: error: implicit declaration of function ‘cleanup_event_report_unsolicited_events’ [-Werror=implicit-function-declaration]
                          cleanup_event_report_unsolicited_events (self,
                          ^
         cc1: all warnings being treated as errors
         Makefile:1489: recipe for target 'ModemManager-mm-bearer-qmi.o' failed
      
      Fixes: 068c7df4
      ffdf20e7
    • Aleksander Morgado's avatar
      port-probe: avoid deadlock trying to disconnect cancellable · 966fc68a
      Aleksander Morgado authored
      We cannot in any way try to disconnect a GCancellable from within a
      cancellation handler, or we'll deadlock.
      
          Thread 1 (Thread 0x7fe98bf25700 (LWP 12079)):
          #0  0x00007fe98a355f36 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
          #1  0x00007fe98a7f5ac0 in g_cond_wait () from /usr/lib/libglib-2.0.so.0
          #2  0x00007fe98ad14650 in g_cancellable_disconnect () from /usr/lib/libgio-2.0.so.0
          #3  0x000000000045be5d in port_probe_run_context_free ()
          #4  0x00007fe98ad519ed in g_task_finalize () from /usr/lib/libgio-2.0.so.0
          #5  0x00007fe98aaaa7b3 in g_object_unref () from /usr/lib/libgobject-2.0.so.0
          #6  0x000000000045b5f8 in port_probe_task_return_error_if_cancelled ()
          #7  0x000000000045c57d in serial_probe_at_parse_response ()
          #8  0x00007fe98ad42ed2 in g_simple_async_result_complete () from /usr/lib/libgio-2.0.so.0
          #9  0x0000000000485c7d in serial_command_ready ()
          #10 0x00007fe98ad42ed2 in g_simple_async_result_complete () from /usr/lib/libgio-2.0.so.0
          #11 0x0000000000482345 in command_context_complete_and_free ()
          #12 0x0000000000482fa5 in port_serial_got_response ()
          #13 0x00000000004830f5 in port_serial_response_wait_cancelled ()
          #14 0x00007fe98aaa70c5 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
          #15 0x00007fe98aab47ce in signal_emit_unlocked_R () from /usr/lib/libgobject-2.0.so.0
          #16 0x00007fe98aabb595 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
          #17 0x00007fe98aabb662 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
          #18 0x00007fe98ad144c5 in g_cancellable_cancel () from /usr/lib/libgio-2.0.so.0
          #19 0x00007fe98aaa70c5 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
          #20 0x00007fe98aab47ce in signal_emit_unlocked_R () from /usr/lib/libgobject-2.0.so.0
          #21 0x00007fe98aabb595 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
          #22 0x00007fe98aabb662 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
          #23 0x00007fe98ad144c5 in g_cancellable_cancel () from /usr/lib/libgio-2.0.so.0
          #24 0x000000000042e9f6 in port_context_cancel ()
          #25 0x00007fe989b99a4c in ffi_call_unix64 () at ../src/x86/unix64.S:75
          #26 0x00007fe989b994b9 in ffi_call (cif=0x7fffc41dcdb0, fn=0x42ea40 <device_context_port_released>, rvalue=<optimized out>, avalue=0x7fffc41dccd0) at ../src/x86/ffi64.c:492
          #27 0x00007fe98aaa7700 in g_cclosure_marshal_generic () from /usr/lib/libgobject-2.0.so.0
          #28 0x00007fe98aaa70c5 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
          #29 0x00007fe98aab47ce in signal_emit_unlocked_R () from /usr/lib/libgobject-2.0.so.0
          #30 0x00007fe98aabb595 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
          #31 0x00007fe98aabb662 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
          #32 0x000000000042c8f0 in mm_device_release_port ()
          #33 0x000000000042a6cb in device_removed ()
          #34 0x000000000042af94 in handle_kernel_event ()
          #35 0x000000000042b356 in report_kernel_event_auth_ready ()
          #36 0x00007fe98ad51783 in g_task_return_now () from /usr/lib/libgio-2.0.so.0
          #37 0x00007fe98ad517b9 in complete_in_idle_cb () from /usr/lib/libgio-2.0.so.0
          #38 0x00007fe98a7bda5e in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
          #39 0x00007fe98a7bddb8 in g_main_context_iterate.isra () from /usr/lib/libglib-2.0.so.0
          #40 0x00007fe98a7be042 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
          #41 0x0000000000428dc4 in main ()
      
      So, just clear the cancellation id before going on with the handler logic.
      
      (cherry picked from commit 71730509)
      966fc68a
  5. Oct 02, 2017
    • Dan Williams's avatar
      bearer-mbim: don't crash when modem doesn't send gateways · 8c521885
      Dan Williams authored
      When the Ericsson F5321 with firmware R3C11/R4D04 is told to make
      an IPv6-only connection, it reports that it has IPv4 configuration
      but then returns no actual addresses.  Check both the flags and
      actual data before trying to use them.
      
      ModemManager[25850]: <debug> [1506958721.914717] IPv4 configuration available: 'address, gateway, dns, mtu'
      ModemManager[25850]: <debug> [1506958721.914731]   IP addresses (0)
      ModemManager[25850]: <debug> [1506958721.914741]   DNS addresses (0)
      ModemManager[25850]: <debug> [1506958721.914748]   MTU: '0'
      ModemManager[25850]: <debug> [1506958721.914758] IPv6 configuration available: 'address, dns, mtu'
      ModemManager[25850]: <debug> [1506958721.914767]   IP addresses (1)
      ModemManager[25850]: <debug> [1506958721.914852]     IP [0]: 'fe80::39:f622:7d01/64'
      ModemManager[25850]: <debug> [1506958721.914866]   DNS addresses (2)
      ModemManager[25850]: <debug> [1506958721.914883]     DNS [0]: 'fd00:976a::9'
      ModemManager[25850]: <debug> [1506958721.914896]   MTU: '1500'
      ModemManager[25850]: <debug> [1506958721.914947] (wwp0s20u1i6): port now connected
      
      (cherry picked from commit 3e15dc15)
      8c521885
  6. Sep 26, 2017
    • Aleksander Morgado's avatar
      huawei: plug memleak when listing cdc-wdm AT ports · ee1e9afb
      Aleksander Morgado authored
      The returned list contains full references, so make sure we unref them
      before going on. Note that it's ok to return a pointer to one object
      inside this list even if we're unref-ing them all, because we're sure
      that the caller knows it's peek-ing a port object.
      
      (cherry picked from commit 4c36bd42)
      ee1e9afb
    • Aleksander Morgado's avatar
      broadband-bearer: fix object types in connect_3gpp() steps · 544f9c3f
      Aleksander Morgado authored
      Some of the steps in the connect_3gpp() sequence are implemented as
      methods in the MMBroadbandBearer class, and therefore the objects
      received in the corresponding ready() methods are all bearers, not
      modems.
      
      This issue wasn't found before because the objects received were not
      really being used after all, as we were relying on the ones kept in
      the context.
      
      (cherry picked from commit 1e318bec)
      544f9c3f
  7. Sep 16, 2017
    • Aleksander Morgado's avatar
      bearer-qmi: cleanup indication handlers on network-initiated disconnects · 068c7df4
      Aleksander Morgado authored
      Otherwise, they'll end up queueing up and each time we get a new
      indication the signal will get called multiple times:
      
          [/dev/cdc-wdm0] received message...
          <<<<<< RAW:
          <<<<<<   length = 20
          <<<<<<   data   = 01:13:00:80:01:09:04:00:00:01:00:07:00:20:04:00:05:00:00:00
          [/dev/cdc-wdm0] received generic indication (translated)...
          <<<<<< QMUX:
          <<<<<<   length  = 19
          <<<<<<   flags   = 0x80
          <<<<<<   service = "wds"
          <<<<<<   client  = 9
          <<<<<< QMI:
          <<<<<<   flags       = "indication"
          <<<<<<   transaction = 0
          <<<<<<   tlv_length  = 7
          <<<<<<   message     = "Event Report" (0x0001)
          <<<<<< TLV:
          <<<<<<   type       = "Preferred Data System" (0x20)
          <<<<<<   length     = 4
          <<<<<<   value      = 05:00:00:00
          <<<<<<   translated = lte
          <debug> [1504578559.592891] Got QMI WDS event report
          <debug> [1504578559.598212] Got QMI WDS event report
          <debug> [1504578559.601694] Got QMI WDS event report
      
      (cherry picked from commit 2ed97061)
      068c7df4
  8. Sep 15, 2017
  9. Sep 13, 2017
  10. Sep 10, 2017
  11. Sep 05, 2017
  12. Aug 29, 2017
  13. Aug 22, 2017
  14. Aug 12, 2017
  15. Aug 11, 2017
  16. Aug 10, 2017
    • Aleksander Morgado's avatar
      udev: remove default ID_MM_PLATFORM_DRIVER_PROBE whitelist · c96c3b11
      Aleksander Morgado authored
      The whitelist made all platform TTYs managed by the 'atmel_usart'
      kernel driver probed by ModemManager, which isn't something we want,
      as most of these aren't broadband modems.
      
      We leave the logic supporting the ID_MM_PLATFORM_DRIVER_PROBE udev tag
      as there may be a case where the user does need ModemManager to probe
      a given platform TTY.
      
      (cherry picked from commit e6f245c6)
      c96c3b11
  17. Aug 08, 2017
  18. Aug 04, 2017
  19. Aug 03, 2017
    • Ben Chan's avatar
      sms-part-cdma: add missing break statements in cause_code_to_delivery_state · 81c94157
      Ben Chan authored and Aleksander Morgado's avatar Aleksander Morgado committed
      This patch fixes cause_code_to_delivery_state() by adding two missing
      break statements for the case ERROR_CLASS_TEMPORARY and
      ERROR_CLASS_PERMANENT in the `switch (error_class)` statement. Without
      the break statements, the switch always falls through to the default and
      returns MM_SMS_DELIVERY_STATE_UNKNOWN for an `error_class' of value
      ERROR_CLASS_TEMPORARY or ERROR_CLASS_PERMANENT.
      
      (cherry picked from commit 0bb01ab6)
      81c94157
    • Ben Chan's avatar
      libmm-glib,firmware: fix unique_id checks · 94a950dd
      Ben Chan authored and Aleksander Morgado's avatar Aleksander Morgado committed
      The following checks in mm_modem_firmware_select() and
      mm_modem_firmware_select_sync() could result in a NULL pointer
      dereference if `unique_id' is NULL:
      
        g_return_if_fail (unique_id != NULL || unique_id[0] == '\0')
        g_return_val_if_fail (unique_id != NULL || unique_id[0] == '\0', FALSE)
      
      This patch fixes the checks to properly verify that `unique_id' is
      neither NULL nor an empty string.
      
      (cherry picked from commit bae45907)
      94a950dd
  20. Jul 31, 2017
  21. Jul 27, 2017
  22. Jul 19, 2017
Loading