Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Race condition in Nokogiri::CSS::Parser #1935

Open
ioquatix opened this issue Oct 23, 2019 · 3 comments

Comments

@ioquatix
Copy link

@ioquatix ioquatix commented Oct 23, 2019

#!/usr/bin/env ruby

require 'nokogiri'

parser = Nokogiri::CSS::Parser.new

puts Nokogiri::CSS::Parser.cache_on?

threads = []

threads << Thread.new do
	Nokogiri::CSS::Parser.without_cache do
		sleep 1
	end
end

threads << Thread.new do
	sleep 0.1
	
	Nokogiri::CSS::Parser.without_cache do
		sleep 2
	end
end

threads.each(&:join)

puts Nokogiri::CSS::Parser.cache_on?

# Prints false, but should be true.
@flavorjones

This comment has been minimized.

Copy link
Member

@flavorjones flavorjones commented Oct 23, 2019

Thanks for reporting, I'll take a look as soon as I can.

@ioquatix

This comment has been minimized.

Copy link
Author

@ioquatix ioquatix commented Oct 25, 2019

The reason why it happens is because there is no locking around @cache_on which is shared global state:

def without_cache &block
tmp = @cache_on
@cache_on = false
block.call
@cache_on = tmp
end

@ioquatix

This comment has been minimized.

Copy link
Author

@ioquatix ioquatix commented Nov 1, 2019

The solution is to use Thread.current[:nokogiri_cache_on] and assign to it directly rather than trying to read/write shared mutable state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.