icalendar 2.12.3 → 2.12.4

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: 7c417db33a0e54ccf03627a5e966cf86206e55e032dc66ba4aaf3f5ac9ec690a
4
- data.tar.gz: cebd6eb2f86f758e92b23fb0dc990032b866f0d1ccc825b05d823c4a56927e04
3
+ metadata.gz: 6a9a656fd81bc80eb43cf61e14d95a3b582f66bae80417da16a7e5d621910581
4
+ data.tar.gz: df88f0f0a1619dbdcba157316aba616019d146fe74e46aba6d7603dc30b40c26
5
5
  SHA512:
6
- metadata.gz: e4674fc5afbca40a1852ffd90a8e7d4b13364c4b9c4a7c966ab4cc4bd1ec06abf3df9bf9651bd99fd6083710717ef72af2520c4dcc75a252bd84ce73e281096c
7
- data.tar.gz: 835f7c88d1af3248ba9c57e7a68a8fc1198a3ed6cd73c540ca83f8e2fb831cebf364128f28d08384005df11f62c05d64462e60ced3a1cfbc799fee2effa7a0c7
6
+ metadata.gz: a0ad4eb07a4123fba9260916530046bd008a9f076a26a276f09a31cce789aa0801a38fff3d553b7b11fcb3de072c72aff758921ad601d7e643b808495425b0df
7
+ data.tar.gz: 06bab135b068613fdf8c4d10554a327a35b2072eb5e37c5e7bc7509b8e62b05e596153cfa8985065b2739e99eb7bc90dd8282c173972929900aa763d58e218b1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 2.12.4 - 2026-07-31
4
+ - TEXT unescape fix - Vincent Gao
5
+
3
6
  ## 2.12.3 - 2026-05-13
4
7
  - Memory use optimization - Jared Menard
5
8
  - Run CI against Ruby 4.0 - Artem Chubchenko
@@ -3,11 +3,11 @@
3
3
  module Icalendar
4
4
  module Values
5
5
  class Text < Value
6
+ UNESCAPE_GSUB_REGEX = /\\([\\,;nN])/.freeze
7
+
6
8
  def initialize(value, *args)
7
- value = value.gsub('\n', "\n")
8
- value.gsub!('\,', ',')
9
- value.gsub!('\;', ';')
10
- value.gsub!('\\\\') { '\\' }
9
+ # One left-to-right pass keeps unescape the exact inverse of value_ical; \n and \N are newline.
10
+ value = value.gsub(UNESCAPE_GSUB_REGEX) { |_| %w[n N].include?($1) ? "\n" : $1 }
11
11
  super value, *args
12
12
  end
13
13
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Icalendar
4
4
 
5
- VERSION = '2.12.3'
5
+ VERSION = '2.12.4'
6
6
 
7
7
  end
@@ -30,6 +30,39 @@ describe Icalendar::Values::Text do
30
30
  end
31
31
  end
32
32
 
33
+ describe 'unescape is the exact inverse of value_ical' do
34
+ bs = "\\"
35
+ {
36
+ 'a literal backslash before n (windows path)' => ["C:#{bs}#{bs}next", "C:#{bs}next"],
37
+ 'a UNC path with several backslashes' => ["#{bs * 4}srv#{bs * 2}sh", "#{bs * 2}srv#{bs}sh"],
38
+ 'an escaped backslash alone' => ["a#{bs}#{bs}b", "a#{bs}b"],
39
+ 'an escaped comma' => ["a#{bs},b", 'a,b'],
40
+ 'an escaped semicolon' => ["a#{bs};b", 'a;b'],
41
+ 'a lowercase newline escape' => ["a#{bs}nb", "a\nb"],
42
+ 'plain text without backslashes' => ['plain summary text', 'plain summary text'],
43
+ }.each do |desc, (onwire, content)|
44
+ context "given #{desc}" do
45
+ subject { described_class.new onwire.dup }
46
+
47
+ it 'decodes to the original content' do
48
+ expect(subject.value).to eq content
49
+ end
50
+
51
+ it 'round-trips back to the on-wire form' do
52
+ expect(subject.value_ical).to eq onwire
53
+ end
54
+ end
55
+ end
56
+
57
+ it 'decodes a capital-N newline escape (RFC 5545 3.3.11)' do
58
+ expect(described_class.new("a#{bs}Nb").value).to eq "a\nb"
59
+ end
60
+
61
+ it 'leaves a backslash before a non-escape char untouched' do
62
+ expect(described_class.new("a#{bs}:b").value).to eq "a#{bs}:b"
63
+ end
64
+ end
65
+
33
66
  describe 'escapes parameter text properly' do
34
67
  subject { described_class.new escaped, {'param' => param_value} }
35
68
  context 'single value, no special characters' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: icalendar
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.12.3
4
+ version: 2.12.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Ahearn