barefoot_js 0.19.0 → 0.19.1

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/barefoot_js.rb +85 -3
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 631274750e8e3f9408118cf4026fd8e0b3d04f94b249f2204ae10d22d153f0ff
4
- data.tar.gz: 6a17675eaef8c0be90ba6d990d14ccc2154ea7463d3aefbdba831b5a80469394
3
+ metadata.gz: bfdedbe747a977df46f615f6520db5261457009fd170541ef1785bdc492288bb
4
+ data.tar.gz: 733e254a8826a16aedd21678318c6307225f05c4fde4c18c76c251b7abd3f674
5
5
  SHA512:
6
- metadata.gz: 3e7301a0439697942dbd8478c4c68cd7502c8f4bece5909ad8389af720a18ac4e73c1f70e1bbb7996bbc74a4628c93ce009769e21017715cbdfde45a4bb8b482
7
- data.tar.gz: fed3eeb6ee21563aeb0a058f89b18321d98157390c58c9f312608158084ebe7ca30ebddd65ac3cb74c77962a547824e476f8809680b5c93c8d44230c289303b1
6
+ metadata.gz: b1c11f900684e23aa6609b9d7e4d81d5fed8dc9dda95cb91496ea66e9a14795dd032b4cc80da7267f05df73e3ccca36594fabfcd5979e501c088057717ac0207
7
+ data.tar.gz: a456a6030e1371aae170129871eebdd576aa0436fe6e10142173c674e121a50da6c572fb4b493802ac008d000324cfc3a2ad9af7448b930a0f7a48aa671a97e6
data/lib/barefoot_js.rb CHANGED
@@ -396,6 +396,12 @@ module BarefootJS
396
396
  return '' if value.nil?
397
397
  return value ? 'true' : 'false' if value.is_a?(TrueClass) || value.is_a?(FalseClass)
398
398
  return Evaluator.number_to_string(value) if value.is_a?(Numeric)
399
+ # JS `Array.prototype.toString` is `this.join(',')`, applied
400
+ # recursively -- Ruby's `Array#to_s` (inspect-style, e.g. "[[1], [2]]")
401
+ # would otherwise leak through here instead of the JS comma-join
402
+ # (e.g. reached via `.flat(0)`'s shallow copy joined afterwards,
403
+ # #2262).
404
+ return value.map { |el| string(el) }.join(',') if value.is_a?(Array)
399
405
 
400
406
  value.to_s
401
407
  end
@@ -564,13 +570,89 @@ module BarefootJS
564
570
  recv.map { |el| string(el) }.join(sep)
565
571
  end
566
572
 
567
- # `.length` works on both arrays (element count) and strings (character
568
- # count).
573
+ # `.length` works on both arrays (element count) and strings. The
574
+ # string branch counts UTF-16 CODE UNITS, matching JS
575
+ # `String.prototype.length` (#2255) -- NOT Ruby's native `String#length`
576
+ # (Unicode codepoints). A codepoint outside the Basic Multilingual
577
+ # Plane (astral, U+10000-U+10FFFF -- e.g. '👍') is a surrogate PAIR in
578
+ # UTF-16, so it counts as 2, not 1; '日本語' is 3 either way (BMP-only).
569
579
  def length(recv)
570
580
  return recv.length if recv.is_a?(Array)
571
581
  return 0 if recv.is_a?(Hash) || recv.nil?
572
582
 
573
- string(recv).length
583
+ string(recv).each_char.sum { |c| c.ord > 0xFFFF ? 2 : 1 }
584
+ end
585
+
586
+ # Mirrors Hono's own CSS-injection guard (`hono/jsx/utils.ts`'s
587
+ # `hasUnsafeStyleValue` -- the ORACLE a dynamic `style={{...}}` value
588
+ # must match, #2261): a hand-rolled structural scan for characters that
589
+ # could break out of a CSS declaration, NOT real CSSOM property
590
+ # validation. Ported byte-for-byte -- every character this scan tests
591
+ # is ASCII, so scanning by byte agrees with Hono's UTF-16-code-unit
592
+ # scan for every input; a multibyte UTF-8 sequence has no byte in the
593
+ # ASCII range, so it can never spuriously match one of these
594
+ # single-byte comparisons. Skips the reference implementation's regex
595
+ # fast-path (a pure optimization -- the scan below already returns
596
+ # `false` promptly for a clean value).
597
+ def has_unsafe_style_value?(value)
598
+ bytes = value.b
599
+ quote = 0
600
+ block_stack = []
601
+ i = 0
602
+ len = bytes.bytesize
603
+ while i < len
604
+ c = bytes.getbyte(i)
605
+ if c == 92 # \
606
+ return true if i == len - 1
607
+ i += 1
608
+ elsif quote != 0
609
+ return true if c == 10 || c == 12 || c == 13
610
+ quote = 0 if c == quote
611
+ elsif c == 47 && i + 1 < len && bytes.getbyte(i + 1) == 42 # "/*"
612
+ endi = bytes.index('*/', i + 2)
613
+ return true if endi.nil?
614
+ i = endi + 1
615
+ elsif c == 34 || c == 39 # " or '
616
+ quote = c
617
+ elsif c == 40 # (
618
+ block_stack.push(41)
619
+ elsif c == 91 # [
620
+ block_stack.push(93)
621
+ elsif c == 123 || c == 125 # { or }
622
+ return true
623
+ elsif c == 41 || c == 93 # ) or ]
624
+ return true if block_stack.empty? || block_stack.last != c
625
+ block_stack.pop
626
+ elsif c == 59 && block_stack.empty? # ;
627
+ return true
628
+ end
629
+ i += 1
630
+ end
631
+ quote != 0 || !block_stack.empty?
632
+ end
633
+
634
+ # Builds the CSS string for a `style={{...}}` JSX object-literal
635
+ # attribute (#2261) -- `pairs` alternates CSS key (always a
636
+ # compile-time-known literal), then value. A value that fails
637
+ # `has_unsafe_style_value?` (after JS-`String()`-style stringification)
638
+ # is DROPPED -- the whole `key:value` pair is omitted -- matching
639
+ # Hono's oracle behavior exactly. The final joined string is STILL
640
+ # HTML-escaped (mirroring Hono's own `escapeToBuffer` call on its
641
+ # accumulated style string) -- a "safe" value can still carry a
642
+ # literal `"`/`'`/`&` (e.g. a BALANCED-quote CSS string value like
643
+ # `"hello"` passes the structural scan) that would otherwise break out
644
+ # of the double-quoted `style="..."` attribute. Returns a `SafeString`
645
+ # so `bf.h` (which the emitter still wraps every dynamic value with)
646
+ # passes the already-escaped result through unchanged.
647
+ def style_object(*pairs)
648
+ parts = []
649
+ pairs.each_slice(2) do |key, value|
650
+ v = string(value)
651
+ next if has_unsafe_style_value?(v)
652
+
653
+ parts << "#{html_escape(key)}:#{html_escape(v)}"
654
+ end
655
+ SafeString.new(parts.join(';'))
574
656
  end
575
657
 
576
658
  # `Array.prototype.indexOf(x)` / `.lastIndexOf(x)` -- value-equality
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: barefoot_js
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.19.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - kobaken