Skip to content

REXML::ParseException: Malformed XML — No root element when calling update on Group object #106

@hiboma

Description

@hiboma

Summary

When using ruby-jss with rexml 3.4.4 or 3.4.3, I encountered a REXML::ParseException when attempting to call save on a Group object.

The error message indicates that the XML being parsed is malformed due to the absence of a root element. This appears to be related to changes in how REXML validates XML documents.

Environment

  • Ruby version: 3.4.6
  • ruby-jss: 4.2.3
  • rexml versions tested:
    • 3.4.4 ❌ (fails)
    • 3.4.3 ❌ (fails)
    • 3.4.2 ✅ (works as expected)
  • OS: macOS

Expected Behavior

ComputerGroup#save should successfully update the group with added members.

Actual Behavior

The method call fails with a REXML::ParseException indicating "Malformed XML: No root element".

Steps to Reproduce

test.rb

#!/usr/bin/env ruby

require 'ruby-jss'

params = {
  host: 'server.example.com',
  client_id: ENV['CLIENT_ID'],
  client_secret: ENV['CLIENT_SECRET'],
}

Jamf.cnx.connect(**params)

id = 131 # example group ID

computer_group = Jamf::ComputerGroup.fetch(id)
computer_group.add_member `hostname`.strip
computer_group.save # 🔥 This line throws the exception

Gemfile

source 'https://rubygems.org'
gem 'ruby-jss'
gem 'rexml', '<version>' # Change version to test different behaviors

Error Stack Trace

/path/to/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb:271:in 'REXML::Parsers::BaseParser#pull_event': Malformed XML: No root element (REXML::ParseException)
Line: 1
Position: 54
Last 80 unconsumed characters:

	from /path/to/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb:249:in 'REXML::Parsers::BaseParser#pull'
	from /path/to/gems/rexml-3.4.4/lib/rexml/parsers/treeparser.rb:21:in 'REXML::Parsers::TreeParser#parse'
	from /path/to/gems/rexml-3.4.4/lib/rexml/document.rb:468:in 'REXML::Document#build'
	from /path/to/gems/rexml-3.4.4/lib/rexml/document.rb:105:in 'REXML::Document#initialize'
	from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/base_classes/group.rb:509:in 'Class#new'
	from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/base_classes/group.rb:509:in 'Jamf::Group#rest_xml'
	from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/api_objects/updatable.rb:97:in 'Jamf::Updatable#update_in_jamf'
	from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/base_classes/api_object.rb:1340:in 'Jamf::APIObject#update'
	from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/base_classes/group.rb:274:in 'Jamf::Group#update'
	from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/base_classes/group.rb:288:in 'Jamf::Group#save'
	from main.rb:20:in '<main>'

Problematic Code

The issue appears to be in lib/jamf/api/classic/base_classes/group.rb:509:

def rest_xml
  doc = REXML::Document.new Jamf::Connection::XML_HEADER # This line causes the exception
  group = doc.add_element self.class::RSRC_OBJECT_KEY.to_s
  # ...
end

Root Cause Analysis

This exception appears to be caused by recent changes in REXML.

It seems that the exception started occurring after the change introduced in Reject no root element XML as an invalid XML by naitoh · Pull Request #291 · ruby/rexml, which rejects XML documents without a root element as invalid.

The XML_HEADER content may need to be adjusted to ensure it contains a valid root element before being passed to REXML::Document.new.

Workaround

Currently, the only workaround is to downgrade to rexml 3.4.2 which doesn't enforce this validation.
I'm happy to assist with testing any potential fixes. Please let me know if you need any additional information.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions