non-aristotelian has quit [Quit: non-aristotelian]
johndescs has quit [Ping timeout: 246 seconds]
johndescs has joined #crystal-lang
vikaton has joined #crystal-lang
<FromGitter>
<anamba> i am working on output safety for ECR (html escaping by default, plus ways to mark strings as "safe" to prevent escaping: https://github.com/anamba/safe_ecr). however, i have run into a major obstacle: i can't inherit from String. i have been working around it, but the problems with my workaround are snowballing. there are a lot of existing methods out there in many different shards that strictly specify String
<FromGitter>
... arguments, and I just can't go rewriting or adding overloads for all of them. so i was curious whether this is "fixable" (some way I can either inherit from string, or add some kind of flag to a string to mark it as safe/unsafe)
ashirase has quit [Ping timeout: 246 seconds]
ashirase has joined #crystal-lang
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 250 seconds]
Raimondi has quit [Ping timeout: 240 seconds]
vikaton has quit [Quit: Connection closed for inactivity]
<yxhuvud>
That sounds like a worthy goal - having the template engine safe by default is so extremely helpful.
<yxhuvud>
Though it is context dependent, not everyone would generate html.
<FromGitter>
<DanilaFe> I for one don't generate HTML using ECR.
<FromGitter>
<DanilaFe> In fact, I generate C and Crystal
<FromGitter>
<anamba> anytime templates are involved, you will probably still need some type of escaping. the escaping function should be customizable.
<FromGitter>
<DanilaFe> I haven't need escaping thus far
<FromGitter>
<DanilaFe> I did use that once or twice
<FromGitter>
<DanilaFe> though if you're really set on this, perhaps some kind of DSL?
<FromGitter>
<DanilaFe> I could see an extension method on String that would return a wrapper class which is handled differently in ECR
_whitelogger has joined #crystal-lang
azuri5 has joined #crystal-lang
azuri5 has quit [Client Quit]
rohitpaulk has joined #crystal-lang
<FromGitter>
<anamba> @DanilaFe you probably want to look at how my shard works 😉
<FromGitter>
<DanilaFe> Hehe, did I say something silly?
<FromGitter>
<anamba> you pretty much described it
<FromGitter>
<DanilaFe> Oh :D
<FromGitter>
<DanilaFe> Your biggest problem, then, is the fact that your wrapper won't have the string methods?
<FromGitter>
<DanilaFe> I'm on my phone which is why I didn't check the shard
<FromGitter>
<DanilaFe> I wonder if some macro wizardry is possible to iterate every method in a class
<FromGitter>
<DanilaFe> Probably not?
azuri5 has joined #crystal-lang
<FromGitter>
<anamba> naw the biggest problem is simply that it's not a string. so if you have a method that wants a `String`, it's not gonna like my `HTMLSafeString`
<FromGitter>
<anamba> my wrapper does have all the string methods more or less, thanks to `forward_missing_to`
<FromGitter>
<DanilaFe> Oh, that's a thing
<FromGitter>
<DanilaFe> I know c++ can have implicit conversions
<FromGitter>
<DanilaFe> I wonder if crystal can do that
<FromGitter>
<anamba> so if this were ruby we'd be done thanks to duck typing :) and if there are methods that don't explicitly specify a `String` type then those are also fine. but there are tons of methods that deal with html that explicitly require `String` args or a union type including `String` (but obviously not my wrapper)
<FromGitter>
<DanilaFe> Unsurprisingly
<FromGitter>
<anamba> all i want is to be able to inherit from string, but String is a very, very strange class... so i can kinda understand why that is not possible right now.
<FromGitter>
<DanilaFe> Crystal doesn't have an implicit conversion mechanism, then?
<FromGitter>
<DanilaFe> What's strange about it?
<FromGitter>
<anamba> well i don't exactly want to convert, because then i'd lose my html safe flag
<FromGitter>
<anamba> oh a lot of things :-D String is not really a crystal class
<FromGitter>
<DanilaFe> Does it go into LLVM territory?
<FromGitter>
<anamba> i am using this in a real app (but for internal use, so i can't show it here)
azuri5 has quit [Quit: azuri5]
azuri5 has joined #crystal-lang
<FromGitter>
<nagash> @anamba Sorry, not sure if I'm helping, just throwing it out ideas. It might be possible to abuse the fact that Strings are reused? https://crystal-lang.org/api/0.27.0/StringPool.html
<FromGitter>
<anamba> that is fascinating, i hadn't seen StringPool before. but i'm not sure how that would help
<FromGitter>
<nagash> Object IDs will be the same; you can potentially look up if that Object ID was previously made safe?
<FromGitter>
<anamba> ah, i see what you mean. i guess i'd never thought of actually using object ids for anything in ruby or crystal before
azuri5 has quit [Quit: azuri5]
<FromGitter>
<anamba> wow strings with the same contents truly are not only equal, but have the same object_id. that is really weird! and kinda neat
<FromGitter>
<nagash> @anamba Yeah, I'm not sure how smart it is though.
<FromGitter>
<nagash> @anamba I think it's only for hard-coded strings that the compiler can find. eg. dynamic strings aren't reused.
<FromGitter>
<j8r> `StringPool` is used in lexers, when converting IO to string
<FromGitter>
<anamba> ah i see. ok, that makes more sense. it wouldn't work then.
<FromGitter>
<j8r> For example, JSON keys.
<FromGitter>
<j8r> @anamba why not adding a method to String, like a to/from
<FromGitter>
<anamba> i tried something like that. the trick is, what would it do?
<FromGitter>
<anamba> it can't modify anything on the string object itself
<FromGitter>
<anamba> it can't create a new string with a certain instance variable set (or at least, i couldn't figure out how)
<FromGitter>
<j8r> The `to` add escapes?
<FromGitter>
<anamba> there needs to be some kind of way to know that the escaping has been done (or intentionally skipped)
<FromGitter>
<j8r> and this isn't possible to have a custom type, with a `to_s : String`?
<FromGitter>
<anamba> @j8r yes, I am doing that, but when you convert to string then you lose the HTML safe status, meaning it might get escaped later
DTZUZO has quit [Ping timeout: 272 seconds]
rohitpaulk has quit [Ping timeout: 272 seconds]
azuri5 has joined #crystal-lang
Renich has joined #crystal-lang
azuri5 has quit [Quit: azuri5]
Renich has quit [Remote host closed the connection]
ashirase has quit [Ping timeout: 250 seconds]
ashirase has joined #crystal-lang
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 245 seconds]
azuri5 has joined #crystal-lang
azuri5 has quit [Client Quit]
<FromGitter>
<straight-shoota> @anamba But when you can use a safe string for any string operation, what ensures that it stays safe?
<FromGitter>
<straight-shoota> You can only safely use it with methods that are aware of safe strings, which means you can control them. All other methods expecting a regular string should be considered unsafe. They should just receive a plain string.
azuri5 has joined #crystal-lang
DTZUZO has joined #crystal-lang
<FromGitter>
<anamba> Strings can't be modified. A method that is not aware of safe strings would return a regular String.
<FromGitter>
<straight-shoota> > A method that is not aware of safe strings would return a regular String. ⏎ ⏎ That's the point. A method that is not aware of safe strings can't be trusted to modify strings in a safe way.
<FromGitter>
<yxhuvud> @straight-shoota that is fine (and very much intentional) as long as the result isn't considered safe. The rails way of handling string safety (which this is), is very convenient makes not escaping something that is opt-in instead of opt-out. It may not be a practical way to implement the same thing in Crystal, but it works *very* well in ruby-land.
<FromGitter>
<alehander42> distinct types could be a good fit, a method which returns a SafeString which is just distinct String (so different only on a type system level)
<FromGitter>
<nagash> I don't think there is any issue with code that you control (eg. it would be reasonable to implement this in a walled garden like amber or kemal), the problem arises if you want to deal with other generic code/shards who might provide generic HTML helpers or similar, probably only dealing with Strings in and out. You need to add state to the String if you want to ensure it's safe, and perform operations with
<FromGitter>
... other strings (addition, modification, whatever).
<FromGitter>
<yxhuvud> Right, you get a long way just be defining `String#+` for the type and possibly `IO#<<`
<FromGitter>
<j8r> other topic, am I alone finding the `Process` creation API confusing/hard to use?
<FromGitter>
<straight-shoota> @yxhuvud What? Why would you need `IO#<<(SafeString)`?
<FromGitter>
<straight-shoota> That's just `SafeString#to_s`
<FromGitter>
<j8r> for `String.build`
<FromGitter>
<straight-shoota> which should obviously act the same as `String#to_s` would for the same content
<FromGitter>
<yxhuvud> Ah.
<FromGitter>
<j8r> always messing `Process.new` vs `Process.run` :)
<FromGitter>
<j8r> In fact `Process.new ... &.wait` =~ `Process.run`
<FromGitter>
<greenbigfrog> ```HTTP::Client.post("localhost", body: response["data"])``` ⏎ ⏎ Why am I getting `no argument named 'body'` for this, but ` - HTTP::Client.post(url : String | URI, headers : HTTP::Headers | ::Nil = nil, body : BodyType = nil, tls = nil) (did you mean this one?)` as suggestion? [https://gitter.im/crystal-lang/crystal?at=5c19077ef4043314192d6e86]
<FromGitter>
<greenbigfrog> ok. so making it `response["data"].to_s` works, since JSON::Any isn't a BodyType, but wtf did I get a `no argument names` error?
<FromGitter>
<j8r> @greenbigfrog this isn't the entire error you got
<FromGitter>
<greenbigfrog> oh... it used the `*`, since it wasn't the fitting type
<FromGitter>
<mpcjanssen> so it seems the type of the voted column is not obviously a string.
<FromGitter>
<rishavs> oh yeah. its a custom type which I was using
<FromGitter>
<rishavs> CREATE TYPE VOTETYPE AS ENUM ('up','none','down');
<FromGitter>
<mpcjanssen> ok so that's why. It's return the raw data as a bytes slice
<FromGitter>
<rishavs> Is there a way to handle this with scalar or should I just use exec/query?
<FromGitter>
<mpcjanssen> scalar should be fine, just not as(String) after it
akaiiro has joined #crystal-lang
<FromGitter>
<rishavs> whats should then I use there? Int32 is also failing and I have never worked with Slices to knowhow to use them
<FromGitter>
<mpcjanssen> removing the `as(String)` and using `String.new(set_liked)` might work.
<FromGitter>
<kinxer> @rishavs Echoing @mpcjanssen, you can use this constructor: https://crystal-lang.org/api/0.27.0/String.html#new%28bytes%3ABytes%2Cencoding%3AString%2Cinvalid%3ASymbol%3F%3Dnil%29%3AString-class-method
<FromGitter>
<kinxer> (`Bytes` is an alias for `Slice(UInt8)`)
<FromGitter>
<mpcjanssen> yes specifying the encoding is obviously better
<FromGitter>
<rishavs> This tribute was acceptable to the compiler gods
<FromGitter>
<rishavs> thanks for all the help!
azuri5 has joined #crystal-lang
<FromGitter>
<rishavs> btw, i should be using utf-8 there, right? `set_liked = String.new(set_liked, "UTF-8")`
<FromGitter>
<r00ster91> @bew good idea! I thought about maybe adding a `color` argument to `Parser.new` (Parser inherits from Lexer) but that sounds much simpler.
<FromGitter>
<kinxer> @rishavs Probably you should use utf-8, but I guess it depends on the encoding used in your database.
azuri5 has quit [Quit: azuri5]
azuri5 has joined #crystal-lang
azuri5 has quit [Client Quit]
DeBot has joined #crystal-lang
<FromGitter>
<j8r> Having `libffi` issues on Alpine Edge :/
azuri5 has joined #crystal-lang
azuri5 has quit [Quit: azuri5]
rohitpaulk has joined #crystal-lang
<FromGitter>
<jwoertink> Interesting difference between ruby and crystal when calling split on an empty string.
<FromGitter>
<kingsleyh> however perhaps the r,s are unset for some reason? and I have not signed it correctly? the verify returns 1 which is successful verify - which I assumed meant the signing was ok
non-aristotelian has joined #crystal-lang
<FromGitter>
<jwoertink> Is there a method to check the last char written to a `String::Builder`?
<oprypin>
kingsleyh, as i was saying, it's a problem with bindings and not logic of any kind
<FromGitter>
<asterite> Nope :-(. It would be nice to have a String::Builder that would work like a mutable String (basically with all the bang operations that String has in Ruby, plus with random access)
<oprypin>
and while it doesn't make sense, that doesn't mean you should waste your time on code logic
<FromGitter>
<j8r> @talbergs what's not working with Tuple?
<FromGitter>
<jwoertink> Ah damn. I'm thinking I could seek and then reset the pointer back? Might get a little tricky though
<FromGitter>
<kingsleyh> oprypin: what do you suggest? you think the problem is with my binding for that function?
<FromGitter>
<j8r> @talbergs StaticArray are near always used for C compat, not in Crystal in the wild
<oprypin>
j8r, while that may be true, it's not really an argument for anything
<FromGitter>
<kinxer> @talbergs What error did you get?
<FromGitter>
<talbergs> ` @tiles uninitialized Tuple(Tile, Tile)` this works fine, thanks for link
<FromGitter>
<asterite> you really don't want to use `uninitialized`
<FromGitter>
<talbergs> p.s. property macro does not work with that line above (because of `unitialized`)..
<FromGitter>
<asterite> I'm also thinking you shouldn't need a tuple there, but I might be wrong
<FromGitter>
<talbergs> Well There will be at most two tiles (some binary data tructure)
<FromGitter>
<kinxer> If it's a 2-tuple, why can't you just have two `Tile` variables? What does a tuple gain you?
<FromGitter>
<talbergs> It's going to be layout structure, the distinction between left or right node doesn't matter. And array has an `each` that I could call. @kinxer
<FromGitter>
<kinxer> @talbergs That's reasonable. I just don't know that it sounds like a good enough reason to use an unsafe language feature.
<FromGitter>
<talbergs> Yes I did @kinxer , now giving it a second thought .. i'll go with that - it will be more structured.. at first glance, I saw I need that inheritance and opinionated instantiation (rather than creating just .new)
<FromGitter>
<talbergs> No it's the best @kinxer thank you for pointing uot that example again. Im such a noob hahaa
<FromGitter>
<kinxer> You're welcome, though @j8r did the work. :P
<FromGitter>
<talbergs> also didn't know structs so much is cr
<FromGitter>
<talbergs> :p
<FromGitter>
<talbergs> We both get that credit thou
<oprypin>
kingsleyh, `passing Void return value of lib fun call has no effect` makes sense to me. show the code and let's resolve this.
<oprypin>
but if you got to that point, why are you then getting the much worse error `Undefined symbols for architecture x86_64`?
<FromGitter>
<talbergs> Yes thanks read that already
<oprypin>
not to mention that, like, the bindings are still infested with those weird `LibC::Int*`
<FromGitter>
<j8r> At the end, I usually use struct
<FromGitter>
<j8r> Because I usually don't need passing a class by reference
<oprypin>
kingsleyh, btw this function `ECDSA_SIG_get0` sets the values of the two args passed to it, they should be implemented using this: https://crystal-lang.org/docs/syntax_and_semantics/c_bindings/out.html -- and there is **no return value** (in conventional sense) if you havent noticed
<FromGitter>
<kingsleyh> oprypin - I got the Void return value error when I was doing a `p` in front of the call
<oprypin>
yeah cuz no return value, that makes sense. what about the rest?
<FromGitter>
<kingsleyh> ah I should define them yes
<oprypin>
i dont think you should?
<oprypin>
but yes, you'll just be getting that error whenever you have a compilable program
<FromGitter>
<kingsleyh> ah no I can't define them
<FromGitter>
<kingsleyh> variable 'r' is already defined, `out` must be used to define a variable, use another name
<oprypin>
you should add a print (`puts`) statement before all of this code and you'll see that none of your code actually runs, this error happens when the executable just barely starts running
<FromGitter>
<kingsleyh> ok - so still not working
<oprypin>
^just so you don't go looking for mistakes in the code's logic. we're back to the same problem with bindings and missing symbols, and my advice hasn't changed before
<oprypin>
from before
<FromGitter>
<kingsleyh> ok yes - you are right - no print statements are printed
<FromGitter>
<kingsleyh> sooooo!
<oprypin>
check that the symbol is there, and check that the library that you're checking is actually the one that's being used here (i think it's not)
<oprypin>
and if macos doesnt have this function by default you should consider looking for yet another alternative xD older than 3 years ago
<oprypin>
so yes, i think that's what your program is actually using
<FromGitter>
<kingsleyh> oh dear
<FromGitter>
<kingsleyh> ECDSA_SIG_get0 does not exist in there
<FromGitter>
<kingsleyh> :(
<oprypin>
so thats what i was saying
<oprypin>
and if you wanna look into fixing `-L#{__DIR__}/../ext/openssl/crypto` , my hunch would be that it should actually be `-L#{__DIR__}/../ext/openssl` or `-L#{__DIR__}/../ext/openssl/lib` or something like that - it's a *directory* path and should not contain a filename
<oprypin>
and again, it shouldnt be `LibC::Int**` but `BIGNUM*` (which, in turn, is `Void*`)
<oprypin>
i'm off now. might reply later if you mention me (no need to wait for me)