SmartClient Version: v12.0p_2019-05-14/LGPL Development Only (built 2019-05-14)
Chrome Version 74.0.3729.157 (Official Build) (64-bit)
Calling validateCell on a hidden ListGrid field throws an error.
Error stack:
The error appears to come from ISC_Grids.js line 54524:
The call to getField in the bolded section returns null if the field is hidden, and hasFieldDependencies will blow up if the field is null.
Only validateCell appears to have this issue. ValidateRow works fine.
With this, it seems a user could bypass a validation by hiding a column using the grid context menus.
Chrome Version 74.0.3729.157 (Official Build) (64-bit)
Calling validateCell on a hidden ListGrid field throws an error.
Code:
public class HiddenFieldValidationTestWindow extends Window { private static class GridDataSource extends DataSource { { setClientOnly(true); final DataSourceTextField g1 = new DataSourceTextField("g1"); g1.setRequired(true); final DataSourceIntegerField g2 = new DataSourceIntegerField("g2"); g2.setRequired(true); setFields(g1, g2); } } private static class ValidationTestGrid extends ListGrid { ValidationTestGrid() { setHeight(100); setCanEdit(true); setDataSource(new GridDataSource()); setData(new ListGridRecord() {{ setAttribute("g1", "Test g1"); }}); final ListGridField g1 = new ListGridField("g1"); final ListGridField g2 = new ListGridField("g2"); setFields(g1, g2); } } private class ValidationTestLayout extends VLayout { ValidationTestLayout() { setHeight(300); setWidth(500); final ValidationTestGrid grid = new ValidationTestGrid(); grid.hideField("g2"); final Button validateG1 = new Button("validate g1") {{ addClickHandler(clickEvent -> grid.validateCell(0, "g1")); }}; final Button validateG2 = new Button("validate g2") {{ addClickHandler(clickEvent -> grid.validateCell(0, "g2")); }}; final Button validateRow = new Button("validate row") {{ addClickHandler(clickEvent -> grid.validateRow(0)); }}; setMembers(grid, validateG1, validateG2, validateRow); } } HiddenFieldValidationTestWindow() { setAutoSize(true); addItem(new ValidationTestLayout()); } }
Code:
*16:20:11.762:MUP0:WARN:Log:com.google.gwt.core.client.JavaScriptException: (TypeError) : Cannot read property 'dataPath' of null at hasFieldDependencies(http://127.0.0.1:8080/sgwt/isomorphic_12.0p_2019-05-14/system/modules-debug/ISC_Grids.js@26:54363) at validateCell(http://127.0.0.1:8080/sgwt/isomorphic_12.0p_2019-05-14/system/modules-debug/ISC_Grids.js@29:54524) at $kf_g$(testgwt-0.js@28:63249) at NEm_g$(testgwt-0.js@22:202646) at REm_g$(testgwt-0.js@3:202673) at ydi_g$(testgwt-0.js@16:138399) at xdi_g$(testgwt-0.js@8:138391) at k9b_g$(testgwt-0.js@8:7917) at mjc_g$(testgwt-0.js@14:8223) at xjc_g$(testgwt-0.js@9:8321) at Djc_g$(testgwt-0.js@8:8394) at ejc_g$(testgwt-0.js@24:8172) at uu_g$(testgwt-0.js@30:16463) at anonymous(testgwt-0.js@16:42812) at qL_g$(testgwt-0.js@28:4414) at tL_g$(testgwt-0.js@16:4470) at anonymous(testgwt-0.js@14:4450) at obj_0_g$.click(testgwt-0.js@22:42836) at handleActivate(http://127.0.0.1:8080/sgwt/isomorphic_12.0p_2019-05-14/system/modules-debug/ISC_Foundation.js@33:4499) at handleClick(http://127.0.0.1:8080/sgwt/isomorphic_12.0p_2019-05-14/system/modules-debug/ISC_Foundation.js@17:4515) at bubbleEvent(http://127.0.0.1:8080/sgwt/isomorphic_12.0p_2019-05-14/system/modules-debug/ISC_Core.js@44:50889) at handleClick(http://127.0.0.1:8080/sgwt/isomorphic_12.0p_2019-05-14/system/modules-debug/ISC_Core.js@24:48249) at _handleMouseUp(http://127.0.0.1:8080/sgwt/isomorphic_12.0p_2019-05-14/system/modules-debug/ISC_Core.js@54:47948) at handleMouseUp(http://127.0.0.1:8080/sgwt/isomorphic_12.0p_2019-05-14/system/modules-debug/ISC_Core.js@26:47791) at dispatch(http://127.0.0.1:8080/sgwt/isomorphic_12.0p_2019-05-14/system/modules-debug/ISC_Core.js@30:52531) at eval(eval at isc__makeFunction (http://127.0.0.1:8080/sgwt/isomorphic_12.0p_2019-05-14/system/modules-debug/ISC_Core.js@21:2446)
Code:
validateCell : function (rowNum, fieldName, suppressDisplay, processDependencies) { var colNum; if (isc.isA.String(fieldName)) colNum = this.getColNum(fieldName); else { colNum = fieldName; fieldName = this.getEditorName(rowNum, colNum); } // if we're showing an edit item for the field, ensure its value is up to date. if (this._editorShowing && (this.getEditRow() == rowNum ) && this.getEditForm().getItem(fieldName) != null) { this.storeUpdatedEditorValue(null, colNum); } var editVals = this.getEditValues(rowNum, colNum), record = this.getCellRecord(rowNum, colNum) ; // don't validate if the cell has not been edited (unless this is a new record in which // case it will be saved as a null value. if (record != null && (!editVals || ![B]this.hasFieldDependencies(this.getField(colNum)[/B], editVals))) { return true; } var undef, hadErrors = this.cellHasErrors(rowNum, fieldName), newValue, oldValue, field = this.getFieldByName(fieldName); if (!editVals) { newValue = undef; } else { newValue = isc.Canvas._getFieldValue(null, field, editVals, this, true, "validate"); } if (!record) { oldValue = undef; } else { oldValue = isc.Canvas._getFieldValue(null, field, record, this, true, "validate"); }
Only validateCell appears to have this issue. ValidateRow works fine.
With this, it seems a user could bypass a validation by hiding a column using the grid context menus.
Comment