-
-
Notifications
You must be signed in to change notification settings - Fork 215
Add basic tests for prototype safety #414
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
Conversation
c60d145
to
1bb5e39
Compare
Language-specific implementation details shouldn't affect property existence checks. Validators should not traverse JS prototype chain or assign to it. If a validator supports applying default values from the schema, it should pass with that both enabled or disabled. Testing that might detect significant issues in e.g. JS implementations.
1bb5e39
to
74709a8
Compare
Included the generator in
|
afd279e
to
eae4651
Compare
Do we really need almost a thousand lines of tests (per directory) to test for this? It seems reasonable to me to check for common bugs, even language-specific ones, but could we make do with a single test in |
@awwright No, these test for a series of failure points, not just a single bug. I can remove the ones that are targeting Lua though, as those weren't checked against any actual Lua validator and I'm not sure if they are useful. The js ones found different issues in several js implementations though, I would prefer not to remove them. |
@awwright I removed Lua tests. This is now ~600 lines. |
e64b713
to
dc03735
Compare
Until they are checked against any actual Lua impl and it's confirmed that they are useful.
dc03735
to
ad19e2c
Compare
@awwright This is a demonstration of how badly js impls fail on this: ChALkeR/json-schema-benchmark@0f1b068 This was also a security vulnerability is ajv leading to code execution: https://github.com/ajv-validator/ajv/releases/tag/v6.12.3 I know only |
It seems like most of these tests are testing the same thing. For example, the outcome isn't going to change because you used an array instead of an object. Is there any case where one of the tests failing is not predictive of the other tests failing? I.e. is it feasible to reduce this to a single schema being tested, with a positive and negative case, in Was the code execution because of how ajv compiles to ECMAScript code? I poked around with this idea some time ago and concluded since you can't store functions in JSON, it's pretty difficult do do anything malicious. |
I mean, to reiterate my earlier point, I think it's OK to test for a common platform-specific or language-specific bug; and if you're adding a second test, it's either testing for something completely different, or it's testing for something that the first one is likely to pick up (in which case, it's not really testing for a "common" bug). |
There were multiple issues in ajv each separately leading to code execution. One of them was directly related to this + Re: duplication -- if you check ChALkeR/json-schema-benchmark@0f1b068, multiple impls fail different subsets of these tests. I don't think this could be reduced to a single one -- that might slip some kind of errors through, which is might be dangerous given the security nature of this. |
@awwright It would be possible to merge this into one huge schema with subschemas for properties and test everything against it (in properties), but I don't see how would that be better than the current approach. |
Here, I split the commit linked above in four parts to make it more readable:
There, it's easy to see in the first commit that different validators fail different subsets of these tests. |
@awwright Specifically, I don't recommend removing any tests from here based on guesses how they should automatically pass if others pass. |
Here is a list of failures minus one validator. Note that this is condensed, and some validators different tests inside them -- this is a list of schemas which caused failures. Expand
|
What does "via required" mean here? |
@awwright: It's a part of the test description Generator:
Test json file: Seems that descriptions in |
727a3c2
to
cf26b9f
Compare
This was my impression as well. When I ran these tests on my implementation, I had 56 errors. There were only three places in my code that needed changes. 56 test failures for 3 bugs indicates that there is a lot of redundancy in these tests. However, just because these tests are redundant the way my implementation is designed, doesn't necessarily mean they are going to be redundant for another implementation that makes different design decisions. So, it's hard to say what the right balance is. Although I'm grateful that these tests found bugs in my implementation, I don't think the official test suite should be this exhaustive for language specific tests. Every implementation should have their own tests in addition to the official suite that tests their API and the quirks of the language they are using. My suggestion would be to add a few tests to the main suite that should cover most prototype safety issues. Three tests would have been sufficient for me and I didn't consider prototype safety at all when implementing, so I think 3-10 tests should be sufficient to catch all issues in all but the most poorly designed code. The full exhaustive set of tests (or at least the generation script) can be included as an optional suite for js implementations who want to be really really sure they're not missing anything. |
@jdesrosiers This now has 30 tests. For comparison, #385 introduces 172 tests. Different implementations have different bugs, as can be seen in the list above. It's testing not one failure point but many, and as you mentioned, that was 3 bugs, not one, in a single impl. |
@jdesrosiers Would you be able to show me the fix that you implemented? |
For the |
This isn't 30 tests. There are 30 subjects that each have 12 tests.
Yep, I find that problematic as well.
You have all that data on which implementations are failing which tests. You should be able to use that data to determine which are the most valuable tests. Like I said, I'm not worried about catching every possible language specific error in the main test suite. I really don't think it should have hundreds of tests that only apply to JavaScript. Having a few of the most valuable tests is fine. Having the exhaustive set of tests available in a separate area (similar to "optional" tests) is fine too. That's my opinion, but I don't care enough argue about it. Whatever you all decide to do with this is fine with me. |
So it sounds like we can pick up on the vast majority of problems with 2-3 tests for ECMAScript and Lua each, then. |
Perhaps there's an "easy" compromise to be made here -- think we just need to make a call. Specifically:
Does that sound agreeable? Probably relevant for #385 as well if we make it "policy" for how we handle large numbers of generated duplicated tests. |
Going to take the silence as "yes" :D -- @ChALkeR can you pick a smallish subset of these (e.g. 3 that cover 80% of the possible issues), submit those to the regular suite, and then obviously keep the generating script, but probably we need to document how to run it (and who should run it) in a sentence or two in the README? |
Any chance anyone who benefited from these is willing to do ^ (pick 3-5)? Otherwise will likely pick whatever few using my less experienced Javascript eye so we can close & merge. |
This extracts tests from #414, originally written in a slightly more granular manner by @ChALkeR, but here combines and pares them down so we only add ~10 rather than hundreds. Hopefully these should at least point implementers at the issue. If any real-world occurrences of bugs are uncovered that aren't covered by these, please raise a follow-up issue! Interested implementers may also reference the PR if they wish to run a fuller set of them. Co-authored by: Nikita Skovoroda <[email protected]>
I've extracted a subset of these (10-15) and pushed them as 597b1fb (across all the drafts). Roughly I pared down to one schema per property, and combined them into one test case. If there's further improvements needed please speak up in a future issue or PR, otherwise closing this! Thanks for submitting them. |
Language-specific implementation details shouldn't affect property existence checks.
Validators should not traverse JS prototype chain.
If a validator supports applying default values from the schema, it should pass with that both enabled or disabled.
Testing that might detect significant issues in e.g. JS implementations (although I attempted to target Lua as well, but that's completely untested against any Lua impl).
This test is generated by a generator of test 5 blocks, here: https://gist.github.com/ChALkeR/38c2753f9420feccbaac036b83bd51c0
Should I include the generator somehow, perhaps? If so, where should I place it?