cowboyd / handlebars.rb Goto Github PK
View Code? Open in Web Editor NEWRuby Bindings for Handlebars.js
Home Page: http://www.handlebarsjs.com
Ruby Bindings for Handlebars.js
Home Page: http://www.handlebarsjs.com
We were having a lot of issues with this gem causing hanging behaviour in a multi-threaded environment. V8 is the downstream cause of this behaviour.
We looked at #46 to try to solve it, but that PR exhibited similar issues.
We ended up solving by using a Singleton class to manage a mutex whenever you want to compile a template. An example below in case anyone else hits the same problem:
HandlebarsCompiler.instance.compile(layout_path, content_path, data)
class HandlebarsCompiler
include Singleton
def initialize
@mutex = Mutex.new
end
def compile(layout_path, content_path, data)
@mutex.synchronize do
content_template = File.read(content_path)
handlebars = Handlebars::Context.new
handlebars.register_partial('content', content_template)
html = handlebars.compile(File.read(layout_path))
html.call(data)
end
end
end
Quote from GH security advisory for CVE-2021-23383, first reported on May 4, 2021:
The package handlebars before 4.7.7 are vulnerable to Prototype Pollution when selecting certain compiling options to compile templates coming from an untrusted source.
GHSA has scored this a 9.8/10 (Critical).
I'm opening this issue as a sort of PSA, in case anyone is still using this gem as-is. It probably would not be too difficult to fix this (just update the gemspec to allow handlebars-source '~>4.7.7'
), but since this gem hasn't been updated in 9 years I don't expect that's going to happen.
As stated in the readme, "In general, you should not trust user-provided templates", and if you're doing that, this CVE likely won't affect you. On the other hand, if you are depending on using user-provided templates, you should be aware that this CVE (and a dozen more, see: https://security.snyk.io/vuln/npm?search=handlebars) could affect you.
TL;DR source code.
So does this support arrays or lists?
Currently it's not possible to run handlebars.rb on JRuby or to switch to mini_racer.
Can we please use execjs instead of invoking therubyracer directly?
Forgive me if this isn't the right place, but is there a way to get at the options hash ala http://handlebarsjs.com/expressions.html#helpers ?
Hello,
I want to do this:
Handlebars.registerHelper('method_label', function(method) {
if( method == "a")
return "label1"
else
return "label2"
});
<span class={{method_label method}}>Hi</span>
how can I add helper like this ?
I know I can do this
handlebars.register_helper(:twice) do |block|
"#{block.call}#{block.call}"
end
but what I really want is this
def my_cool_method(string)
string + "is so cool!"
end
handlebars.register_helper(:my_cool_method)
My aim is to keep my view helpers as DRY as my templates.
It would seriously kick 20 types of ass if this worked :)
I am having some issues in figuring out how to reference this in a helper.
From the example it looks like helpers are written in ruby, how can i reference this then?
It would be nice if there was support for Rails' String#html_safe to be treated the same way as Handlebars::SafeString.
Handlebars 1.0.0-rc3 has a problem with the parser that is fixed in 1.0.12.
1.0.0-rc3 example
http://jsbin.com/alegep/1/edit
1.0.12 example
http://jsbin.com/ahiqoq/1/edit
According to http://handlebarsjs.com/expressions.html, "A Handlebars helper call is a simple identifier, followed by zero or more parameters", which was the case as of handlebars.rb 0.3.2.
I had added a custom "helperMissing" helper to my Handlebars::Context subclasses that made use of this feature for simple property lookup on the object. As of 0.4.0, this no longer works: the helperMissing helper is simply not invoked unless there are one or more parameters supplied.
Here's a link to a commit on my project that illustrates this.
Is this by design, and the handlebars docs are outdated? Or is this a bug?
I'm not sure if this is broken, or if I'm just doing it wrong. But there is no documentation on how to precompile templates and then load the precompiled template and call it.
I'm generating html on the server, but want to precompile the templates (for performance reasons) and save them as .js. Then at runtime, load the js file and call it with an options hash to generate html.
I see in Handlebars::Context there is a precompile function but it seems to produce different output from npm's handlebars precompile. And once I have it, I can't seem to load it back in, and call it.
I've tried Handlebars::Context.new.handlebars.template(str).apply({}), and variations of that. But still can't get something working.
Can someone update the docs on this, if the functionality is there and working? Or otherwise fix this.
Thanks in advance
Not clear (or possible?) from the documentation. Thanks!
we have to skip this. verify that partials are either working or not and then enable the tests.
Although therubyracer can be set up with Rosetta emulation, there are runtime issues with it. While searching for a solution, I discovered that therubyracer is no longer maintained.
therubyracer should be switched out with another suitable JS runner so that handlebars.rb can be used into the future.
See the following for a good example:
I just forked the project to give this a go. I'll update with findings as I go.
Hi
How do I get this to install on windows *keep in mind libv8 and therubyracer dependencies.
Thanks
I have a template with the expression {{#if array.count > 0}}
but it always evaluates to true. {{ array.count}}
seems to evaluate to empty. I also tried array.length
but same result.
I looked at upgrading the handlebars-source gem, but the specs all fail.
The handlebars variable here, has no methods on it after upgrade.
Something in the 1.1 release has changed with the handlebars-source, I assume with the change to include AMD and CommonJS builds, but this is out of my depth.
Any ideas?
Could this gem use ExecJS instead of a hard dependency on therubyracer? We're having some version conflicts and making this more flexible would be great.
I'd like to be able to use handlebars as a safe and simple templating system that can process user provided templates. The README on the project doesn't make a statement on whether this is an intended or safe use of the library. I asked on #handlebars on freenode and got an "unknown" response from wycats.
I ran through the handlebars.rb source and nothing jumped out at me, but I'm uncertain about what can happen in the handoff to the javascript engine.. This seems like it should be a operation, but we all know how fickle security can be. Any comments that we can add to the documentation?
Looks like rending same compiled template many times simultaneously fires errors like V8::Error: Maximum call stack size exceeded
or worse, gets the process stuck.
Is there a better practice for that?
I don't want to lose the speed of compiled templates.
The rendering is running under Sidekiq process which gets stuck often.
require 'celluloid'
handlebars = Handlebars::Context.new
tpl = handlebars.compile(...)
# works fine
10.times { 20.times.map { |i| Celluloid::Future.new { puts "start #{i}"; sleep 0.1; puts "end #{i}" } }.each(&:value) }
# process will hang forever at some point
10.times { 20.times.map { |i| Celluloid::Future.new { puts "start #{i}"; tpl.call(data: data); puts "end #{i}" } }.each(&:value) }
I have a reasonable simple ActiveRecord relation with a method on my Tenancy object
class Tenancy
...
has_many :tenants
def full_names
collect(&:full_name).join(', ')
end
end
and a test that won't work
describe "template with deeper nesting" do
let(:t) {Handlebars::Context.new.compile "{{tenancy.tenants.full_names}}"}
it "should resolve" do
tenancy = Tenancy.create!
tenancy.tenants << Person.create full_name: "Tom Brady"
tenancy.tenants.full_names.should == "Tom Brady" #Success
t.call(:tenancy => tenancy).should == "Tom Brady" #Fails... why??
end
end
Just to make sure I was sane I checked 3 level resolution on tryhandlebarsjs.com and the following works fine
{{foo.bar.baz}}
with
{ "foo" :
{ "bar" :
{ "baz" : "Success" }
}
}
So what is the reason that the resolution fails in this case? Is it intended behaviour or a bug?
(For background, I have large client-side app using many handlebars templates, but looking to see if handlebars.rb is suitable for server side document generation from user-defined templates)
It's possible to cache compiled templates to speed up template rendering?
Marshal.dump(template)
TypeError: no _dump_data is defined for class V8::C::Object
I am assuming that I'd have to register helpers to get the standard #if
and #each
functionality to work with this Ruby implementation by default? I'm just looking at http://handlebarsjs.com/builtin_helpers.html and finding that this implementation generates the following error:
/Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/mustache-0.99.7/lib/mustache/parser.rb:267:in `error': Unclosed tag (Mustache::Parser::SyntaxError)
Line 70
{{#if credentialBindings}}
^
from /Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/mustache-0.99.7/lib/mustache/parser.rb:192:in `scan_tags'
from /Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/mustache-0.99.7/lib/mustache/parser.rb:122:in `compile'
from /Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/mustache-0.99.7/lib/mustache/template.rb:55:in `tokens'
from /Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/mustache-0.99.7/lib/mustache/template.rb:49:in `compile'
from /Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/mustache-0.99.7/lib/mustache/template.rb:35:in `render'
from /Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/mustache-0.99.7/lib/mustache.rb:125:in `render'
from /Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/mustache-0.99.7/lib/mustache.rb:85:in `render'
from /Users/Shared/Jenkins/Home/jobs/__JenkinsConfig/workspace/d2:86:in `create_android_gradle_build_config'
from /Users/Shared/Jenkins/Home/jobs/__JenkinsConfig/workspace/d2:241:in `block in create_jenkins_config'
from /Users/Shared/Jenkins/Home/jobs/__JenkinsConfig/workspace/d2:222:in `each'
from /Users/Shared/Jenkins/Home/jobs/__JenkinsConfig/workspace/d2:222:in `create_jenkins_config'
from /Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.18.1/lib/thor/command.rb:27:in `run'
from /Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command'
from /Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch'
from /Users/Shared/Jenkins/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
from /Users/Shared/Jenkins/Home/jobs/__JenkinsConfig/workspace/d2:461:in `<main>'
Please, update handlebars-source to the latest version
https://rubygems.org/gems/handlebars-source/versions/4.7.6
I followed the instructions in the readme:
git clone [email protected]:cowboyd/handlebars.rb.git #git it
cd handlebars.rb #go to it
git submodule update --init #pull down handlebars.js
rspec spec/ #test it
When I run rspec spec/ I get a bunch of failures, all due to the same thing:
Failure/Error: subject.compile(*args)
V8::Error:
no such module 'handlebars/compiler/parser'
Sure enough, vendor/handlebars/lib/handlebars/compiler/parser.js does not exist. I poked through the handlebars.js Git repo and it doesn't seem like that file was ever checked in.. what am I missing here?
The version bump to 0.8.0 happened 3 months ago now. There hasn't been a new version published to rubygems in a year. Any chance you'd be willing to update what's out on rubygems?
Cowboyd thx for the lib...
We are using our lib extensively
When are planing to support handlebars 1.0.0?
Here is how to reproduce this problem
class Greeting
def hello(name: 'John Doe')
"Hello #{name}"
end
end
greeting = Greeting.new
Handlebars::Context.new.compile("{{hello}}").call(greeting)
# V8::Error: wrong number of arguments (given 1, expected 0)
I would expect it to return "Hello John Doe"
but instead it raises an exception.
I'm guessing the intention is for this to be under the same MIT license as Handlebars.js, but I don't see any declaration as such.
Please add more detail to the security section of the Readme. It'd be useful to have some example code showing how to safely use user-provided templates. I'd also like to know what the vulnerabilities are, generally.
My current plan to avoid security issues in using user-provided templates is to serialize and then deserialize any objects that I pass to template.call(). Would that be enough to remove filesystem and database access in a Rails environment?
Finally, I'll use a whitelist to limit the fields that I allow to be reserialized before passing the object to template.call() so the users can't read any variables that I don't want to make public.
Thanks!
We had our app creating a new context for each request and memory usage went off the charts. But when we move it out to a global variable, memory stays pretty stable.
"this" changes when using a helper and the context to the original gets lost...
You know what I mean since we talked about it.
Getting the following error - I believe it's because base.js is now in the handlebars directory. I'm new at this - any idea how to fix the loader to respect the relative paths in the JS instead of always assuming /js/lib?
/Users/ippy04/Code/forked/handlebars.rb/lib/handlebars/loader.rb:25:in require': no such file: /Users/ippy04/Code/forked/handlebars.rb/js/lib/base.js (V8::JSError) from at /Users/ippy04/Code/forked/handlebars.rb/js/lib/handlebars/utils.js:1:55 from /Users/ippy04/Code/forked/handlebars.rb/lib/handlebars/loader.rb:33:in
require'
from at /Users/ippy04/Code/forked/handlebars.rb/js/lib/handlebars.js:6:1
from /Users/ippy04/Code/forked/handlebars.rb/lib/handlebars/loader.rb:33:in require' from /Users/ippy04/Code/forked/handlebars.rb/lib/handlebars.rb:20:in
block in handlebars'
from /Users/ippy04/Code/forked/handlebars.rb/lib/handlebars.rb:19:in module_eval' from /Users/ippy04/Code/forked/handlebars.rb/lib/handlebars.rb:19:in
handlebars'
from /Users/ippy04/Code/forked/handlebars.rb/lib/handlebars.rb:15:in register_helper' from /Users/ippy04/Code/forked/handlebars.rb/spec/handlebars_spec.rb:23:in
block (2 levels) in <top (required)>'
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.