Gin: jsoniter change now causing panic on BindJSON()

Created on 12 Jul 2017  路  6Comments  路  Source: gin-gonic/gin

A change that was made on July 8th (commit 12508320c2834204677e29be58fec8103facdaf8) where you replaced json lib with jsoniter is now resulting in a panic being thrown (already in capture mode).

/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_iter_skip.go:47
/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_iter_skip.go:35
/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_reflect_native.go:626
/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_reflect_struct_decoder.go:909
/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_reflect_struct_decoder.go:765
/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_reflect.go:86
/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_reflect_slice.go:101
/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_reflect_slice.go:82
/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_reflect_struct_decoder.go:909
/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_reflect_struct_decoder.go:444
/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_reflect.go:216
/home/dev1/Projects/Go/src/github.com/json-iterator/go/feature_adapter.go:74
/home/dev1/Projects/Go/src/github.com/gin-gonic/gin/binding/json.go:29
autogenerated:5
/home/dev1/Projects/Go/src/github.com/gin-gonic/gin/context.go:467
/home/dev1/Projects/Go/src/github.com/gin-gonic/gin/context.go:456
/home/dev1/Projects/Go/src/github.com/gin-gonic/gin/context.go:449

Rolling back to the commit before has the code working with no panic. Below is an example JSON payload that results in the panic:

{
    "agency": null,
    "candidateId": 0,
    "candidate": "Blah Blah",
    "bookingId": 0,
    "shiftId": 1,
    "shiftTypeId": 0,
    "shift": "Standard",
    "bonus": 0,
    "bonusNI": 0,
    "days": [],
    "totalHours": 27,
    "expenses": [],
    "weekEndingDateSystem": "2016-10-09",
    "weekEndingDateClient": "2016-10-09",
    "submittedAt": null,
    "submittedById": null,
    "approvedAt": "2016-10-10T18:38:04Z",
    "approvedById": 0,
    "authorisedAt": "2016-10-10T18:38:04Z",
    "authorisedById": 0,
    "invoicedAt": "2016-10-10T20:00:00Z",
    "revokedAt": null,
    "revokedById": null,
    "revokeReason": null,
    "rejectedAt": null,
    "rejectedById": null,
    "rejectReasonCode": null,
    "rejectReason": null,
    "createdAt": "2016-10-03T00:00:00Z",
    "updatedAt": "2016-11-09T10:26:13Z",
    "updatedById": null,
    "overrides": [],
    "bookingApproverId": null,
    "bookingApprover": null,
    "status": "approved"
}

So much for being a "100% compatible drop in replacement" - surely the fact the next few commits had to go and change tests to make them work should've been a clue that something wasn't right?

bug

Most helpful comment

I will watch gin issues closely, raise issue here is fine.

All 6 comments

@AndyEsser Can you also open the issue on https://github.com/json-iterator/go

cc @taowen

can you provide your struct definition?

I will watch gin issues closely, raise issue here is fine.

Hello, please find below our structure for Timesheets which is the JSON payload I had above:

// Timesheet represents a timesheet.
type Timesheet struct {
    ID                   int64            `json:"id" db:"id"`
    JobID                int64            `json:"jobId" db:"job_id"`
    Job                  *string          `json:"job" db:"job_name"`
    ClientID             int64            `json:"clientId" db:"client_id"`
    ClientBusinessUnitID int64            `json:"clientBusinessUnitId" db:"client_business_unit_id"`
    ClientBusinessUnit   *string          `json:"clientBusinessUnit" db:"client_business_unit_name"`
    Client               *string          `json:"client" db:"client_name"`
    AgencyID             *int64           `json:"agencyId" db:"agency_id"`
    AgencyBusinessUnitID *int64           `json:"agencyBusinessUnitId" db:"agency_business_unit_id"`
    AgencyBusinessUnit   *string          `json:"agencyBusinessUnit" db:"agency_business_unit_name"`
    Agency               *string          `json:"agency" db:"agency_name"`
    CandidateID          int64            `json:"candidateId" db:"candidate_id"`
    CandidateFirstName   *string          `json:"candidateFirstName" db:"candidate_first_name"`
    CandidateLastName    *string          `json:"candidateLastName" db:"candidate_last_name"`
    BookingID            int64            `json:"bookingId" db:"booking_id"`
    Booking              *booking.Booking `json:"-"`
    ShiftID              int64            `json:"shiftId" db:"shift_id"`
    ShiftTypeID          int64            `json:"shiftTypeId" db:"shift_type_id"`
    Shift                *string          `json:"shift" db:"shift_type_name"`
    Bonus                *float64         `json:"bonus" db:"bonus"`
    BonusNI              *float64         `json:"bonusNI" db:"bonus_ni"`
    Days                 Days             `json:"days"`
    TotalHours           float64          `json:"totalHours"`
    Expenses             Expenses         `json:"expenses"`
    WeekEndingDateSystem date.Date        `json:"weekEndingDateSystem" db:"week_ending_date_system"`
    WeekEndingDateClient date.Date        `json:"weekEndingDateClient" db:"week_ending_date_client"`
    SubmittedAt          *time.Time       `json:"submittedAt" db:"submitted_at,omitempty"`
    SubmittedByID        *int64           `json:"submittedById" db:"submitted_by_id,omitempty"`
    ApprovedAt           *time.Time       `json:"approvedAt" db:"approved_at,omitempty"`
    ApprovedByID         *int64           `json:"approvedById" db:"approved_by_id,omitempty"`
    AuthorisedAt         *time.Time       `json:"authorisedAt" db:"authorised_at,omitempty"`
    AuthorisedByID       *int64           `json:"authorisedById" db:"authorised_by_id,omitempty"`
    InvoicedAt           *time.Time       `json:"invoicedAt" db:"invoiced_at,omitempty"`
    AdjustedAt           *time.Time       `json:"adjustedAt" db:"adjusted_at,omitempty"`
    RevokedAt            *time.Time       `json:"revokedAt" db:"revoked_at,omitempty"`
    RevokedByID          *int64           `json:"revokedById" db:"revoked_by_id,omitempty"`
    RevokeReason         *int             `json:"revokeReason" db:"revoke_reason"`
    RejectedAt           *time.Time       `json:"rejectedAt" db:"rejected_at,omitempty"`
    RejectedByID         *int64           `json:"rejectedById" db:"rejected_by_id,omitempty"`
    RejectReasonCode     *int             `json:"rejectReasonCode" db:"reject_reason_code"`
    RejectReason         *string          `json:"rejectReason" db:"reject_reason"`
    CreatedAt            time.Time        `json:"createdAt" db:"created_at"`
    UpdatedAt            *time.Time       `json:"updatedAt" db:"updated_at"`
    UpdatedByID          *int64           `json:"updatedById" db:"updated_by_id"`
    Overrides            Overrides        `json:"overrides"`
    Status               string           `json:"status"`
    AvailableShiftDays   []int            `json:"availableShiftDays"`
    BookingReference     *string          `json:"bookingReference" db:"booking_reference"`
    ReportingType        *string          `json:"reportingType,omitempty" db:"reporting_type"`
}

Note that I removed items from the JSON Payload to reduce it's length to that required to duplicate the bug - the bug still presents itself with a fully formed structure that has passed JSON Linter

Thank you

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mdnight picture mdnight  路  3Comments

mastrolinux picture mastrolinux  路  3Comments

xpbliss picture xpbliss  路  3Comments

oryband picture oryband  路  3Comments

wangcn picture wangcn  路  3Comments