From 53dfd91ca411e2b5b534ecafe7f40685bba6d568 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 22 Jan 2026 20:09:21 -0500 Subject: [PATCH 1/9] fix: still show ranges if there are multiple ranges, even if some are invalid --- index.js | 23 ++++++++++++++++++++--- test/range-parser.js | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 1d09e26..28a4155 100644 --- a/index.js +++ b/index.js @@ -42,6 +42,10 @@ function rangeParser (size, str, options) { // add ranges type ranges.type = str.slice(0, index) + // check if there are multiple ranges + var isMultiple = arr.length > 1 + var hasValidFormat = false + // parse all ranges for (var i = 0; i < arr.length; i++) { var indexOf = arr[i].indexOf('-') @@ -67,11 +71,20 @@ function rangeParser (size, str, options) { end = size - 1 } - if (isNaN(start) || isNaN(end)) { - return -2 + var isInvalidFormat = isNaN(start) || isNaN(end) + + // invalid format range + if (isInvalidFormat) { + if (!isMultiple) { + return -2 + } + continue } - // invalid or unsatisifiable + // track valid format + hasValidFormat = true + + // skip unsatisfiable ranges if (start > end || start < 0) { continue } @@ -84,6 +97,10 @@ function rangeParser (size, str, options) { } if (ranges.length < 1) { + // all ranges have invalid format + if (!hasValidFormat) { + return -2 + } // unsatisifiable return -1 } diff --git a/test/range-parser.js b/test/range-parser.js index f882a93..f5546bc 100644 --- a/test/range-parser.js +++ b/test/range-parser.js @@ -41,6 +41,12 @@ describe('parseRange(len, str)', function () { assert.strictEqual(parse(200, 'bytes=100-15b0'), -2) }) + it('should return -2 when all multiple ranges have invalid format', function () { + assert.strictEqual(parse(200, 'bytes=y-v,x-'), -2) + assert.strictEqual(parse(200, 'bytes=abc-def,ghi-jkl'), -2) + assert.strictEqual(parse(200, 'bytes=x-,y-,z-'), -2) + }) + it('should return -1 for unsatisfiable range', function () { assert.strictEqual(parse(200, 'bytes=500-600'), -1) }) @@ -55,6 +61,11 @@ describe('parseRange(len, str)', function () { assert.strictEqual(parse(200, 'bytes=500-999,1000-1499'), -1) }) + it('should return -1 when invalid format mixed with unsatisfiable ranges', function () { + assert.strictEqual(parse(200, 'bytes=500-600,x-'), -1) + assert.strictEqual(parse(200, 'bytes=x-,500-600'), -1) + }) + it('should parse str', function () { var range = parse(1000, 'bytes=0-499') assert.strictEqual(range.type, 'bytes') @@ -111,6 +122,28 @@ describe('parseRange(len, str)', function () { deepEqual(range[0], { start: 999, end: 999 }) }) + it('should ignore invalid format range when valid range exists', function () { + var range = parse(1000, 'bytes=100-200,x-') + assert.strictEqual(range.type, 'bytes') + assert.strictEqual(range.length, 1) + deepEqual(range[0], { start: 100, end: 200 }) + }) + + it('should ignore invalid format ranges when some are valid', function () { + var range = parse(1000, 'bytes=x-,0-100,y-') + assert.strictEqual(range.type, 'bytes') + assert.strictEqual(range.length, 1) + deepEqual(range[0], { start: 0, end: 100 }) + }) + + it('should ignore invalid format ranges at different positions', function () { + var range = parse(1000, 'bytes=0-50,abc-def,100-150') + assert.strictEqual(range.type, 'bytes') + assert.strictEqual(range.length, 2) + deepEqual(range[0], { start: 0, end: 50 }) + deepEqual(range[1], { start: 100, end: 150 }) + }) + it('should parse str with multiple ranges', function () { var range = parse(1000, 'bytes=40-80,81-90,-1') assert.strictEqual(range.type, 'bytes') From 7622b94c7f79627aa2badae71485f46e9b419baf Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 22 Jan 2026 20:39:44 -0500 Subject: [PATCH 2/9] test: add case for range missing dash in parseRange --- test/range-parser.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/range-parser.js b/test/range-parser.js index f5546bc..9aff2e5 100644 --- a/test/range-parser.js +++ b/test/range-parser.js @@ -1,4 +1,3 @@ - var assert = require('assert') var deepEqual = require('deep-equal') var parse = require('..') @@ -9,6 +8,12 @@ describe('parseRange(len, str)', function () { /TypeError: argument str must be a string/) }) + it('should return -2 for range missing dash', function () { + assert.strictEqual(parse(200, 'bytes=100200'), -2) + assert.strictEqual(parse(200, 'bytes=,100200'), -2) + assert.strictEqual(parse(200, 'bytes=100-200,100200'), -2) + }) + it('should return -2 for invalid str', function () { assert.strictEqual(parse(200, 'malformed'), -2) }) From c0bb7ea7df67385e6e128362ad21c3619d76e9a5 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 22 Jan 2026 21:22:28 -0500 Subject: [PATCH 3/9] refactor --- index.js | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/index.js b/index.js index 28a4155..4ccdf69 100644 --- a/index.js +++ b/index.js @@ -44,7 +44,7 @@ function rangeParser (size, str, options) { // check if there are multiple ranges var isMultiple = arr.length > 1 - var hasValidFormat = false + var status = -2 // -2: all ranges invalid, -1: at least one valid but unsatisfiable // parse all ranges for (var i = 0; i < arr.length; i++) { @@ -71,18 +71,16 @@ function rangeParser (size, str, options) { end = size - 1 } - var isInvalidFormat = isNaN(start) || isNaN(end) - // invalid format range - if (isInvalidFormat) { + if (isNaN(start) || isNaN(end)) { if (!isMultiple) { return -2 } continue } - // track valid format - hasValidFormat = true + // unsatisifiable + status = -1 // skip unsatisfiable ranges if (start > end || start < 0) { @@ -97,12 +95,7 @@ function rangeParser (size, str, options) { } if (ranges.length < 1) { - // all ranges have invalid format - if (!hasValidFormat) { - return -2 - } - // unsatisifiable - return -1 + return status } return options && options.combine From 0acd73ca1b66883a37f448f34e83848ea6705bc2 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 22 Jan 2026 21:49:01 -0500 Subject: [PATCH 4/9] add cases for handling empty and whitespace-only ranges in parseRange --- index.js | 4 ++++ test/range-parser.js | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/index.js b/index.js index 4ccdf69..8a7c3ba 100644 --- a/index.js +++ b/index.js @@ -50,6 +50,10 @@ function rangeParser (size, str, options) { for (var i = 0; i < arr.length; i++) { var indexOf = arr[i].indexOf('-') if (indexOf === -1) { + // ignore empty/whitespace-only ranges if there are other valid ranges + if (arr.length > 1 && arr[i].trim() === '') { + continue + } return -2 } diff --git a/test/range-parser.js b/test/range-parser.js index 9aff2e5..bec9f36 100644 --- a/test/range-parser.js +++ b/test/range-parser.js @@ -8,6 +8,10 @@ describe('parseRange(len, str)', function () { /TypeError: argument str must be a string/) }) + it('should return -2 for completely empty header', function () { + assert.strictEqual(parse(200, ''), -2) + }) + it('should return -2 for range missing dash', function () { assert.strictEqual(parse(200, 'bytes=100200'), -2) assert.strictEqual(parse(200, 'bytes=,100200'), -2) @@ -33,6 +37,12 @@ describe('parseRange(len, str)', function () { assert.strictEqual(parse(200, 'bytes= - '), -2) }) + it('should return -2 for empty range value', function () { + assert.strictEqual(parse(200, 'bytes='), -2) + assert.strictEqual(parse(200, 'bytes=,'), -2) + assert.strictEqual(parse(200, 'bytes= , , '), -2) + }) + it('should return -2 with multiple dashes in range', function () { assert.strictEqual(parse(200, 'bytes=100-200-300'), -2) }) @@ -199,4 +209,11 @@ describe('parseRange(len, str)', function () { deepEqual(range[2], { start: 0, end: 1 }) }) }) + + it('should ignore whitespace-only invalid ranges when valid present', function () { + var range = parse(1000, 'bytes= , 0-10') + assert.strictEqual(range.type, 'bytes') + assert.strictEqual(range.length, 1) + deepEqual(range[0], { start: 0, end: 10 }) + }) }) From 1cbffb1d874434e09f313b344c11e9ea26d4ff21 Mon Sep 17 00:00:00 2001 From: Blake Embrey Date: Fri, 23 Jan 2026 08:59:58 -0800 Subject: [PATCH 5/9] Remove extra conditions --- index.js | 21 +++++---------------- test/range-parser.js | 5 ++--- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/index.js b/index.js index 8a7c3ba..d5eb0ab 100644 --- a/index.js +++ b/index.js @@ -38,23 +38,17 @@ function rangeParser (size, str, options) { // split the range string var arr = str.slice(index + 1).split(',') var ranges = [] + var code = -1 // add ranges type ranges.type = str.slice(0, index) - // check if there are multiple ranges - var isMultiple = arr.length > 1 - var status = -2 // -2: all ranges invalid, -1: at least one valid but unsatisfiable - // parse all ranges for (var i = 0; i < arr.length; i++) { var indexOf = arr[i].indexOf('-') if (indexOf === -1) { - // ignore empty/whitespace-only ranges if there are other valid ranges - if (arr.length > 1 && arr[i].trim() === '') { - continue - } - return -2 + code = -2 + continue } var startStr = arr[i].slice(0, indexOf).trim() @@ -77,15 +71,10 @@ function rangeParser (size, str, options) { // invalid format range if (isNaN(start) || isNaN(end)) { - if (!isMultiple) { - return -2 - } + code = -2 continue } - // unsatisifiable - status = -1 - // skip unsatisfiable ranges if (start > end || start < 0) { continue @@ -99,7 +88,7 @@ function rangeParser (size, str, options) { } if (ranges.length < 1) { - return status + return code } return options && options.combine diff --git a/test/range-parser.js b/test/range-parser.js index bec9f36..c6552cf 100644 --- a/test/range-parser.js +++ b/test/range-parser.js @@ -15,7 +15,6 @@ describe('parseRange(len, str)', function () { it('should return -2 for range missing dash', function () { assert.strictEqual(parse(200, 'bytes=100200'), -2) assert.strictEqual(parse(200, 'bytes=,100200'), -2) - assert.strictEqual(parse(200, 'bytes=100-200,100200'), -2) }) it('should return -2 for invalid str', function () { @@ -77,8 +76,8 @@ describe('parseRange(len, str)', function () { }) it('should return -1 when invalid format mixed with unsatisfiable ranges', function () { - assert.strictEqual(parse(200, 'bytes=500-600,x-'), -1) - assert.strictEqual(parse(200, 'bytes=x-,500-600'), -1) + assert.strictEqual(parse(200, 'bytes=500-600,900-'), -1) + assert.strictEqual(parse(200, 'bytes=900-,500-600'), -1) }) it('should parse str', function () { From 4d8964453a4d7baf6f34af4976f87d7d3c606bf9 Mon Sep 17 00:00:00 2001 From: Blake Embrey Date: Fri, 23 Jan 2026 09:07:11 -0800 Subject: [PATCH 6/9] Remove invalid test --- test/range-parser.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/range-parser.js b/test/range-parser.js index c6552cf..373a5cc 100644 --- a/test/range-parser.js +++ b/test/range-parser.js @@ -75,11 +75,6 @@ describe('parseRange(len, str)', function () { assert.strictEqual(parse(200, 'bytes=500-999,1000-1499'), -1) }) - it('should return -1 when invalid format mixed with unsatisfiable ranges', function () { - assert.strictEqual(parse(200, 'bytes=500-600,900-'), -1) - assert.strictEqual(parse(200, 'bytes=900-,500-600'), -1) - }) - it('should parse str', function () { var range = parse(1000, 'bytes=0-499') assert.strictEqual(range.type, 'bytes') From 87b3c8a28a446e1fb69c7c5f45c5cb8dc2c4dbdd Mon Sep 17 00:00:00 2001 From: Blake Embrey Date: Fri, 23 Jan 2026 09:57:49 -0800 Subject: [PATCH 7/9] Add mixed invalids test back --- test/range-parser.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/range-parser.js b/test/range-parser.js index 373a5cc..aa049ea 100644 --- a/test/range-parser.js +++ b/test/range-parser.js @@ -75,6 +75,12 @@ describe('parseRange(len, str)', function () { assert.strictEqual(parse(200, 'bytes=500-999,1000-1499'), -1) }) + it('should return -2 for mixed invalid and unsatisfiable ranges', function () { + assert.strictEqual(parse(200, 'bytes=abc-def,500-999'), -2) + assert.strictEqual(parse(200, 'bytes=500-999,xyz-uvw'), -2) + assert.strictEqual(parse(200, 'bytes=abc-def,500-999,xyz-uvw'), -2) + }) + it('should parse str', function () { var range = parse(1000, 'bytes=0-499') assert.strictEqual(range.type, 'bytes') From 2718a652eecc1534e1703a8c60419ed9e1a95f52 Mon Sep 17 00:00:00 2001 From: Blake Embrey Date: Fri, 23 Jan 2026 10:43:44 -0800 Subject: [PATCH 8/9] Change to -1 for invalids + unsatisfied --- index.js | 7 +++---- test/range-parser.js | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index d5eb0ab..41e1cd3 100644 --- a/index.js +++ b/index.js @@ -38,7 +38,7 @@ function rangeParser (size, str, options) { // split the range string var arr = str.slice(index + 1).split(',') var ranges = [] - var code = -1 + var valid = false // add ranges type ranges.type = str.slice(0, index) @@ -47,7 +47,6 @@ function rangeParser (size, str, options) { for (var i = 0; i < arr.length; i++) { var indexOf = arr[i].indexOf('-') if (indexOf === -1) { - code = -2 continue } @@ -71,12 +70,12 @@ function rangeParser (size, str, options) { // invalid format range if (isNaN(start) || isNaN(end)) { - code = -2 continue } // skip unsatisfiable ranges if (start > end || start < 0) { + valid = true continue } @@ -88,7 +87,7 @@ function rangeParser (size, str, options) { } if (ranges.length < 1) { - return code + return valid ? -1 : -2 } return options && options.combine diff --git a/test/range-parser.js b/test/range-parser.js index aa049ea..03e517d 100644 --- a/test/range-parser.js +++ b/test/range-parser.js @@ -76,9 +76,9 @@ describe('parseRange(len, str)', function () { }) it('should return -2 for mixed invalid and unsatisfiable ranges', function () { - assert.strictEqual(parse(200, 'bytes=abc-def,500-999'), -2) - assert.strictEqual(parse(200, 'bytes=500-999,xyz-uvw'), -2) - assert.strictEqual(parse(200, 'bytes=abc-def,500-999,xyz-uvw'), -2) + assert.strictEqual(parse(200, 'bytes=abc-def,500-999'), -1) + assert.strictEqual(parse(200, 'bytes=500-999,xyz-uvw'), -1) + assert.strictEqual(parse(200, 'bytes=abc-def,500-999,xyz-uvw'), -1) }) it('should parse str', function () { From cd769d6a8ea037929de9c05beac8ed1ca85f30be Mon Sep 17 00:00:00 2001 From: Blake Embrey Date: Fri, 23 Jan 2026 10:45:12 -0800 Subject: [PATCH 9/9] Update test name --- test/range-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/range-parser.js b/test/range-parser.js index 03e517d..9f2c483 100644 --- a/test/range-parser.js +++ b/test/range-parser.js @@ -75,7 +75,7 @@ describe('parseRange(len, str)', function () { assert.strictEqual(parse(200, 'bytes=500-999,1000-1499'), -1) }) - it('should return -2 for mixed invalid and unsatisfiable ranges', function () { + it('should return -1 for mixed invalid and unsatisfiable ranges', function () { assert.strictEqual(parse(200, 'bytes=abc-def,500-999'), -1) assert.strictEqual(parse(200, 'bytes=500-999,xyz-uvw'), -1) assert.strictEqual(parse(200, 'bytes=abc-def,500-999,xyz-uvw'), -1)