Skip to content

fix(netlink): guard string.decode() against AttributeError in NLA array mode - #1481

Open
PhinehasNarh wants to merge 2 commits into
svinota:masterfrom
PhinehasNarh:fix/string-nla-array-decode
Open

fix(netlink): guard string.decode() against AttributeError in NLA array mode#1481
PhinehasNarh wants to merge 2 commits into
svinota:masterfrom
PhinehasNarh:fix/string-nla-array-decode

Conversation

@PhinehasNarh

Copy link
Copy Markdown

Problem

When an NLA attribute is declared as *string (an array of strings, e.g. NL80211_ATTR_SCAN_SSIDS), the base class nla_base.decode() sets self.value to a list of child cell objects rather than raw bytes. nlmsg_atoms.string.decode() then unconditionally called:

self.value = self.value.decode('utf-8')

on that list, raising:

AttributeError: 'list' object has no attribute 'decode'

This produced a WARNING traceback logged on every NL80211_CMD_TRIGGER_SCAN event when debug logging was enabled. The attribute value was still parsed correctly after the first failed call (because cell.decoded was already set to True by the base class), so the error was non-fatal but noisy.

Repro from #1330:

import logging
import pyroute2

logging.basicConfig(level=logging.DEBUG)
nl80211 = pyroute2.netlink.nl80211.NL80211()
nl80211.bind()
nl80211.add_membership("scan")
for event in nl80211.get():
    print(event)

Triggers:

WARNING:pyroute2.netlink:decoding NL80211_ATTR_SCAN_SSIDS
WARNING:pyroute2.netlink:AttributeError: 'list' object has no attribute 'decode'

Fix

One-line guard: only call .decode('utf-8') when self.value is actually bytes. When _nla_array=True, the value is already a list of child cells and should be left as-is.

if isinstance(self.value, bytes):
    try:
        self.value = self.value.decode('utf-8')
    except UnicodeDecodeError:
        pass

Tests

Three unit tests added to tests/test_unit/test_nlmsg/test_string_nla_array.py:

  • test_string_nla_array_decode_no_attributeerror: verifies decode does not raise
  • test_string_nla_array_value_is_list: verifies the decoded value is a list
  • test_string_nla_plain_decode_still_returns_str: verifies plain (non-array) string decode is unchanged

Run with:

make test session=unit

The tests pass on Linux. They cannot run on Windows due to fcntl being imported transitively through pyroute2/__init__.py, which is consistent with the rest of the test_unit suite.

Closes #1330.

When an NLA attribute is declared as *string (an array of strings), the
base class decode() path sets self.value to a list of child cell objects
rather than raw bytes. nlmsg_atoms.string.decode() then called

    self.value = self.value.decode('utf-8')

on that list, raising:

    AttributeError: 'list' object has no attribute 'decode'

This produced a WARNING traceback on every NL80211_CMD_TRIGGER_SCAN
event when debug logging was enabled (NL80211_ATTR_SCAN_SSIDS is
declared as *string and is present in every scan trigger message).

The fix wraps the utf-8 decode in an isinstance(self.value, bytes) guard
so it only fires when the value is raw bytes, leaving list values (from
the NLA array decode path) untouched.

Closes svinota#1330.
@svinota

svinota commented Jun 29, 2026

Copy link
Copy Markdown
Owner

Thanks, checking!

flake8 flagged two issues in the test file:
- F401: 'pytest' was imported but not used directly (fixtures are
  auto-discovered, no explicit import needed)
- E501: docstring on line 50 was 80 characters, one over the 79-char limit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AttributeError: 'list' object has no attribute 'decode' when decoding "NL80211_ATTR_SCAN_SSIDS"

2 participants