Class: Phlex::CSV

Inherits:
Object
  • Object
show all
Includes:
Callable
Defined in:
lib/phlex/csv.rb

Constant Summary collapse

FORMULA_PREFIXES =
["=", "+", "-", "@", "\t", "\r"].to_h { |prefix| [prefix, true] }.freeze
SPACE_CHARACTERS =
[" ", "\t", "\r"].to_h { |char| [char, true] }.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Callable

#to_proc

Constructor Details

#initialize(collection) ⇒ CSV

Returns a new instance of CSV.



9
10
11
12
13
14
15
16
# File 'lib/phlex/csv.rb', line 9

def initialize(collection)
	@collection = collection
	@_headers = []
	@_current_row = []
	@_current_column_index = 0
	@_view_context = nil
	@_first = true
end

Instance Attribute Details

#collectionObject (readonly)

Returns the value of attribute collection.



18
19
20
# File 'lib/phlex/csv.rb', line 18

def collection
  @collection
end

Instance Method Details

#call(buffer = +"",, view_context: nil) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/phlex/csv.rb', line 20

def call(buffer = +"", view_context: nil)
	unless escape_csv_injection? == true || escape_csv_injection? == false
		raise <<~MESSAGE
			You need to define escape_csv_injection? in #{self.class.name}, returning either `true` or `false`.

			CSV injection is a security vulnerability where malicious spreadsheet formulae are used to execute code or exfiltrate data when a CSV is opened in a spreadsheet program such as Microsoft Excel or Google Sheets.

			For more information, see https://owasp.org/www-community/attacks/CSV_Injection

			If you're sure this CSV will never be opened in a spreadsheet program, you can disable CSV injection escapes:

			  def escape_csv_injection? = false

			This is useful when using CSVs for byte-for-byte data exchange between secure systems.

			Alternatively, you can enable CSV injection escapes at the cost of data integrity:

			  def escape_csv_injection? = true

			Note: Enabling the CSV injection escapes will prefix any values that start with `=`, `+`, `-`, `@`, `\\t`, or `\\r` with a single quote `'` to prevent them from being interpreted as formulae by spreadsheet programs.

			Unfortunately, there is no one-size-fits-all solution to CSV injection. You need to decide based on your specific use case.
		MESSAGE
	end

	@_view_context = view_context

	each_item do |record|
		yielder(record) do |*args, **kwargs|
			view_template(*args, **kwargs)

			if @_first && render_headers?
				buffer << @_headers.join(",") << "\n"
			end

			buffer << @_current_row.join(",") << "\n"
			@_current_column_index = 0
			@_current_row.clear
		end

		@_first = false
	end

	buffer
end

#content_typeObject



70
71
72
# File 'lib/phlex/csv.rb', line 70

def content_type
	"text/csv"
end

#filenameObject



66
67
68
# File 'lib/phlex/csv.rb', line 66

def filename
	nil
end