Skip to content
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

URI.withinString - TypeError: Cannot read property 'length' of undefined #303

Closed
dandreit opened this issue Jun 30, 2016 · 3 comments
Closed

Comments

@dandreit
Copy link

dandreit commented Jun 30, 2016

Hi,

I'm using URI.js in node.js (v4.2.6) [ npm install --save urijs ]

And I wanted to extract several URLs from a text, so I wrote this little file:
lib/parseUrlsFromText.js:

const URI = require('urijs');

module.exports = function parseUrlsFromText(text) {
  console.log('text: ' + JSON.stringify(text, null, 2));
  var urls = [];
  URI.withinString(text, function(url) {
    console.log('detected url: ' + url);
    urls.push(url);
  });
  console.log('urls: ' + JSON.stringify(urls, null, 2));
  return urls;
};

* I then tried to test it, and then added the console.logs because of fails:
test/parseUrlsFromText.js:

const expect = require('chai').expect;
const parseUrlsFromText = require('../lib/parseUrlsFromText');

describe('lib/parseUrlsFromText.js', () => {

  // text: null
  // urls: []
  // -> OK
  it('should return empty array on \'null\' text', done => {
    expect(parseUrlsFromText(null)).to.deep.equal([]);
    done();
  });

  // text: "www.example.com"
  // detected_url: www.example.com
  // urls: []
  // result: 
  // -> TypeError: Cannot read property 'length' of undefined
  //    at Function.URI.withinString (node_modules/urijs/src/URI.js:972:40)
  it('should return a URL contained in \'www.example.com\'', done => {
    // expect(parseUrlsFromText('I love www.example.com!')).to.deep.equal(['example.com']);
    console.log('result: ' + parseUrlsFromText('www.example.com'));
    done();
  });

  // text: "I love example.com!"
  // urls: []
  // result:
  // -> Result empty, but NO BUG
  it('should return a URL contained in \'I love example.com!\'', done => {
    // expect(parseUrlsFromText('I love example.com!')).to.deep.equal(['example.com']);
    console.log('result: ' + parseUrlsFromText('I love example.com!'));
    done();
  });
...

I have not dug further, but this solved my problem:
In (node_modules/urijs/src/)URI.js:969 & 972
-> conditional add of slice.length and result.length

URI.withinString = function(string, callback, options) {
...
    while (true) {
      ...
      end = start + (slice && slice.length) ? slice.length : 0;
      var result = callback(slice, start, end, string);
      string = string.slice(0, start) + result + string.slice(end);
      _start.lastIndex = start + (result && result.length) ? result.length : 0;
    }

It may not be enough to make a Pull Request, but it's probably worth considering.
Hope that helps!
Cheers

@rodneyrehm
Copy link
Member

Nice catch!

.withinString() expects the callback to return a string, which your code (parseUrlsFromText.js) does not do. Because of that result.length fails.

A fix, if you want to send a PR, would be to skip the string mutation and set _start.lastIndex = end in case result === undefined. Adding a test for non-mutating callbacks would round things off nicely. Please make sure to open the PR against master, not gh-pages.

@dandreit
Copy link
Author

Thanks for your quick answer and clues!
I'll take a look and try to make it nicely. ; )

@dandreit
Copy link
Author

Note to anyone experiencing the same problem:
Until something may be done to make .withinString usable as I tryed,
as mentioned by @rodneyrehm, simply return the text argument you passed.
My adapted example:
lib/parseUrlsFromText.js:

const URI = require('urijs');

module.exports = function parseUrlsFromText(text) {
  var urls = [];
  URI.withinString(text, function(url) {
    urls.push(url);
    return text;
  });
  return urls;
};

=> Closing the Issue, as it solves the problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants