summaryrefslogtreecommitdiffstats
path: root/drivers/parisc/dino.c
AgeCommit message (Expand)Author
2019-09-08parisc: Disable HP HSC-PCI Cards to prevent kernel crashHelge Deller
2019-09-06parisc: Save some bytes in dino driverHelge Deller
2019-05-30treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152Thomas Gleixner
2019-02-21parisc/dino: use container_of in DINO_DEVChristoph Hellwig
2019-02-21parisc: move internal implementation details out of <asm/dma-mapping.h>Christoph Hellwig
2018-10-17parisc: Ratelimit dino stuck interrupt warningsHelge Deller
2018-10-17parisc: dino: Utilize DINO_MASK_IRQ() macroHelge Deller
2018-01-02parisc: Show unhashed HPA of Dino chipHelge Deller
2017-08-22parisc: Fix section mismatches in parisc core driversHelge Deller
2017-08-16parisc: pci memory bar assignment fails with 64bit kernels on dino/cujoThomas Bogendoerfer
2017-07-03parisc: DMA API: return error instead of BUG_ON for dma ops on non dma devsThomas Bogendoerfer
2016-01-12parisc: Initialize PCI bridge cache line and default latencyHelge Deller
2015-09-15PCI: Revert "PCI: Call pci_read_bridge_bases() from core instead of arch code"Bjorn Helgaas
2015-07-23PCI: Call pci_read_bridge_bases() from core instead of arch codeLorenzo Pieralisi
2014-08-27parisc: dino: fix %d confusingly prefixed with 0x in format stringHans Wennborg
2013-02-20drivers/parisc: Use printf extension %pR for struct resourceJoe Perches
2013-01-03Drivers: misc: remove __dev* attributes.Greg Kroah-Hartman
2012-08-22parisc/PCI: Use list_for_each_entry() for bus->devices traversalBjorn Helgaas
2012-06-13parisc/PCI: register busn_res for root busesYinghai Lu
2012-06-13PCI: replace struct pci_bus secondary/subordinate with busn_resYinghai Lu
2012-03-28Merge tag 'split-asm_system_h-for-linus-20120328' of git://git.kernel.org/pub...Linus Torvalds
2012-03-28Remove all #inclusions of asm/system.hDavid Howells
2012-02-23parisc/PCI: get rid of device resource fixupsBjorn Helgaas
2012-01-06parisc/PCI: dino: convert to pci_create_root_bus() for correct root bus resou...Bjorn Helgaas
2012-01-06parisc/PCI: dino: use pci_create_bus() instead of pci_scan_bus_parented()Bjorn Helgaas
2011-02-10[PARISC] Convert to new irq_chip functionsThomas Gleixner
2010-12-04parisc: convert the rest of the irq handlers to simple/percpuJames Bottomley
2010-10-14parisc: convert gsc and dino pci interrupts to flow handlersKyle McMartin
2010-10-14parisc: lay groundwork for killing __do_IRQKyle McMartin
2009-12-16parisc: Fixup last users of irq_chip->typenameThomas Gleixner
2009-08-02parisc: dino.c - check return value of pci_assign_resource()Helge Deller
2009-07-03parisc: remove obsolete hw_interrupt_typeThomas Gleixner
2009-07-03parisc: advertise PCI devs after "assign_resources"Grant Grundler
2009-04-02parisc: drivers: fix warningsAlexander Beregalov
2009-03-13parisc: dino: struct device - replace bus_id with dev_name(), dev_set_name()Kay Sievers
2009-03-13parisc: fix wrong assumption about bus->selfGrant Grundler
2009-01-09Merge git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6Linus Torvalds
2009-01-07PCI: parisc: use generic pci_swizzle_interrupt_pin()Bjorn Helgaas
2009-01-05parisc: drivers/parisc/: make code staticAdrian Bunk
2008-10-16generic: sparse irqs: use irq_desc() together with dyn_array, instead of irq_...Yinghai Lu
2008-05-15drivers/parisc: replace remaining __FUNCTION__ occurrencesHarvey Harrison
2008-04-20PCI: remove parisc consumer of the pci global_listJames Bottomley
2006-10-06Build fixes for struct pt_regs removalMatthew Wilcox
2006-10-05IRQ: Maintain regs pointer globally rather than passing to IRQ handlersDavid Howells
2006-06-30Remove obsolete #include <linux/config.h>Jörn Engel
2006-06-29[PATCH] genirq: rename desc->handler to desc->chipIngo Molnar
2006-03-30[PARISC] I/O-Space must be ioremap_nocache()'dHelge Deller
2006-01-22[PARISC] Use kzalloc and other janitor-style cleanupsHelge Deller
2006-01-10[PARISC] Fix Dino reporting on J2240Matthew Wilcox
2006-01-10[PARISC] Introduce DINO_LOCAL_IRQS and use it for gsc_find_local_irqHelge Deller
='n301' href='#n301'>301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
// SPDX-License-Identifier: GPL-3.0-or-later

#include "../libnetdata.h"

// ----------------------------------------------------------------------------
// URL encode / decode
// code from: http://www.geekhideout.com/urlcode.shtml

/* Converts a hex character to its integer value */
char from_hex(char ch) {
    return (char)(isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10);
}

/* Converts an integer value to its hex character*/
char to_hex(char code) {
    static char hex[] = "0123456789abcdef";
    return hex[code & 15];
}

/* Returns a url-encoded version of str */
/* IMPORTANT: be sure to free() the returned string after use */
char *url_encode(char *str) {
    char *buf, *pbuf;

    pbuf = buf = mallocz(strlen(str) * 3 + 1);

    while (*str) {
        if (isalnum(*str) || *str == '-' || *str == '_' || *str == '.' || *str == '~')
            *pbuf++ = *str;

        else if (*str == ' ')
            *pbuf++ = '+';

        else
            *pbuf++ = '%', *pbuf++ = to_hex(*str >> 4), *pbuf++ = to_hex(*str & 15);

        str++;
    }
    *pbuf = '\0';

    pbuf = strdupz(buf);
    freez(buf);
    return pbuf;
}

/**
 * URL Decode
 *
 * Returns a url-decoded version of str
 * IMPORTANT: be sure to free() the returned string after use
 *
 * @param str the string that will be decode
 *
 * @return a pointer for the url decoded.
 */
char *url_decode(char *str) {
    size_t size = strlen(str) + 1;

    char *buf = mallocz(size);
    return url_decode_r(buf, str, size);
}

/**
 *  Percentage escape decode
 *
 *  Decode %XX character or return 0 if cannot
 *
 *  @param s the string to decode
 *
 *  @return The character decoded on success and 0 otherwise
 */
char url_percent_escape_decode(char *s) {
    if(likely(s[1] && s[2]))
        return from_hex(s[1]) << 4 | from_hex(s[2]);
    return 0;
}

/**
 * Get byte length
 *
 * This (utf8 string related) should be moved in separate file in future
 *
 * @param c is the utf8 character
 *  *
 * @return It reurns the length of the specific character.
 */
char url_utf8_get_byte_length(char c) {
    if(!IS_UTF8_BYTE(c))
        return 1;

    char length = 0;
    while(likely(c & 0x80)) {
        length++;
        c <<= 1;
    }
    //4 byte is max size for UTF-8 char
    //10XX XXXX is not valid character -> check length == 1
    if(length > 4 || length == 1)
        return -1;

    return length;
}

/**
 * Decode Multibyte UTF8
 *
 * Decode % encoded UTF-8 characters and copy them to *d
 *
 * @param s first address
 * @param d
 * @param d_end last address
 *
 * @return count of bytes written to *d
 */
char url_decode_multibyte_utf8(char *s, char *d, char *d_end) {
    char first_byte = url_percent_escape_decode(s);

    if(unlikely(!first_byte || !IS_UTF8_STARTBYTE(first_byte)))
        return 0;

    char byte_length = url_utf8_get_byte_length(first_byte);

    if(unlikely(byte_length <= 0 || d+byte_length >= d_end))
        return 0;

    char to_read = byte_length;
    while(to_read > 0) {
        char c = url_percent_escape_decode(s);

        if(unlikely( !IS_UTF8_BYTE(c) ))
            return 0;
        if((to_read != byte_length) && IS_UTF8_STARTBYTE(c)) 
            return 0;

        *d++ = c;
        s+=3;
        to_read--;
    }

    return byte_length;
}

/*
 * The utf8_check() function scans the '\0'-terminated string starting
 * at s. It returns a pointer to the first byte of the first malformed
 * or overlong UTF-8 sequence found, or NULL if the string contains
 * only correct UTF-8. It also spots UTF-8 sequences that could cause
 * trouble if converted to UTF-16, namely surrogate characters
 * (U+D800..U+DFFF) and non-Unicode positions (U+FFFE..U+FFFF). This
 * routine is very likely to find a malformed sequence if the input
 * uses any other encoding than UTF-8. It therefore can be used as a
 * very effective heuristic for distinguishing between UTF-8 and other
 * encodings.
 *
 * Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/> -- 2005-03-30
 * License: http://www.cl.cam.ac.uk/~mgk25/short-license.html
 */
unsigned char *utf8_check(unsigned char *s)
{
    while (*s)
    {
        if (*s < 0x80)
            /* 0xxxxxxx */
            s++;
        else if ((s[0] & 0xe0) == 0xc0)
        {
            /* 110XXXXx 10xxxxxx */
            if ((s[1] & 0xc0) != 0x80 ||
                (s[0] & 0xfe) == 0xc0) /* overlong? */
                return s;
            else
                s += 2;
        }
        else if ((s[0] & 0xf0) == 0xe0)
        {
            /* 1110XXXX 10Xxxxxx 10xxxxxx */
            if ((s[1] & 0xc0) != 0x80 ||
                (s[2] & 0xc0) != 0x80 ||
                (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */
                (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */
                (s[0] == 0xef && s[1] == 0xbf &&
                 (s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */
                return s;
            else
                s += 3;
        }
        else if ((s[0] & 0xf8) == 0xf0)
        {
            /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */
            if ((s[1] & 0xc0) != 0x80 ||
                (s[2] & 0xc0) != 0x80 ||
                (s[3] & 0xc0) != 0x80 ||
                (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) ||    /* overlong? */
                (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) /* > U+10FFFF? */
                return s;
            else
                s += 4;
        }
        else
            return s;
    }

    return NULL;
}

char *url_decode_r(char *to, char *url, size_t size) {
    char *s = url,           // source
         *d = to,            // destination
         *e = &to[size - 1]; // destination end

    while(*s && d < e) {
        if(unlikely(*s == '%')) {
            char t = url_percent_escape_decode(s);
            if(IS_UTF8_BYTE(t)) {
                char bytes_written = url_decode_multibyte_utf8(s, d, e);
                if(likely(bytes_written)){
                    d += bytes_written;
                    s += (bytes_written * 3)-1;
                }
                else {
                    goto fail_cleanup;
                }
            }
            else if(likely(t) && isprint(t)) {
                // avoid HTTP header injection
                *d++ = t;
                s += 2;
            }
            else
                goto fail_cleanup;
        }
        else