Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    ListGrid.validateCell throws js error on hidden fields

    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.

    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());
        }
    }
    Error stack:

    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)
    The error appears to come from ISC_Grids.js line 54524:

    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");
        }
    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.

    #2
    Thanks for pointing this out. The crash has been resolved in all affected branches as of the nightly builds dated 2019-05-27.

    As far as hiding fields disabling validation, that's a separate issue, but should only be true for client-only DataSources, as the server itself will do its own validation before approving an update. If validation fails, an error will be reported back to the client.

    Comment


      #3
      Confirmed fixed on build 2019-07-03. Calling validateCell on a hidden field no longer throws a js error.

      Comment

      Working...
      X