smarter_csv 1.8.4 → 1.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 122fe57cc771c142a77ceb6305212e8884660a21b9c9edd67a198a14d19e103e
4
- data.tar.gz: 4355a9bb355d9f2fa7640ed9f712e6ba57b0a8682417c7668745f96ded39a7c1
3
+ metadata.gz: 8a812edc2e7a7778b0722a120acf8432eb844895b09668c3adf37184cfa08408
4
+ data.tar.gz: e78756cef3558b32cfa2788fdbfdd8723cc7a06872c97916fc2c95e16cf363d7
5
5
  SHA512:
6
- metadata.gz: 1646311a9207cf6f042f7e9b30b4ebc94cb6389b541548104b1af888ebdec7af0e50c675fd98ae3e60e86f0b6cd81b51a7e01588b82ae79cdb9ac2674bcc8a51
7
- data.tar.gz: 24cc3e5d6467349d24bac39c615e802a1a8f8e5100b1d8f1f93962f23d6ababb50d58e8505d28e83e5b3c7de7d65d57880dc4447dc1247ac2a200ba2f034d27e
6
+ metadata.gz: e81dfd9e713a301f58c64311a02e5047aa3678652e7c410fd8bfaaa5f49459faa3766f5e152d27b080d8677fb3cb452b45ae76086f9feba5caf5f1cd57220260
7
+ data.tar.gz: c2a6206128b0860138ca739a70b9546fe6ddbb37b4d09069607abc17a08fd51a2f2070d9ab2a6f55955a5f6a98f9def1dad7ce5ac03d0d6aabe67c9593be792f
data/CHANGELOG.md CHANGED
@@ -1,6 +1,9 @@
1
1
 
2
2
  # SmarterCSV 1.x Change Log
3
3
 
4
+ ## 1.8.5 (2023-06-25)
5
+ * fix parsing of escaped quote characters (thanks to JP Camara)
6
+
4
7
  ## 1.8.4 (2023-04-01)
5
8
  * fix gem loading issue (issue #232, #234)
6
9
 
data/CONTRIBUTORS.md CHANGED
@@ -50,3 +50,4 @@ A Big Thank you to everyone who filed issues, sent comments, and who contributed
50
50
  * [Hirotaka Mizutani ](https://github.com/hirotaka)
51
51
  * [Rahul Chaudhary](https://github.com/rahulch95)
52
52
  * [Alessandro Fazzi](https://github.com/pioneerskies)
53
+ * [JP Camara](https://github.com/jpcamara)
@@ -39,6 +39,8 @@ static VALUE rb_parse_csv_line(VALUE self, VALUE line, VALUE col_sep, VALUE quot
39
39
  VALUE field;
40
40
  long i;
41
41
 
42
+ char prev_char = '\0'; // Store the previous character for comparison against an escape character
43
+
42
44
  while (p < endP) {
43
45
  /* does the remaining string start with col_sep ? */
44
46
  col_sep_found = true;
@@ -59,11 +61,13 @@ static VALUE rb_parse_csv_line(VALUE self, VALUE line, VALUE col_sep, VALUE quot
59
61
  startP = p;
60
62
  }
61
63
  } else {
62
- if (*p == *quoteP) {
64
+ if (*p == *quoteP && prev_char != '\\') {
63
65
  quote_count += 1;
64
66
  }
65
67
  p++;
66
68
  }
69
+
70
+ prev_char = *(p - 1); // Update the previous character
67
71
  } /* while */
68
72
 
69
73
  /* check if the last part of the line needs to be processed */
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SmarterCSV
4
- VERSION = "1.8.4"
4
+ VERSION = "1.8.5"
5
5
  end
data/lib/smarter_csv.rb CHANGED
@@ -69,8 +69,8 @@ module SmarterCSV
69
69
  # in which case the row data will be split across multiple lines (see the sample content in spec/fixtures/carriage_returns_rn.csv)
70
70
  # by detecting the existence of an uneven number of quote characters
71
71
 
72
- multiline = line.count(options[:quote_char]).odd? # should handle quote_char nil
73
- while line.count(options[:quote_char]).odd? # should handle quote_char nil
72
+ multiline = count_quote_chars(line, options[:quote_char]).odd? # should handle quote_char nil
73
+ while count_quote_chars(line, options[:quote_char]).odd? # should handle quote_char nil
74
74
  next_line = fh.readline(options[:row_sep])
75
75
  next_line = next_line.force_encoding('utf-8').encode('utf-8', invalid: :replace, undef: :replace, replace: options[:invalid_byte_sequence]) if options[:force_utf8] || options[:file_encoding] !~ /utf-8/i
76
76
  line += next_line
@@ -196,6 +196,21 @@ module SmarterCSV
196
196
  @headers
197
197
  end
198
198
 
199
+ # Counts the number of quote characters in a line, excluding escaped quotes.
200
+ def count_quote_chars(line, quote_char)
201
+ return 0 if line.nil? || quote_char.nil?
202
+
203
+ count = 0
204
+ previous_char = ''
205
+
206
+ line.each_char do |char|
207
+ count += 1 if char == quote_char && previous_char != '\\'
208
+ previous_char = char
209
+ end
210
+
211
+ count
212
+ end
213
+
199
214
  protected
200
215
 
201
216
  # NOTE: this is not called when "parse" methods are tested by themselves
@@ -310,15 +325,18 @@ module SmarterCSV
310
325
  start = 0
311
326
  i = 0
312
327
 
328
+ previous_char = ''
313
329
  while i < line_size
314
330
  if line[i...i+col_sep_size] == col_sep && quote_count.even?
315
331
  break if !header_size.nil? && elements.size >= header_size
316
332
 
317
333
  elements << cleanup_quotes(line[start...i], quote)
334
+ previous_char = line[i]
318
335
  i += col_sep.size
319
336
  start = i
320
337
  else
321
- quote_count += 1 if line[i] == quote
338
+ quote_count += 1 if line[i] == quote && previous_char != '\\'
339
+ previous_char = line[i]
322
340
  i += 1
323
341
  end
324
342
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smarter_csv
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.4
4
+ version: 1.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tilo Sloboda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-02 00:00:00.000000000 Z
11
+ date: 2023-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
141
  - !ruby/object:Gem::Version
142
142
  version: '0'
143
143
  requirements: []
144
- rubygems_version: 3.1.6
144
+ rubygems_version: 3.2.3
145
145
  signing_key:
146
146
  specification_version: 4
147
147
  summary: Ruby Gem for smarter importing of CSV Files (and CSV-like files), with lots