-
Notifications
You must be signed in to change notification settings - Fork 916
GODRIVER-3605 Refactor StringN #2128
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,6 @@ package bsoncore | |
import ( | ||
"fmt" | ||
"io" | ||
"math" | ||
"strconv" | ||
"strings" | ||
) | ||
|
@@ -83,55 +82,73 @@ func (a Array) DebugString() string { | |
// String outputs an ExtendedJSON version of Array. If the Array is not valid, this method | ||
// returns an empty string. | ||
func (a Array) String() string { | ||
return a.StringN(math.MaxInt) | ||
str, _ := a.stringN(0) | ||
return str | ||
} | ||
|
||
// StringN stringifies an array upto N bytes | ||
func (a Array) StringN(n int) string { | ||
if lens, _, _ := ReadLength(a); lens < 5 || n <= 0 { | ||
return "" | ||
func (a Array) StringN(n int) (string, bool) { | ||
if n <= 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider treating n<=0 as "no limit", see comment on document.StringN(). |
||
if l, _, ok := ReadLength(a); !ok || l < 5 { | ||
return "", false | ||
} | ||
return "", true | ||
} | ||
return a.stringN(n) | ||
} | ||
|
||
// stringN stringify an array. If N is larger than 0, it will truncate the string to N bytes. | ||
func (a Array) stringN(n int) (string, bool) { | ||
length, rem, ok := ReadLength(a) | ||
if !ok || length < 5 { | ||
return "", false | ||
} | ||
length -= (4 /* length bytes */ + 1 /* final null byte */) | ||
|
||
var buf strings.Builder | ||
buf.WriteByte('[') | ||
|
||
length, rem, _ := ReadLength(a) // We know we have enough bytes to read the length | ||
length -= 4 | ||
|
||
var truncated bool | ||
var elem Element | ||
var ok bool | ||
|
||
if n > 0 { | ||
for length > 1 { | ||
elem, rem, ok = ReadElement(rem) | ||
|
||
length -= int32(len(elem)) | ||
if !ok { | ||
return "" | ||
} | ||
|
||
str := elem.Value().StringN(n - buf.Len()) | ||
|
||
buf.WriteString(str) | ||
|
||
if buf.Len() == n { | ||
return buf.String() | ||
var str string | ||
first := true | ||
for length > 0 && !truncated { | ||
l := 0 | ||
if n > 0 { | ||
if buf.Len() >= n { | ||
truncated = true | ||
break | ||
} | ||
|
||
if length > 1 { | ||
buf.WriteByte(',') | ||
l = n - buf.Len() | ||
} | ||
if !first { | ||
buf.WriteByte(',') | ||
if l > 0 { | ||
l-- | ||
if l == 0 { | ||
truncated = true | ||
break | ||
} | ||
} | ||
} | ||
if length != 1 { // Missing final null byte or inaccurate length | ||
return "" | ||
|
||
elem, rem, ok = ReadElement(rem) | ||
length -= int32(len(elem)) | ||
if !ok || length < 0 { | ||
return "", false | ||
} | ||
|
||
str, truncated = elem.Value().stringN(l) | ||
buf.WriteString(str) | ||
|
||
first = false | ||
} | ||
|
||
if buf.Len()+1 <= n { | ||
if n <= 0 || (buf.Len() < n && !truncated) { | ||
buf.WriteByte(']') | ||
} | ||
|
||
return buf.String() | ||
return buf.String(), truncated | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to truncate the string in the buffer? E.g. bsoncoreutil.Truncate(buf.String()) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not technically necessary, as the buffer has been truncated previously. However, an extra-truncating sounds like a good idea for an additional layer of security |
||
} | ||
|
||
// Values returns this array as a slice of values. The returned slice will contain valid values. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line causes GODRIVER-3561