<commit_before>'use strict'

const {Cc, Ci, Cu, Cm, Cr, components} = require('chrome')
const ioservice = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService)
Cu.import('resource://gre/modules/XPCOMUtils.jsm') /* global XPCOMUtils */
const gw = require('./gateways.js')
const isIPFS = require('./npm/is-ipfs.js')

const IPFS_SCHEME = 'ipfs'
const IPNS_SCHEME = 'ipns'
const FS_SCHEME = 'fs'
const WEB_SCHEME_PREFIX = 'web+' // https://github.com/lidel/ipfs-firefox-addon/issues/36

function CommonProtocolHandler () {}

function IpfsProtocolHandler () {}

function WebIpfsProtocolHandler () {}

function IpnsProtocolHandler () {}

function WebIpnsProtocolHandler () {}

function FsProtocolHandler () {}

function WebFsProtocolHandler () {}

const HANDLERS = {
  'fs': FsProtocolHandler,
  'ipfs': IpfsProtocolHandler,
  'ipns': IpnsProtocolHandler,

  'web+fs': WebFsProtocolHandler,
  'web+ipfs': WebIpfsProtocolHandler,
  'web+ipns': WebIpnsProtocolHandler
}

/*
 nsIURI does not not resolve relative paths properly
 nsIStandardURL does, but always uses /// for authority-less URLs
 thus we convert back and forth
*/
function resolveRelative (base, relative) {
  let newBase = Cc['@mozilla.org/network/standard-url;1'].createInstance(Ci.nsIStandardURL)
  newBase.QueryInterface(Ci.nsIURI)
  newBase.init(Ci.nsIStandardURL.URLTYPE_NO_AUTHORITY, -1, base.spec, null, null)
  let resolved = Cc['@mozilla.org/network/standard-url;1'].createInstance(Ci.nsIStandardURL)
  resolved.init(Ci.nsIStandardURL.URLTYPE_NO_AUTHORITY, -1, relative, null, newBase)
  resolved.QueryInterface(Ci.nsIURI)

  // console.log("rel", base, relative, newBase, resolved)

  return resolved.spec
}

CommonProtocolHandler.prototype = Object.freeze({
  defaultPort: -1,
  allowPort: function (port, scheme) { // eslint-disable-line no-unused-vars
    return false
  },

  /*
   since ipfs is a public network and pages could just embed their own js-ipfs code anyway to fetch the data
   we allow any page to embed ipfs uris and waive CORS restrictions

   TODO: consider adding URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT (discussion needed)
  */
  protocolFlags: Ci.nsIProtocolHandler.URI_NOAUTH |
    Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE |
    Ci.nsIProtocolHandler.URI_FETCHABLE_BY_ANYONE,

  normalizedIpfsPath: function (uriSpec) {
    let schemeExp = this.scheme.replace(/\+/, '\\+') // fix for web+fs etc
    let ipfsPath = uriSpec.replace(new RegExp('^' + schemeExp + '\\:\\/*'), '')
    // add protocol prefix if missing
    if (!(/^ip(?:f|n)s\//.test(ipfsPath))) {
      ipfsPath = this.pathPrefix + ipfsPath
    }
    return ipfsPath
  },

  newURI: function (aSpec, aOriginCharset, aBaseURI) {
    // console.info('Detected newURI with IPFS protocol: ' + aSpec)
    // console.log(aSpec, aOriginCharset, aBaseURI && aBaseURI.spec)

    if (aBaseURI && aBaseURI.scheme === this.scheme) {
      // presence of aBaseURI means a dependent resource or a relative link
      // resolve relative within the current protocol
      // leave the decision to convert to http to the next steps
      aSpec = resolveRelative(aBaseURI, aSpec)
    }

    let normalized = this.normalizedIpfsPath(aSpec)

    // console.log("norm", normalized)

    if (gw.fsUris && this.scheme === FS_SCHEME && new RegExp(`^${this.scheme}:`).test(aSpec)) {
      let uri = Cc['@mozilla.org/network/simple-uri;1'].createInstance(Ci.nsIURI)
      uri.spec = this.scheme + ':/' + normalized
      return uri
    }

    let uri = ioservice.newURI(normalized, aOriginCharset, gw.publicUri)

    // console.info('newURI routed to HTTP gateway:  ' + uri.spec)
    return uri
  },

  newChannel2: function (aURI, loadInfo) {
    // console.info('Detected newChannel for IPFS protocol: ' + aURI.spec)
    let normalized = this.normalizedIpfsPath(this.pathPrefix + aURI.path)
    let httpUri = ioservice.newURI(normalized, aURI.originCharset, gw.gwUri)
    let channel = null

    if (loadInfo !== null) {
      channel = ioservice.newChannelFromURIWithLoadInfo(httpUri, loadInfo)
    } else {
      channel = ioservice.newChannelFromURI(httpUri)
    }

    if (gw.fsUris && this.scheme === FS_SCHEME) {
      channel.originalURI = aURI
      channel.loadFlags &= ~Ci.nsIChannel.LOAD_REPLACE
<commit_msg>Reject invalid URIs in fs: handler<commit_after>'use strict'

const {Cc, Ci, Cu, Cm, Cr, components} = require('chrome')
const ioservice = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService)
Cu.import('resource://gre/modules/XPCOMUtils.jsm') /* global XPCOMUtils */
const gw = require('./gateways.js')
const isIPFS = require('./npm/is-ipfs.js')

const IPFS_SCHEME = 'ipfs'
const IPNS_SCHEME = 'ipns'
const FS_SCHEME = 'fs'
const WEB_SCHEME_PREFIX = 'web+' // https://github.com/lidel/ipfs-firefox-addon/issues/36

function CommonProtocolHandler () {}

function IpfsProtocolHandler () {}

function WebIpfsProtocolHandler () {}

function IpnsProtocolHandler () {}

function WebIpnsProtocolHandler () {}

function FsProtocolHandler () {}

function WebFsProtocolHandler () {}

const HANDLERS = {
  'fs': FsProtocolHandler,
  'ipfs': IpfsProtocolHandler,
  'ipns': IpnsProtocolHandler,

  'web+fs': WebFsProtocolHandler,
  'web+ipfs': WebIpfsProtocolHandler,
  'web+ipns': WebIpnsProtocolHandler
}

/*
 nsIURI does not not resolve relative paths properly
 nsIStandardURL does, but always uses /// for authority-less URLs
 thus we convert back and forth
*/
function resolveRelative (base, relative) {
  let newBase = Cc['@mozilla.org/network/standard-url;1'].createInstance(Ci.nsIStandardURL)
  newBase.QueryInterface(Ci.nsIURI)
  newBase.init(Ci.nsIStandardURL.URLTYPE_NO_AUTHORITY, -1, base.spec, null, null)
  let resolved = Cc['@mozilla.org/network/standard-url;1'].createInstance(Ci.nsIStandardURL)
  resolved.init(Ci.nsIStandardURL.URLTYPE_NO_AUTHORITY, -1, relative, null, newBase)
  resolved.QueryInterface(Ci.nsIURI)

  // console.log("rel", base, relative, newBase, resolved)

  return resolved.spec
}

CommonProtocolHandler.prototype = Object.freeze({
  defaultPort: -1,
  allowPort: function (port, scheme) { // eslint-disable-line no-unused-vars
    return false
  },

  /*
   since ipfs is a public network and pages could just embed their own js-ipfs code anyway to fetch the data
   we allow any page to embed ipfs uris and waive CORS restrictions

   TODO: consider adding URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT (discussion needed)
  */
  protocolFlags: Ci.nsIProtocolHandler.URI_NOAUTH |
    Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE |
    Ci.nsIProtocolHandler.URI_FETCHABLE_BY_ANYONE,

  normalizedIpfsPath: function (uriSpec) {
    let schemeExp = this.scheme.replace(/\+/, '\\+') // fix for web+fs etc
    let ipfsPath = uriSpec.replace(new RegExp('^' + schemeExp + '\\:\\/*'), '')
    // add protocol prefix if missing
    if (!(/^ip(?:f|n)s\//.test(ipfsPath))) {
      ipfsPath = this.pathPrefix + ipfsPath
    }
    return ipfsPath
  },

  newURI: function (aSpec, aOriginCharset, aBaseURI) {
    // console.info('Detected newURI with IPFS protocol: ' + aSpec)
    // console.log(aSpec, aOriginCharset, aBaseURI && aBaseURI.spec)

    if (aBaseURI && aBaseURI.scheme === this.scheme) {
      // presence of aBaseURI means a dependent resource or a relative link
      // resolve relative within the current protocol
      // leave the decision to convert to http to the next steps
      aSpec = resolveRelative(aBaseURI, aSpec)
    }

    let normalized = this.normalizedIpfsPath(aSpec)

    // console.log("norm", normalized)

    if (gw.fsUris && this.scheme === FS_SCHEME && new RegExp(`^${this.scheme}:`).test(aSpec)) {
      let uri = Cc['@mozilla.org/network/simple-uri;1'].createInstance(Ci.nsIURI)
      uri.spec = this.scheme + ':/' + normalized
      return uri
    }

    let uri = ioservice.newURI(normalized, aOriginCharset, gw.publicUri)

    // console.info('newURI routed to HTTP gateway:  ' + uri.spec)
    return uri
  },

  newChannel2: function (aURI, loadInfo) {
    // console.info('Detected newChannel for IPFS protocol: ' + aURI.spec)
    let normalized = this.normalizedIpfsPath(this.pathPrefix + aURI.path)
    let httpUri = ioservice.newURI(normalized, aURI.originCharset, gw.gwUri)
    let channel = null

    if (loadInfo !== null) {
      channel = ioservice.newChannelFromURIWithLoadInfo(httpUri, loadInfo)
    } else {
      channel = ioservice.newChannelFromURI(httpUri)
    }

    // fs: handler should reject non-ipfs URIs
    if (!isIPFS.url(httpUri.spec)) {
      channel.cancel(Cr.NS_ERROR_MALFORMED_URI)
      return channel
    }

    if (gw.fsUris && this.scheme === FS_SCHEME) {
      channel.originalURI = aURI
      channel.loadFlags &= ~Ci.nsIChannel.LOAD_REPLACE

{'fraction_non_alphanumeric': 0.1254451464675474, 'fraction_numerical': 0.0022975301550832855, 'mean_word_length': 3.8800448430493275, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6670717', 'n_tokens_mistral': 2960, 'n_tokens_neox': 2874, 'n_words': 648}