Skip to content

Commit d550528

Browse files
committed
feat(client): add table and column name length validation
1 parent 457df4c commit d550528

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

sender.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ import (
4848
// chars found in table or column name.
4949
var ErrInvalidMsg = errors.New("invalid message")
5050

51+
const fsFileNameLimit = 127
52+
5153
type tlsMode int64
5254

5355
const (
@@ -375,6 +377,11 @@ func (s *LineSender) writeTableName(str string) error {
375377
if str == "" {
376378
return fmt.Errorf("table name cannot be empty: %w", ErrInvalidMsg)
377379
}
380+
// We use string length in bytes as an approximation. That's to
381+
// avoid calculating the number of runes.
382+
if len(str) > fsFileNameLimit {
383+
return fmt.Errorf("table name length is too large: %w", ErrInvalidMsg)
384+
}
378385
// Since we're interested in ASCII chars, it's fine to iterate
379386
// through bytes instead of runes.
380387
for i := 0; i < len(str); i++ {
@@ -470,6 +477,11 @@ func (s *LineSender) writeColumnName(str string) error {
470477
if str == "" {
471478
return fmt.Errorf("column name cannot be empty: %w", ErrInvalidMsg)
472479
}
480+
// We use string length in bytes as an approximation. That's to
481+
// avoid calculating the number of runes.
482+
if len(str) > fsFileNameLimit {
483+
return fmt.Errorf("column name length is too large: %w", ErrInvalidMsg)
484+
}
473485
// Since we're interested in ASCII chars, it's fine to iterate
474486
// through bytes instead of runes.
475487
for i := 0; i < len(str); i++ {

sender_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,49 @@ func TestFloat64Serialization(t *testing.T) {
193193
}
194194
}
195195

196+
func TestErrorOnLengthyNames(t *testing.T) {
197+
ctx := context.Background()
198+
199+
lengthyStr := strings.Repeat("a", 128)
200+
201+
testCases := []struct {
202+
name string
203+
writerFn writerFn
204+
expectedErrMsg string
205+
}{
206+
{
207+
"lengthy table name",
208+
func(s *qdb.LineSender) error {
209+
return s.Table(lengthyStr).StringColumn("str_col", "foo").AtNow(ctx)
210+
},
211+
"table name length is too large",
212+
},
213+
{
214+
"lengthy column name",
215+
func(s *qdb.LineSender) error {
216+
return s.Table(testTable).StringColumn(lengthyStr, "foo").AtNow(ctx)
217+
},
218+
"column name length is too large",
219+
},
220+
}
221+
222+
for _, tc := range testCases {
223+
t.Run(tc.name, func(t *testing.T) {
224+
srv, err := newTestServer(readAndDiscard)
225+
assert.NoError(t, err)
226+
227+
sender, err := qdb.NewLineSender(ctx, qdb.WithAddress(srv.addr))
228+
assert.NoError(t, err)
229+
230+
err = tc.writerFn(sender)
231+
assert.ErrorContains(t, err, tc.expectedErrMsg)
232+
233+
sender.Close()
234+
srv.close()
235+
})
236+
}
237+
}
238+
196239
func TestErrorOnMissingTableCall(t *testing.T) {
197240
ctx := context.Background()
198241

0 commit comments

Comments
 (0)