Skip to content

Commit a139d00

Browse files
committed
fix #109
1 parent 1404667 commit a139d00

File tree

2 files changed

+38
-19
lines changed

2 files changed

+38
-19
lines changed

func.go

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -459,25 +459,42 @@ func substringFunc(arg1, arg2, arg3 query) func(query, iterator) interface{} {
459459

460460
var start, length float64
461461
var ok bool
462-
463462
if start, ok = functionArgs(arg2).Evaluate(t).(float64); !ok {
464-
panic(errors.New("substring() function first argument type must be int"))
465-
} else if start < 1 {
466-
panic(errors.New("substring() function first argument type must be >= 1"))
467-
}
468-
start--
469-
if arg3 != nil {
470-
if length, ok = functionArgs(arg3).Evaluate(t).(float64); !ok {
471-
panic(errors.New("substring() function second argument type must be int"))
463+
panic(errors.New("substring() function first argument type must be number"))
464+
}
465+
// fix https://github.com/antchfx/xpath/issues/109
466+
start = math.Round(start)
467+
if start > float64(len(m)) {
468+
return ""
469+
}
470+
if arg3 == nil {
471+
if start <= 0 {
472+
return m
472473
}
474+
return m[int(start)-1:]
475+
}
476+
477+
if length, ok = functionArgs(arg3).Evaluate(t).(float64); !ok {
478+
panic(errors.New("substring() function second argument type must be number"))
473479
}
474-
if (len(m) - int(start)) < int(length) {
475-
panic(errors.New("substring() function start and length argument out of range"))
480+
length = math.Round(length)
481+
if length <= 0 {
482+
return ""
483+
}
484+
if length > float64(len(m)) {
485+
length = float64(len(m))
486+
}
487+
if start < 0 {
488+
length = length - math.Abs(start)
489+
if length <= 1 {
490+
return ""
491+
}
492+
return m[:int(length-1)]
476493
}
477-
if length > 0 {
478-
return m[int(start):int(length+start)]
494+
if start == 0 {
495+
return m[:int(length-1)]
479496
}
480-
return m[int(start):]
497+
return m[int(start-1):int(length+start-1)]
481498
}
482499
}
483500

xpath_function_test.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,14 @@ func Test_func_string_length(t *testing.T) {
118118
func Test_func_substring(t *testing.T) {
119119
test_xpath_eval(t, empty_example, `substring("motor car", 6)`, " car")
120120
test_xpath_eval(t, empty_example, `substring("metadata", 4, 3)`, "ada")
121-
//test_xpath_eval(t, empty_example, `substring("12345", 5, -3)`, "") // ?? it should be 1 ??
122-
//test_xpath_eval(t, empty_example, `substring("12345", 1.5, 2.6)`, "234")
123-
//test_xpath_eval(t, empty_example, `substring("12345", 0, 3)`, "12") // panic??
124-
//test_xpath_eval(t, empty_example, `substring("12345", 5, -3)`, "1")
121+
test_xpath_eval(t, empty_example, `substring("12345", 5, -3)`, "")
122+
test_xpath_eval(t, empty_example, `substring("12345", 1.5, 2.6)`, "234")
123+
test_xpath_eval(t, empty_example, `substring("12345", 0, 3)`, "12")
124+
test_xpath_eval(t, empty_example, `substring("12345", 5, -3)`, "")
125+
test_xpath_eval(t, empty_example, `substring("12345", 0, 5)`, "1234")
126+
test_xpath_eval(t, empty_example, `substring("12345", 1, 5)`, "12345")
127+
test_xpath_eval(t, empty_example, `substring("12345", 1, 6)`, "12345")
125128
test_xpath_eval(t, html_example, `substring(//title/child::node(), 1)`, "My page")
126-
//assertPanic(t, func() { selectNode(empty_example, `substring("12345", 5, -3)`) }) // Should be supports a negative value
127129
//assertPanic(t, func() { selectNode(empty_example, `substring("12345", 5, "")`) })
128130
}
129131

0 commit comments

Comments
 (0)