Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX #2565] data-store: escape leading tildes in message content #2612

Merged
merged 1 commit into from
Dec 25, 2017

Conversation

vitvly
Copy link
Contributor

@vitvly vitvly commented Dec 5, 2017

Per Transit documentation, leading tildes have to be escaped, otherwise they are treated as tagged values.

@pablanopete
Copy link
Contributor

Hi @siphiuel thanks for your contribution! One of our team members will review shortly - in the meantime are you already part of the conversation on our Riot? I'd like to invite you at https://chat.status.im/#/register and ping me @hutch when you join! Thanks.

Copy link
Contributor

@jeluard jeluard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests to validate this behavior.

Transit is used for JSON parsing."
[{:keys [content] :as message}]
(if (and (not (string/blank? content))
(string/starts-with? content "~"))
Copy link
Contributor

@jeluard jeluard Dec 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like ~ is not the only special character. Also we probably want to do this generically, not only for this particular field? @

@vitvly vitvly force-pushed the bug/tildes-in-message-content-#2565 branch 2 times, most recently from 7107f6a to b1b53a8 Compare December 20, 2017 20:17
@vitvly
Copy link
Contributor Author

vitvly commented Dec 20, 2017

Hi!

Thank you for reviewing!

Made the following changes:

  1. Added tests in status-im.test.data-store.realm.core namespace
  2. The function that does the escaping (prepare-for-transit) is moved to status-im.data-store.realm.core and recursively walks through all string fields in a data structure that is saved to Realm.
  3. Additional special characters are taken into account.

I did a force push and some of your comments (the ones regarding items #2 and #3) seem to be gone. Sorry for that.

@jeluard
Copy link
Contributor

jeluard commented Dec 21, 2017

Thanks! It's not clear to me if escaped characters will be deserialized correctly. Could we add a round-trip test that would validate the the full serialize / deserialize logic?

@vitvly
Copy link
Contributor Author

vitvly commented Dec 21, 2017

Hi! There's a round-trip test at line #25:

(is (= data (-> prepared-data
                      clj->js
                      internal-convert)))

It checks where Clojure data structure survives the conversion in both directions intact. Do you think it is enough? Or should I add more tests of that kind?

@jeluard
Copy link
Contributor

jeluard commented Dec 21, 2017

Great I missed it!

)
(str "~" e)
(walk/walk walk-fn identity e)))]
(walk/walk walk-fn identity message)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use postwalk, then no need to use recursion inside walk-fn.
Something like

(letfn [(walk-fn [e]
            (cond->> e
                     (to-be-escaped? e)
                     (str escape-char)))]
    (walk/postwalk walk-fn message))

But this is just a suggestion

(if (and (string? e)
(first e)
(contains? #{"~" "^" "`"} (first e))
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[message]
(letfn [(walk-fn [e]
(if (and (string? e)
(first e)
Copy link
Contributor

@rasom rasom Dec 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this check, i mean (first e)

(letfn [(walk-fn [e]
(if (and (string? e)
(first e)
(contains? #{"~" "^" "`"} (first e))
Copy link
Contributor

@rasom rasom Dec 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please extract this set of characters which should be escaped to a constant.

(first e)
(contains? #{"~" "^" "`"} (first e))
)
(str "~" e)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please extract magic value ("~") to constant

fetching from Realm where Transit is used for JSON parsing."
[message]
(letfn [(walk-fn [e]
(if (and (string? e)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also would be great to extract all these predicates to separate function


(deftest transit-preparation
(testing "Check if leading Transit special characters are properly escaped with tildes"
(let [data {:to-be-escaped1 "~bad string"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please align values in maps and let forms

:to-be-escaped3 "`and another bad string"
:no-escaping "no escaping"
:vector-content ["a" "b" "c"]}
prepare-for-transit #'core/prepare-for-transit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for not using core/prepare-for-transit directly?

Copy link
Contributor

@rasom rasom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments above

@vitvly
Copy link
Contributor Author

vitvly commented Dec 24, 2017

Hi, thanks for reviewing!

Made the requested changes, details below:

  1. walk->postwalk: agree, looks simpler.
  2. Trailing parens: removed.
  3. Extra check for (first e): removed.
  4. Extracted special char values to constants, created a predicate fn.
  5. Not sure if I got the alignment properly in the test fn.
  6. Referring to private functions by vars: in Clojure private ns functions can only be referred to from outside via vars, but it seems that in Clojurescript there is no such restriction?

@rasom
Copy link
Contributor

rasom commented Dec 25, 2017

Referring to private functions by vars: in Clojure private ns functions can only be referred to from outside via vars, but it seems that in Clojurescript there is no such restriction?

I just haven't noticed that function is "private". Yeah it doesn't work in cljs and tbh i see no reason for using defn-, but that's not a big problem.

Not sure if I got the alignment properly in the test fn.

We usually align let-binding values, so it should look like

(let [data          {:to-be-escaped1 "~bad string"
                     :to-be-escaped2 "^another bad string"
                     :to-be-escaped3 "`and another bad string"
                     :no-escaping    "no escaping"
                     :vector-content ["a" "b" "c"]}
      prepared-data (core/prepare-for-transit data)]
  ...)

not

(let [data {:to-be-escaped1 "~bad string"
            :to-be-escaped2 "^another bad string"
            :to-be-escaped3 "`and another bad string"
            :no-escaping    "no escaping"
            :vector-content ["a" "b" "c"]}
      prepared-data (core/prepare-for-transit data)]
  ...)

@vitvly
Copy link
Contributor Author

vitvly commented Dec 25, 2017

Got it, made the changes.

@vitvly
Copy link
Contributor Author

vitvly commented Dec 25, 2017

I can squash if there are no other changes to be done.

@rasom
Copy link
Contributor

rasom commented Dec 25, 2017

@siphiuel, yes please squash commits

@vitvly vitvly force-pushed the bug/tildes-in-message-content-#2565 branch from ebe44a2 to e307794 Compare December 25, 2017 12:07
@vitvly
Copy link
Contributor Author

vitvly commented Dec 25, 2017

Done.

@rasom rasom merged commit b0b4226 into status-im:develop Dec 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants