-
Notifications
You must be signed in to change notification settings - Fork 8
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
Validator added every time a step is submitted #42
Comments
Nice catch guys! |
yeah a deep clone would fix this case but as you said this may not be the only place the bug occurs. We should be ideally making config immutable - could use something like https://facebook.github.io/immutable-js/ or https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze. Obviously @gxxm's current method of setting options on the fly would need rethinking slightly, could perhaps unfreeze, amend the re-freeze? |
actually there isn't a way to unfreeze but still think we should consider locking config down |
+1 for making config immutable, unfortunately |
Nice spot! More debug around this might have made it visible earlier. It's something I'm keen to add more to our modules UKHomeOffice-attic/hof#90 |
Yes, it will need some thought but will hopefully pinpoint any other places in the code where we are directly modifying config |
@joefitter: A deep copy of fields on each request should fix all the related bugs as well shouldn't it? Obviously code should still check that a validator doesn't already exist when adding it to the list. |
@daniel-ac-martin yes it would but it wouldn't stop us from unknowingly altering the fields object again somewhere further down the line, or steps, or any other config we may wish to pass. Object.freeze should be used on any config objects to ensure this doesn't happen in future, but a deep copy on each request should fix the current issue |
In case it isn't obvious, I'd like to say that I think this bug should have quite a high priority (though I'm biased). - We do need to patch the validators on a per request basis and this bug can potentially allow a malicious user to render the forms un-completable for other users. (My new date-controller suffers from this but cannot really be fixed until it is fixed here.) Of course, I also think this will be a pain to fix. Anyone feeling energetic? |
You start Dan. |
@JoeChapman: Well I'm sure I will at some point, but I don't really get any time in my working day to do HOF stuff. (Been mainly writing Scala recently.) So really me being able to do this all hinges on me having no life. ;-) |
This is an initial fix for issue #42. Rather than adding an option validator (to check that the selected option is one of the defined set of options) on each form submission, add it once on start instead. - Moves the equality validator on 'options' outside of the function return - This means that the validator is added to the field on start up, not on each submission of the form. - We can avoid the overhead of checking if the validator has already been added on each submission. - Unit test added for the updated code, and others cleaned up slightly.
This is an initial fix for issue #42. For 'options' fields the form controller adds a validator to check that the chosen option is one of the defined set of options for the field. Rather than adding this validator on each form submission, this change adds it once on start up. - Moves the equality validator on 'options' outside of the function return - Unit test added for the updated code, and others cleaned up slightly.
Thanks @joefitter and @gxxm for flagging this! The Passport renewals service has now gone public, so keen to plug the memory leak as an initial step - #47 |
Cheers @daniel-ac-martin for merging. In terms of the wider discussion, I agree about immutable config. However, not so convinced about patching validators per request (quite possibly due to not really knowing the specifics of what you are doing). What if validators (formatters, etc...) could instead ask for the data they need? Rough example: a1ebdec Is that viable, and would it give enough flexibility to satisfy the needs of, for example, the date controller? |
@oli-weighell2: Yes I've been coming around to that point of view as well. It does mean that we will need something in the fields config to indicate that a field should be treated as an input-date mixin. (Support for the input-date mixin is the reason I thought we would need this.) I'd favour introducing a new concept (processors?) rather than expanding the scope of the validators and formatters. - They are quite neat little things as thing stand. I have a few ideas, but they will require PRs on the HMPO stack rather than simply being a controller that can sit in its own module. |
Updated HMPO/hmpo-form-wizard#35 to discuss. |
Incidentally, deep copy is a PITA in JavaScript in any case. |
however I dont think underscore has an equivalent |
It does not. We should move all the things to lodash imho |
@easternbloc I started to do just that in a branch. Stuff broke and I ran out of time. :-( |
fixed by deep cloning options a while back |
https://github.com/UKHomeOffice/passports-form-controller/blob/master/lib/validation/index.js#L62-L67
This appears to be an issue with any step that contains a field with options (radio, typeahead etc). An additional validator is added to the list of validators (created if empty) to check the value is in the list of options. The problem being that it doesn't check if the validator has already been added, and mutates the original array (reference to original stored, not cloned).
More worryingly is that this is persisted for the life of the instance, and across all users, each user that completes that step causes another identical validator to be added to the validators config, and this is persisted server-wide causing a potentially large memory leak.
@gxxm has been working on a fix, but probably worth pointing out to @easternbloc @JoeChapman @daniel-ac-martin and @gavboulton as will likely be affecting live systems.
This likely wasn't picked up before as the same validator is added many times, so the reduce below just calls the validator function over and over again yielding the same result (this should be replaced with _.any for efficiency), @gxxm noticed it when altering the
options
dynamically based on the results of a postcode lookup - multiple validators are added with different options and validation always failsThe text was updated successfully, but these errors were encountered: